]> granicus.if.org Git - strace/blob - resource.c
.
[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 #if defined(SVR4) || defined(FREEBSD)
45 #include <sys/times.h>
46 #include <sys/time.h>
47 #endif
48
49 #if HAVE_LONG_LONG_RLIM_T
50 /*
51  * Hacks for systems that have a long long rlim_t
52  */
53
54 #define rlimit64 rlimit                 /* Ugly hack */
55 #define rlim64_t rlim_t                 /* Ugly hack */
56 #define RLIM64_INFINITY RLIM_INFINITY   /* You guessed it */
57
58 #define sys_getrlimit64 sys_getrlimit
59 #define sys_setrlimit64 sys_setrlimit
60 #endif
61
62 static const struct xlat resources[] = {
63 #ifdef RLIMIT_CPU
64         { RLIMIT_CPU,   "RLIMIT_CPU"    },
65 #endif
66 #ifdef RLIMIT_FSIZE
67         { RLIMIT_FSIZE, "RLIMIT_FSIZE"  },
68 #endif
69 #ifdef RLIMIT_DATA
70         { RLIMIT_DATA,  "RLIMIT_DATA"   },
71 #endif
72 #ifdef RLIMIT_STACK
73         { RLIMIT_STACK, "RLIMIT_STACK"  },
74 #endif
75 #ifdef RLIMIT_CORE
76         { RLIMIT_CORE,  "RLIMIT_CORE"   },
77 #endif
78 #ifdef RLIMIT_RSS
79         { RLIMIT_RSS,   "RLIMIT_RSS"    },
80 #endif
81 #ifdef RLIMIT_NPROC
82         { RLIMIT_NPROC,"RLIMIT_NPROC"   },
83 #endif
84 #ifdef RLIMIT_NOFILE
85         { RLIMIT_NOFILE,"RLIMIT_NOFILE" },
86 #endif
87 #ifdef RLIMIT_MEMLOCK
88         { RLIMIT_MEMLOCK,       "RLIMIT_MEMLOCK"        },
89 #endif
90 #ifdef RLIMIT_VMEM
91         { RLIMIT_VMEM,  "RLIMIT_VMEM"   },
92 #endif
93 #ifdef RLIMIT_AS
94         { RLIMIT_AS,    "RLIMIT_AS"     },
95 #endif
96 #ifdef RLIMIT_LOCKS
97         { RLIMIT_LOCKS, "RLIMIT_LOCKS"  },
98 #endif
99 #ifdef RLIMIT_SIGPENDING
100         { RLIMIT_SIGPENDING,    "RLIMIT_SIGPENDING"     },
101 #endif
102 #ifdef RLIMIT_MSGQUEUE
103         { RLIMIT_MSGQUEUE,      "RLIMIT_MSGQUEUE"       },
104 #endif
105         { 0,            NULL            },
106 };
107
108 #if !HAVE_LONG_LONG_RLIM_T
109 static char *
110 sprintrlim(lim)
111 long lim;
112 {
113         static char buf[32];
114
115         if (lim == RLIM_INFINITY)
116                 sprintf(buf, "RLIM_INFINITY");
117         else if (lim > 1024 && lim%1024 == 0)
118                 sprintf(buf, "%ld*1024", lim/1024);
119         else
120                 sprintf(buf, "%ld", lim);
121         return buf;
122 }
123
124 int
125 sys_getrlimit(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         }
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(tcp)
149 struct tcb *tcp;
150 {
151         struct rlimit rlim;
152
153         if (entering(tcp)) {
154                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
155                 tprintf(", ");
156                 if (!verbose(tcp))
157                         tprintf("%#lx", tcp->u_arg[1]);
158                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
159                         tprintf("{...}");
160                 else {
161                         tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
162                         tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
163                 }
164         }
165         return 0;
166 }
167 #endif /* !HAVE_LONG_LONG_RLIM_T */
168
169 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_RLIM_T
170 static char *
171 sprintrlim64(lim)
172 rlim64_t lim;
173 {
174         static char buf[64];
175
176         if (lim == RLIM64_INFINITY)
177                 sprintf(buf, "RLIM64_INFINITY");
178         else if (lim > 1024 && lim%1024 == 0)
179                 sprintf(buf, "%lld*1024", (long long) lim/1024);
180         else
181                 sprintf(buf, "%lld", (long long) lim);
182         return buf;
183 }
184
185 int
186 sys_getrlimit64(tcp)
187 struct tcb *tcp;
188 {
189         struct rlimit64 rlim;
190
191         if (entering(tcp)) {
192                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
193                 tprintf(", ");
194         }
195         else {
196                 if (syserror(tcp) || !verbose(tcp))
197                         tprintf("%#lx", tcp->u_arg[1]);
198                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
199                         tprintf("{...}");
200                 else {
201                         tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
202                         tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
203                 }
204         }
205         return 0;
206 }
207
208 int
209 sys_setrlimit64(tcp)
210 struct tcb *tcp;
211 {
212         struct rlimit64 rlim;
213
214         if (entering(tcp)) {
215                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
216                 tprintf(", ");
217                 if (!verbose(tcp))
218                         tprintf("%#lx", tcp->u_arg[1]);
219                 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
220                         tprintf("{...}");
221                 else {
222                         tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
223                         tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
224                 }
225         }
226         return 0;
227 }
228 #endif /* _LFS64_LARGEFILES || HAVE_LONG_LONG_RLIM_T */
229
230 #ifndef SVR4
231
232 static const struct xlat usagewho[] = {
233         { RUSAGE_SELF,          "RUSAGE_SELF"           },
234         { RUSAGE_CHILDREN,      "RUSAGE_CHILDREN"       },
235 #ifdef RUSAGE_BOTH
236         { RUSAGE_BOTH,          "RUSAGE_BOTH"           },
237 #endif
238         { 0,                    NULL                    },
239 };
240
241 #ifdef ALPHA
242 void
243 printrusage32(tcp, addr)
244 struct tcb *tcp;
245 long addr;
246 {
247     struct timeval32
248     {
249         unsigned tv_sec;
250         unsigned tv_usec;
251     };
252     struct rusage32
253     {
254         struct timeval32 ru_utime;      /* user time used */
255         struct timeval32 ru_stime;      /* system time used */
256         long    ru_maxrss;              /* maximum resident set size */
257         long    ru_ixrss;               /* integral shared memory size */
258         long    ru_idrss;               /* integral unshared data size */
259         long    ru_isrss;               /* integral unshared stack size */
260         long    ru_minflt;              /* page reclaims */
261         long    ru_majflt;              /* page faults */
262         long    ru_nswap;               /* swaps */
263         long    ru_inblock;             /* block input operations */
264         long    ru_oublock;             /* block output operations */
265         long    ru_msgsnd;              /* messages sent */
266         long    ru_msgrcv;              /* messages received */
267         long    ru_nsignals;            /* signals received */
268         long    ru_nvcsw;               /* voluntary context switches */
269         long    ru_nivcsw;              /* involuntary " */
270     } ru;
271
272     if (!addr)
273         tprintf("NULL");
274     else if (syserror(tcp) || !verbose(tcp))
275         tprintf("%#lx", addr);
276     else if (umove(tcp, addr, &ru) < 0)
277         tprintf("{...}");
278     else if (!abbrev(tcp)) {
279         tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
280                 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
281                 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
282         tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
283                 ru.ru_maxrss, ru.ru_ixrss);
284         tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
285                 ru.ru_idrss, ru.ru_isrss);
286         tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
287                 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
288         tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
289                 ru.ru_inblock, ru.ru_oublock);
290         tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
291                 ru.ru_msgsnd, ru.ru_msgrcv);
292         tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
293                 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
294     }
295     else {
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     }
300 }
301 #endif
302
303 void
304 printrusage(tcp, addr)
305 struct tcb *tcp;
306 long addr;
307 {
308         struct rusage ru;
309
310         if (!addr)
311                 tprintf("NULL");
312         else if (syserror(tcp) || !verbose(tcp))
313                 tprintf("%#lx", addr);
314         else if (umove(tcp, addr, &ru) < 0)
315                 tprintf("{...}");
316         else if (!abbrev(tcp)) {
317                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
318                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
319                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
320                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
321                         ru.ru_maxrss, ru.ru_ixrss);
322                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
323                         ru.ru_idrss, ru.ru_isrss);
324                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
325                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
326                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
327                         ru.ru_inblock, ru.ru_oublock);
328                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
329                         ru.ru_msgsnd, ru.ru_msgrcv);
330                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
331                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
332         }
333         else {
334                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
335                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
336                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
337         }
338 }
339
340 int
341 sys_getrusage(tcp)
342 struct tcb *tcp;
343 {
344         if (entering(tcp)) {
345                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
346                 tprintf(", ");
347         }
348         else
349                 printrusage(tcp, tcp->u_arg[1]);
350         return 0;
351 }
352
353 #ifdef ALPHA
354 int
355 sys_osf_getrusage(tcp)
356 struct tcb *tcp;
357 {
358     if (entering(tcp)) {
359         printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
360         tprintf(", ");
361     }
362     else
363         printrusage32(tcp, tcp->u_arg[1]);
364     return 0;
365 }
366 #endif /* ALPHA */
367
368 #endif /* !SVR4 */
369
370 #ifdef LINUX
371
372 int
373 sys_sysinfo(tcp)
374 struct tcb *tcp;
375 {
376         struct sysinfo si;
377
378         if (exiting(tcp)) {
379                 if (syserror(tcp) || !verbose(tcp))
380                         tprintf("%#lx", tcp->u_arg[0]);
381                 else if (umove(tcp, tcp->u_arg[0], &si) < 0)
382                         tprintf("{...}");
383                 else {
384                         tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ",
385                                 si.uptime, si.loads[0], si.loads[1],
386                                 si.loads[2]);
387                         tprintf("totalram=%lu, freeram=%lu, ",
388                                 si.totalram, si.freeram);
389                         tprintf("sharedram=%lu, bufferram=%lu} ",
390                                 si.sharedram, si.bufferram);
391                         tprintf("totalswap=%lu, freeswap=%lu, procs=%hu}",
392                                 si.totalswap, si.freeswap, si.procs);
393                 }
394         }
395         return 0;
396 }
397
398 #endif /* LINUX */
399
400 static const struct xlat priorities[] = {
401         { PRIO_PROCESS, "PRIO_PROCESS"  },
402         { PRIO_PGRP,    "PRIO_PGRP"     },
403         { PRIO_USER,    "PRIO_USER"     },
404         { 0,            NULL            },
405 };
406
407 int
408 sys_getpriority(tcp)
409 struct tcb *tcp;
410 {
411         if (entering(tcp)) {
412                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
413                 tprintf(", %lu", tcp->u_arg[1]);
414         }
415         return 0;
416 }
417
418 int
419 sys_setpriority(tcp)
420 struct tcb *tcp;
421 {
422         if (entering(tcp)) {
423                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
424                 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]);
425         }
426         return 0;
427 }
428
429 int
430 sys_nice(tcp)
431 struct tcb *tcp;
432 {
433         if (entering(tcp))
434                 tprintf("%ld", tcp->u_arg[0]);
435         return 0;
436 }
437
438 #ifndef SUNOS4
439
440 int
441 sys_times(tcp)
442 struct tcb *tcp;
443 {
444         struct tms tbuf;
445
446         if (exiting(tcp)) {
447                 if (tcp->u_arg[0] == 0)
448                         tprintf("NULL");
449                 else if (syserror(tcp))
450                         tprintf("%#lx", tcp->u_arg[0]);
451                 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0)
452                         tprintf("{...}");
453                 else {
454                         tprintf("{tms_utime=%lu, tms_stime=%lu, ",
455                                 tbuf.tms_utime, tbuf.tms_stime);
456                         tprintf("tms_cutime=%lu, tms_cstime=%lu}",
457                                 tbuf.tms_cutime, tbuf.tms_cstime);
458                 }
459         }
460         return 0;
461 }
462
463 #endif /* !SUNOS4 */
464
465 #ifdef LINUX
466
467 #define NEW_CMD(c)      ((0x80<<16)+(c))
468 #define XQM_CMD(c)      (('X'<<8)+(c))
469 #define NEW_COMMAND(c) (( ((c) >> SUBCMDSHIFT) & (0x80 << 16)))
470 #define XQM_COMMAND(c) (( ((c) >> SUBCMDSHIFT) & ('X' << 8)) == ('X' << 8))
471 #define OLD_COMMAND(c) (!NEW_COMMAND(c) && !XQM_COMMAND(c))
472
473 static const struct xlat quotacmds[] = {
474         { Q_QUOTAON,    "Q_QUOTAON"     },
475         { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
476         { Q_GETQUOTA,   "Q_GETQUOTA"    },
477         { Q_SETQUOTA,   "Q_SETQUOTA"    },
478         { Q_SETUSE,     "Q_SETUSE"      },
479         { Q_SYNC,       "Q_SYNC"        },
480         { Q_SETQLIM,    "Q_SETQLIM"     },
481         { Q_GETSTATS,   "Q_GETSTATS"    },
482         { Q_RSQUASH,    "Q_RSQUASH"     },
483         { NEW_CMD(0x1), "Q_SYNC"        },
484         { NEW_CMD(0x2), "Q_QUOTAON"     },
485         { NEW_CMD(0x3), "Q_QUOTAOFF"    },
486         { NEW_CMD(0x4), "Q_GETFMT"      },
487         { NEW_CMD(0x5), "Q_GETINFO"     },
488         { NEW_CMD(0x6), "Q_SETINFO"     },
489         { NEW_CMD(0x7), "Q_GETQUOTA"    },
490         { NEW_CMD(0x8), "Q_SETQUOTA"    },
491         { XQM_CMD(0x1), "Q_XQUOTAON"    },
492         { XQM_CMD(0x2), "Q_XQUOTAOFF"   },
493         { XQM_CMD(0x3), "Q_XGETQUOTA"   },
494         { XQM_CMD(0x4), "Q_XSETQLIM"    },
495         { XQM_CMD(0x5), "Q_XGETQSTAT"   },
496         { XQM_CMD(0x6), "Q_XQUOTARM"    },
497         { 0,            NULL            },
498 };
499
500 static const struct xlat quotatypes[] = {
501         { USRQUOTA,     "USRQUOTA"      },
502         { GRPQUOTA,     "GRPQUOTA"      },
503         { 0,            NULL            },
504 };
505
506 int
507 sys_quotactl(tcp)
508 struct tcb *tcp;
509 {
510         /*
511          * The Linux kernel only looks at the low 32 bits of the command
512          * argument, but on some 64-bit architectures (s390x) this word
513          * will have been sign-extended when we see it.  The high 1 bits
514          * don't mean anything, so don't confuse the output with them.
515          */
516         unsigned int cmd = tcp->u_arg[0];
517
518         if (entering(tcp)) {
519                 printxval(quotacmds, cmd >> SUBCMDSHIFT, "Q_???");
520                 tprintf("|");
521                 printxval(quotatypes, cmd & SUBCMDMASK, "???QUOTA");
522                 tprintf(", ");
523                 printstr(tcp, tcp->u_arg[1], -1);
524                 tprintf(", %lu, ", tcp->u_arg[2]);
525         }
526         else {
527                 struct dqblk dq;
528
529                 if (!tcp->u_arg[3])
530                         tprintf("NULL");
531                else if (!verbose(tcp) || !OLD_COMMAND(cmd))
532                         tprintf("%#lx", tcp->u_arg[3]);
533                 else if (umoven(tcp, tcp->u_arg[3], sizeof(struct dqblk),
534                     (char *) &dq) < 0)
535                         tprintf("???");
536                 else {
537                         tprintf("{");
538                         tprintf("%u, ", dq.dqb_bhardlimit);
539                         tprintf("%u, ", dq.dqb_bsoftlimit);
540                         tprintf("%u, ", dq.dqb_curblocks);
541                         tprintf("%u, ", dq.dqb_ihardlimit);
542                         tprintf("%u, ", dq.dqb_isoftlimit);
543                         tprintf("%u, ", dq.dqb_curinodes);
544                         tprintf("%lu, ", dq.dqb_btime);
545                         tprintf("%lu", dq.dqb_itime);
546                         tprintf("}");
547                 }
548
549         }
550         return 0;
551 }
552
553 #endif /* Linux */
554
555 #if defined(SUNOS4) || defined(FREEBSD)
556
557 #ifdef FREEBSD
558 #include <ufs/ufs/quota.h>
559 #endif
560
561 static const struct xlat quotacmds[] = {
562         { Q_QUOTAON,    "Q_QUOTAON"     },
563         { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
564         { Q_GETQUOTA,   "Q_GETQUOTA"    },
565         { Q_SETQUOTA,   "Q_SETQUOTA"    },
566 #ifdef Q_SETQLIM
567         { Q_SETQLIM,    "Q_SETQLIM"     },
568 #endif
569 #ifdef Q_SETUSE
570         { Q_SETUSE,     "Q_SETUSE"      },
571 #endif
572         { Q_SYNC,       "Q_SYNC"        },
573         { 0,            NULL            },
574 };
575
576 int
577 sys_quotactl(tcp)
578 struct tcb *tcp;
579 {
580         /* fourth arg (addr) not interpreted here */
581         if (entering(tcp)) {
582 #ifdef SUNOS4
583                 printxval(quotacmds, tcp->u_arg[0], "Q_???");
584                 tprintf(", ");
585                 printstr(tcp, tcp->u_arg[1], -1);
586 #endif
587 #ifdef FREEBSD
588                 printpath(tcp, tcp->u_arg[0]);
589                 tprintf(", ");
590                 printxval(quotacmds, tcp->u_arg[1], "Q_???");
591 #endif
592                 tprintf(", %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
593         }
594         return 0;
595 }
596
597 #endif /* SUNOS4 || FREEBSD */