]> granicus.if.org Git - strace/blob - resource.c
Linux/MIPS uses syscalls up to >4k, so set MAX_QUALS to 4999
[strace] / resource.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *      $Id$
31  */
32
33 #include "defs.h"
34
35 #include <sys/resource.h>
36 #ifdef LINUX
37 #include <sys/times.h>
38 #include <linux/kernel.h>
39 #include <sys/quota.h>
40 #endif /* LINUX */
41 #ifdef SUNOS4
42 #include <ufs/quota.h>
43 #endif /* SUNOS4 */
44 #ifdef SVR4
45 #include <sys/times.h>
46 #include <sys/time.h>
47 #endif
48
49 static struct xlat resources[] = {
50 #ifdef RLIMIT_CPU
51         { RLIMIT_CPU,   "RLIMIT_CPU"    },
52 #endif
53 #ifdef RLIMIT_FSIZE
54         { RLIMIT_FSIZE, "RLIMIT_FSIZE"  },
55 #endif
56 #ifdef RLIMIT_DATA
57         { RLIMIT_DATA,  "RLIMIT_DATA"   },
58 #endif
59 #ifdef RLIMIT_STACK
60         { RLIMIT_STACK, "RLIMIT_STACK"  },
61 #endif
62 #ifdef RLIMIT_CORE
63         { RLIMIT_CORE,  "RLIMIT_CORE"   },
64 #endif
65 #ifdef RLIMIT_RSS
66         { RLIMIT_RSS,   "RLIMIT_RSS"    },
67 #endif
68 #ifdef RLIMIT_NPROC
69         { RLIMIT_NPROC,"RLIMIT_NPROC"   },
70 #endif
71 #ifdef RLIMIT_NOFILE
72         { RLIMIT_NOFILE,"RLIMIT_NOFILE" },
73 #endif
74 #ifdef RLIMIT_MEMLOCK
75         { RLIMIT_MEMLOCK,       "RLIMIT_MEMLOCK"        },
76 #endif
77 #ifdef RLIMIT_VMEM
78         { RLIMIT_VMEM,  "RLIMIT_VMEM"   },
79 #endif
80 #ifdef RLIMIT_AS
81         { RLIMIT_AS,    "RLIMIT_AS"     },
82 #endif
83         { 0,            NULL            },
84 };
85
86 static char *
87 sprintrlim(lim)
88 long lim;
89 {
90         static char buf[32];
91
92         if (lim == RLIM_INFINITY)
93                 sprintf(buf, "RLIM_INFINITY");
94         else if (lim > 1024 && lim%1024 == 0)
95                 sprintf(buf, "%ld*1024", lim/1024);
96         else
97                 sprintf(buf, "%ld", lim);
98         return buf;
99 }
100
101 int
102 sys_getrlimit(tcp)
103 struct tcb *tcp;
104 {
105         struct rlimit rlim;
106
107         if (entering(tcp)) {
108                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
109                 tprintf(", ");
110         }
111         else {
112                 if (syserror(tcp) || !verbose(tcp))
113                         tprintf("%#lx", tcp->u_arg[1]);
114                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
115                         tprintf("{...}");
116                 else {
117                         tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
118                         tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
119                 }
120         }
121         return 0;
122 }
123
124 int
125 sys_setrlimit(tcp)
126 struct tcb *tcp;
127 {
128         struct rlimit rlim;
129
130         if (entering(tcp)) {
131                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
132                 tprintf(", ");
133                 if (!verbose(tcp))
134                         tprintf("%#lx", tcp->u_arg[1]);
135                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
136                         tprintf("{...}");
137                 else {
138                         tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
139                         tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
140                 }
141         }
142         return 0;
143 }
144
145 #ifndef SVR4
146
147 static struct xlat usagewho[] = {
148         { RUSAGE_SELF,          "RUSAGE_SELF"           },
149         { RUSAGE_CHILDREN,      "RUSAGE_CHILDREN"       },
150 #ifdef RUSAGE_BOTH
151         { RUSAGE_BOTH,          "RUSAGE_BOTH"           },
152 #endif
153         { 0,                    NULL                    },
154 };
155
156 #ifdef ALPHA
157 void
158 printrusage32(tcp, addr)
159 struct tcb *tcp;
160 long addr;
161 {
162     struct timeval32
163     {
164         unsigned tv_sec;
165         unsigned tv_usec;
166     };
167     struct rusage32
168     {
169         struct timeval32 ru_utime;      /* user time used */
170         struct timeval32 ru_stime;      /* system time used */
171         long    ru_maxrss;              /* maximum resident set size */
172         long    ru_ixrss;               /* integral shared memory size */
173         long    ru_idrss;               /* integral unshared data size */
174         long    ru_isrss;               /* integral unshared stack size */
175         long    ru_minflt;              /* page reclaims */
176         long    ru_majflt;              /* page faults */
177         long    ru_nswap;               /* swaps */
178         long    ru_inblock;             /* block input operations */
179         long    ru_oublock;             /* block output operations */
180         long    ru_msgsnd;              /* messages sent */
181         long    ru_msgrcv;              /* messages received */
182         long    ru_nsignals;            /* signals received */
183         long    ru_nvcsw;               /* voluntary context switches */
184         long    ru_nivcsw;              /* involuntary " */
185     } ru;
186
187     if (!addr)
188         tprintf("NULL");
189     else if (syserror(tcp) || !verbose(tcp))
190         tprintf("%#lx", addr);
191     else if (umove(tcp, addr, &ru) < 0)
192         tprintf("{...}");
193     else if (!abbrev(tcp)) {
194         tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
195                 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
196                 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
197         tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
198                 ru.ru_maxrss, ru.ru_ixrss);
199         tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
200                 ru.ru_idrss, ru.ru_isrss);
201         tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
202                 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
203         tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
204                 ru.ru_inblock, ru.ru_oublock);
205         tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
206                 ru.ru_msgsnd, ru.ru_msgrcv);
207         tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
208                 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
209     }
210     else {
211         tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
212                 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
213                 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
214     }
215 }
216 #endif
217
218 void
219 printrusage(tcp, addr)
220 struct tcb *tcp;
221 long addr;
222 {
223         struct rusage ru;
224
225         if (!addr)
226                 tprintf("NULL");
227         else if (syserror(tcp) || !verbose(tcp))
228                 tprintf("%#lx", addr);
229         else if (umove(tcp, addr, &ru) < 0)
230                 tprintf("{...}");
231         else if (!abbrev(tcp)) {
232                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
233                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
234                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
235                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
236                         ru.ru_maxrss, ru.ru_ixrss);
237                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
238                         ru.ru_idrss, ru.ru_isrss);
239                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
240                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
241                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
242                         ru.ru_inblock, ru.ru_oublock);
243                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
244                         ru.ru_msgsnd, ru.ru_msgrcv);
245                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
246                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
247         }
248         else {
249                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
250                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
251                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
252         }
253 }
254
255 int
256 sys_getrusage(tcp)
257 struct tcb *tcp;
258 {
259         if (entering(tcp)) {
260                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
261                 tprintf(", ");
262         }
263         else
264                 printrusage(tcp, tcp->u_arg[1]);
265         return 0;
266 }
267
268 #ifdef ALPHA
269 int
270 sys_osf_getrusage(tcp)
271 struct tcb *tcp;
272 {
273     if (entering(tcp)) {
274         printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
275         tprintf(", ");
276     }
277     else
278         printrusage32(tcp, tcp->u_arg[1]);
279     return 0;
280 }
281 #endif /* ALPHA */
282
283 #endif /* !SVR4 */
284
285 #ifdef LINUX
286
287 int
288 sys_sysinfo(tcp)
289 struct tcb *tcp;
290 {
291         struct sysinfo si;
292
293         if (exiting(tcp)) {
294                 if (syserror(tcp) || !verbose(tcp))
295                         tprintf("%#lx", tcp->u_arg[0]);
296                 else if (umove(tcp, tcp->u_arg[0], &si) < 0)
297                         tprintf("{...}");
298                 else {
299                         tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ",
300                                 si.uptime, si.loads[0], si.loads[1],
301                                 si.loads[2]);
302                         tprintf("totalram=%lu, freeram=%lu, ",
303                                 si.totalram, si.freeram);
304                         tprintf("sharedram=%lu, bufferram=%lu} ",
305                                 si.sharedram, si.bufferram);
306                         tprintf("totalswap=%lu, freeswap=%lu, procs=%hu}",
307                                 si.totalswap, si.freeswap, si.procs);
308                 }
309         }
310         return 0;
311 }
312
313 #endif /* LINUX */
314
315 static struct xlat priorities[] = {
316         { PRIO_PROCESS, "PRIO_PROCESS"  },
317         { PRIO_PGRP,    "PRIO_PGRP"     },
318         { PRIO_USER,    "PRIO_USER"     },
319         { 0,            NULL            },
320 };
321
322 int
323 sys_getpriority(tcp)
324 struct tcb *tcp;
325 {
326         if (entering(tcp)) {
327                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
328                 tprintf(", %lu", tcp->u_arg[1]);
329         }
330         return 0;
331 }
332
333 int
334 sys_setpriority(tcp)
335 struct tcb *tcp;
336 {
337         if (entering(tcp)) {
338                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
339                 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]);
340         }
341         return 0;
342 }
343
344 int
345 sys_nice(tcp)
346 struct tcb *tcp;
347 {
348         if (entering(tcp))
349                 tprintf("%ld", tcp->u_arg[0]);
350         return 0;
351 }
352
353 #ifndef SUNOS4
354
355 int
356 sys_times(tcp)
357 struct tcb *tcp;
358 {
359         struct tms tbuf;
360
361         if (exiting(tcp)) {
362                 if (tcp->u_arg[0] == 0)
363                         tprintf("NULL");
364                 else if (syserror(tcp))
365                         tprintf("%#lx", tcp->u_arg[0]);
366                 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0)
367                         tprintf("{...}");
368                 else {
369                         tprintf("{tms_utime=%lu, tms_stime=%lu, ",
370                                 tbuf.tms_utime, tbuf.tms_stime);
371                         tprintf("tms_cutime=%lu, tms_cstime=%lu}",
372                                 tbuf.tms_cutime, tbuf.tms_cstime);
373                 }
374         }
375         return 0;
376 }
377
378 #endif /* !SUNOS4 */
379
380 #ifdef LINUX
381
382 static struct xlat quotacmds[] = {
383         { Q_QUOTAON,    "Q_QUOTAON"     },
384         { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
385         { Q_GETQUOTA,   "Q_GETQUOTA"    },
386         { Q_SETQUOTA,   "Q_SETQUOTA"    },
387         { Q_SETUSE,     "Q_SETUSE"      },
388         { Q_SYNC,       "Q_SYNC"        },
389         { Q_SETQLIM,    "Q_SETQLIM"     },
390         { Q_GETSTATS,   "Q_GETSTATS"    },
391         { Q_RSQUASH,    "Q_RSQUASH"     },
392         { 0,            NULL            },
393 };
394
395 static struct xlat quotatypes[] = {
396         { USRQUOTA,     "USRQUOTA"      },
397         { GRPQUOTA,     "GRPQUOTA"      },
398         { 0,            NULL            },
399 };
400
401 int
402 sys_quotactl(tcp)
403 struct tcb *tcp;
404 {
405         if (entering(tcp)) {
406                 printxval(quotacmds, tcp->u_arg[0] >> SUBCMDSHIFT, "Q_???");
407                 tprintf("|");
408                 printxval(quotatypes, tcp->u_arg[0] & SUBCMDMASK, "???QUOTA");
409                 tprintf(", ");
410                 printstr(tcp, tcp->u_arg[1], -1);
411                 tprintf(", %lu, ", tcp->u_arg[2]);
412         }
413         else {
414                 struct dqblk dq;
415
416                 if (!tcp->u_arg[3])
417                         tprintf("NULL");
418                 else if (!verbose(tcp))
419                         tprintf("%#lx", tcp->u_arg[3]);
420                 else if (umoven(tcp, tcp->u_arg[3], sizeof(struct dqblk),   
421                     (char *) &dq) < 0)
422                         tprintf("???");
423                 else {
424                         tprintf("{");
425                         tprintf("%u, ", dq.dqb_bhardlimit);
426                         tprintf("%u, ", dq.dqb_bsoftlimit);
427                         tprintf("%u, ", dq.dqb_curblocks);
428                         tprintf("%u, ", dq.dqb_ihardlimit);
429                         tprintf("%u, ", dq.dqb_isoftlimit);
430                         tprintf("%u, ", dq.dqb_curinodes);
431                         tprintf("%lu, ", dq.dqb_btime);
432                         tprintf("%lu", dq.dqb_itime);
433                         tprintf("}");
434                 }
435
436         }
437         return 0;
438 }
439
440 #endif /* Linux */
441
442 #ifdef SUNOS4
443
444 static struct xlat quotacmds[] = {
445         { Q_QUOTAON,    "Q_QUOTAON"     },
446         { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
447         { Q_GETQUOTA,   "Q_GETQUOTA"    },
448         { Q_SETQUOTA,   "Q_SETQUOTA"    },
449         { Q_SETQLIM,    "Q_SETQLIM"     },
450         { Q_SYNC,       "Q_SYNC"        },
451         { 0,            NULL            },
452 };
453
454 int
455 sys_quotactl(tcp)
456 struct tcb *tcp;
457 {
458         /* fourth arg (addr) not interpreted here */
459         if (entering(tcp)) {
460                 printxval(quotacmds, tcp->u_arg[0], "Q_???");
461                 tprintf(", ");
462                 printstr(tcp, tcp->u_arg[1], -1);
463                 tprintf(", %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
464         }
465         return 0;
466 }
467
468 #endif /* SUNOS4 */