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