]> granicus.if.org Git - strace/blob - resource.c
ea741b8f496056da786b9074942c8580eb52b349
[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 #endif /* LINUX */
40 #ifdef SUNOS4
41 #include <ufs/quota.h>
42 #endif /* SUNOS4 */
43 #ifdef SVR4
44 #include <sys/times.h>
45 #include <sys/time.h>
46 #endif
47
48 static struct xlat resources[] = {
49 #ifdef RLIMIT_CPU
50         { RLIMIT_CPU,   "RLIMIT_CPU"    },
51 #endif
52 #ifdef RLIMIT_FSIZE
53         { RLIMIT_FSIZE, "RLIMIT_FSIZE"  },
54 #endif
55 #ifdef RLIMIT_DATA
56         { RLIMIT_DATA,  "RLIMIT_DATA"   },
57 #endif
58 #ifdef RLIMIT_STACK
59         { RLIMIT_STACK, "RLIMIT_STACK"  },
60 #endif
61 #ifdef RLIMIT_CORE
62         { RLIMIT_CORE,  "RLIMIT_CORE"   },
63 #endif
64 #ifdef RLIMIT_RSS
65         { RLIMIT_RSS,   "RLIMIT_RSS"    },
66 #endif
67 #ifdef RLIMIT_NOFILE
68         { RLIMIT_NOFILE,"RLIMIT_NOFILE" },
69 #endif
70 #ifdef RLIMIT_VMEM
71         { RLIMIT_VMEM,  "RLIMIT_VMEM"   },
72 #endif
73 #ifdef RLIMIT_AS
74         { RLIMIT_AS,    "RLIMIT_AS"     },
75 #endif
76         { 0,            NULL            },
77 };
78
79 static char *
80 sprintrlim(lim)
81 long lim;
82 {
83         static char buf[32];
84
85         if (lim == RLIM_INFINITY)
86                 sprintf(buf, "RLIM_INFINITY");
87         else if (lim > 1024 && lim%1024 == 0)
88                 sprintf(buf, "%ld*1024", lim/1024);
89         else
90                 sprintf(buf, "%ld", lim);
91         return buf;
92 }
93
94 int
95 sys_getrlimit(tcp)
96 struct tcb *tcp;
97 {
98         struct rlimit rlim;
99
100         if (entering(tcp)) {
101                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
102                 tprintf(", ");
103         }
104         else {
105                 if (syserror(tcp) || !verbose(tcp))
106                         tprintf("%#lx", tcp->u_arg[1]);
107                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
108                         tprintf("{...}");
109                 else {
110                         tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
111                         tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
112                 }
113         }
114         return 0;
115 }
116
117 int
118 sys_setrlimit(tcp)
119 struct tcb *tcp;
120 {
121         struct rlimit rlim;
122
123         if (entering(tcp)) {
124                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
125                 tprintf(", ");
126                 if (!verbose(tcp))
127                         tprintf("%#lx", tcp->u_arg[1]);
128                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
129                         tprintf("{...}");
130                 else {
131                         tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
132                         tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
133                 }
134         }
135         return 0;
136 }
137
138 #ifndef SVR4
139
140 static struct xlat usagewho[] = {
141         { RUSAGE_SELF,          "RUSAGE_SELF"           },
142         { RUSAGE_CHILDREN,      "RUSAGE_CHILDREN"       },
143         { 0,                    NULL                    },
144 };
145
146 #ifdef ALPHA
147 void
148 printrusage32(tcp, addr)
149 struct tcb *tcp;
150 long addr;
151 {
152     struct timeval32
153     {
154         unsigned tv_sec;
155         unsigned tv_usec;
156     };
157     struct rusage32
158     {
159         struct timeval32 ru_utime;      /* user time used */
160         struct timeval32 ru_stime;      /* system time used */
161         long    ru_maxrss;              /* maximum resident set size */
162         long    ru_ixrss;               /* integral shared memory size */
163         long    ru_idrss;               /* integral unshared data size */
164         long    ru_isrss;               /* integral unshared stack size */
165         long    ru_minflt;              /* page reclaims */
166         long    ru_majflt;              /* page faults */
167         long    ru_nswap;               /* swaps */
168         long    ru_inblock;             /* block input operations */
169         long    ru_oublock;             /* block output operations */
170         long    ru_msgsnd;              /* messages sent */
171         long    ru_msgrcv;              /* messages received */
172         long    ru_nsignals;            /* signals received */
173         long    ru_nvcsw;               /* voluntary context switches */
174         long    ru_nivcsw;              /* involuntary " */
175     } ru;
176
177     if (!addr)
178         tprintf("NULL");
179     else if (syserror(tcp) || !verbose(tcp))
180         tprintf("%#lx", addr);
181     else if (umove(tcp, addr, &ru) < 0)
182         tprintf("{...}");
183     else if (!abbrev(tcp)) {
184         tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
185                 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
186                 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
187         tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
188                 ru.ru_maxrss, ru.ru_ixrss);
189         tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
190                 ru.ru_idrss, ru.ru_isrss);
191         tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
192                 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
193         tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
194                 ru.ru_inblock, ru.ru_oublock);
195         tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
196                 ru.ru_msgsnd, ru.ru_msgrcv);
197         tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
198                 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
199     }
200     else {
201         tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
202                 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
203                 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
204     }
205 }
206 #endif
207
208 void
209 printrusage(tcp, addr)
210 struct tcb *tcp;
211 long addr;
212 {
213         struct rusage ru;
214
215         if (!addr)
216                 tprintf("NULL");
217         else if (syserror(tcp) || !verbose(tcp))
218                 tprintf("%#lx", addr);
219         else if (umove(tcp, addr, &ru) < 0)
220                 tprintf("{...}");
221         else if (!abbrev(tcp)) {
222                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
223                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
224                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
225                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
226                         ru.ru_maxrss, ru.ru_ixrss);
227                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
228                         ru.ru_idrss, ru.ru_isrss);
229                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
230                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
231                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
232                         ru.ru_inblock, ru.ru_oublock);
233                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
234                         ru.ru_msgsnd, ru.ru_msgrcv);
235                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
236                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
237         }
238         else {
239                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
240                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
241                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
242         }
243 }
244
245 int
246 sys_getrusage(tcp)
247 struct tcb *tcp;
248 {
249         if (entering(tcp)) {
250                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
251                 tprintf(", ");
252         }
253         else
254                 printrusage(tcp, tcp->u_arg[1]);
255         return 0;
256 }
257
258 #ifdef ALPHA
259 int
260 sys_osf_getrusage(tcp)
261 struct tcb *tcp;
262 {
263     if (entering(tcp)) {
264         printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
265         tprintf(", ");
266     }
267     else
268         printrusage32(tcp, tcp->u_arg[1]);
269     return 0;
270 }
271 #endif /* ALPHA */
272
273 #endif /* !SVR4 */
274
275 #ifdef LINUX
276
277 int
278 sys_sysinfo(tcp)
279 struct tcb *tcp;
280 {
281         struct sysinfo si;
282
283         if (exiting(tcp)) {
284                 if (syserror(tcp) || !verbose(tcp))
285                         tprintf("%#lx", tcp->u_arg[0]);
286                 else if (umove(tcp, tcp->u_arg[0], &si) < 0)
287                         tprintf("{...}");
288                 else {
289                         tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ",
290                                 si.uptime, si.loads[0], si.loads[1],
291                                 si.loads[2]);
292                         tprintf("totalram=%lu, freeram=%lu, ",
293                                 si.totalram, si.freeram);
294                         tprintf("sharedram=%lu, bufferram=%lu} ",
295                                 si.sharedram, si.bufferram);
296                         tprintf("totalswap=%lu, freeswap=%lu, procs=%hu}",
297                                 si.totalswap, si.freeswap, si.procs);
298                 }
299         }
300         return 0;
301 }
302
303 #endif /* LINUX */
304
305 static struct xlat priorities[] = {
306         { PRIO_PROCESS, "PRIO_PROCESS"  },
307         { PRIO_PGRP,    "PRIO_PGRP"     },
308         { PRIO_USER,    "PRIO_USER"     },
309         { 0,            NULL            },
310 };
311
312 int
313 sys_getpriority(tcp)
314 struct tcb *tcp;
315 {
316         if (entering(tcp)) {
317                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
318                 tprintf(", %lu", tcp->u_arg[1]);
319         }
320         return 0;
321 }
322
323 int
324 sys_setpriority(tcp)
325 struct tcb *tcp;
326 {
327         if (entering(tcp)) {
328                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
329                 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]);
330         }
331         return 0;
332 }
333
334 int
335 sys_nice(tcp)
336 struct tcb *tcp;
337 {
338         if (entering(tcp))
339                 tprintf("%ld", tcp->u_arg[0]);
340         return 0;
341 }
342
343 #ifndef SUNOS4
344
345 int
346 sys_times(tcp)
347 struct tcb *tcp;
348 {
349         struct tms tbuf;
350
351         if (exiting(tcp)) {
352                 if (tcp->u_arg[0] == 0)
353                         tprintf("NULL");
354                 else if (syserror(tcp))
355                         tprintf("%#lx", tcp->u_arg[0]);
356                 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0)
357                         tprintf("{...}");
358                 else {
359                         tprintf("{tms_utime=%lu, tms_stime=%lu, ",
360                                 tbuf.tms_utime, tbuf.tms_stime);
361                         tprintf("tms_cutime=%lu, tms_cstime=%lu}",
362                                 tbuf.tms_cutime, tbuf.tms_cstime);
363                 }
364         }
365         return 0;
366 }
367
368 #endif /* !SUNOS4 */
369
370 #ifdef SUNOS4
371
372 static struct xlat quotacmds[] = {
373         { Q_QUOTAON,    "Q_QUOTAON"     },
374         { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
375         { Q_GETQUOTA,   "Q_GETQUOTA"    },
376         { Q_SETQUOTA,   "Q_SETQUOTA"    },
377         { Q_SETQLIM,    "Q_SETQLIM"     },
378         { Q_SYNC,       "Q_SYNC"        },
379         { 0,            NULL            },
380 };
381
382 int
383 sys_quotactl(tcp)
384 struct tcb *tcp;
385 {
386         /* fourth arg (addr) not interpreted here */
387         if (entering(tcp)) {
388                 printxval(quotacmds, tcp->u_arg[0], "Q_???");
389                 tprintf(", ");
390                 printstr(tcp, tcp->u_arg[1], -1);
391                 tprintf(", %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
392         }
393         return 0;
394 }
395
396 #endif /* SUNOS4 */