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