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