]> granicus.if.org Git - strace/blobdiff - resource.c
Merge Harald Böhme's solaris patches
[strace] / resource.c
index cb63214f46bc94d8f07b801248c6b7ddd30e269c..833e0f6bdeed64fad223dba980a10618b4e0d79b 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
+ * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifdef LINUX
 #include <sys/times.h>
 #include <linux/kernel.h>
+#include <sys/quota.h>
 #endif /* LINUX */
 #ifdef SUNOS4
 #include <ufs/quota.h>
 #endif /* SUNOS4 */
-#ifdef SVR4
+#if defined(SVR4) || defined(FREEBSD)
 #include <sys/times.h>
 #include <sys/time.h>
 #endif
@@ -63,9 +65,15 @@ static struct xlat resources[] = {
 #ifdef RLIMIT_RSS
        { RLIMIT_RSS,   "RLIMIT_RSS"    },
 #endif
+#ifdef RLIMIT_NPROC
+       { RLIMIT_NPROC,"RLIMIT_NPROC"   },
+#endif
 #ifdef RLIMIT_NOFILE
        { RLIMIT_NOFILE,"RLIMIT_NOFILE" },
 #endif
+#ifdef RLIMIT_MEMLOCK
+       { RLIMIT_MEMLOCK,       "RLIMIT_MEMLOCK"        },
+#endif
 #ifdef RLIMIT_VMEM
        { RLIMIT_VMEM,  "RLIMIT_VMEM"   },
 #endif
@@ -134,14 +142,140 @@ struct tcb *tcp;
        return 0;
 }
 
+#if _LFS64_LARGEFILE
+static char *
+sprintrlim64(lim)
+rlim64_t lim;
+{
+       static char buf[64];
+
+       if (lim == RLIM64_INFINITY)
+               sprintf(buf, "RLIM64_INFINITY");
+       else if (lim > 1024 && lim%1024 == 0)
+               sprintf(buf, "%lld*1024", lim/1024);
+       else
+               sprintf(buf, "%lld", lim);
+       return buf;
+}
+
+int
+sys_getrlimit64(tcp)
+struct tcb *tcp;
+{
+       struct rlimit64 rlim;
+
+       if (entering(tcp)) {
+               printxval(resources, tcp->u_arg[0], "RLIMIT_???");
+               tprintf(", ");
+       }
+       else {
+               if (syserror(tcp) || !verbose(tcp))
+                       tprintf("%#lx", tcp->u_arg[1]);
+               else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
+                       tprintf("{...}");
+               else {
+                       tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
+                       tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
+               }
+       }
+       return 0;
+}
+
+int
+sys_setrlimit64(tcp)
+struct tcb *tcp;
+{
+       struct rlimit64 rlim;
+
+       if (entering(tcp)) {
+               printxval(resources, tcp->u_arg[0], "RLIMIT_???");
+               tprintf(", ");
+               if (!verbose(tcp))
+                       tprintf("%#lx", tcp->u_arg[1]);
+               else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
+                       tprintf("{...}");
+               else {
+                       tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
+                       tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
+               }
+       }
+       return 0;
+}
+#endif
+
 #ifndef SVR4
 
 static struct xlat usagewho[] = {
        { RUSAGE_SELF,          "RUSAGE_SELF"           },
        { RUSAGE_CHILDREN,      "RUSAGE_CHILDREN"       },
+#ifdef RUSAGE_BOTH
+       { RUSAGE_BOTH,          "RUSAGE_BOTH"           },
+#endif
        { 0,                    NULL                    },
 };
 
+#ifdef ALPHA
+void
+printrusage32(tcp, addr)
+struct tcb *tcp;
+long addr;
+{
+    struct timeval32
+    {
+       unsigned tv_sec;
+       unsigned tv_usec;
+    };
+    struct rusage32
+    {
+       struct timeval32 ru_utime;      /* user time used */
+       struct timeval32 ru_stime;      /* system time used */
+       long    ru_maxrss;              /* maximum resident set size */
+       long    ru_ixrss;               /* integral shared memory size */
+       long    ru_idrss;               /* integral unshared data size */
+       long    ru_isrss;               /* integral unshared stack size */
+       long    ru_minflt;              /* page reclaims */
+       long    ru_majflt;              /* page faults */
+       long    ru_nswap;               /* swaps */
+       long    ru_inblock;             /* block input operations */
+       long    ru_oublock;             /* block output operations */
+       long    ru_msgsnd;              /* messages sent */
+       long    ru_msgrcv;              /* messages received */
+       long    ru_nsignals;            /* signals received */
+       long    ru_nvcsw;               /* voluntary context switches */
+       long    ru_nivcsw;              /* involuntary " */
+    } ru;
+
+    if (!addr)
+       tprintf("NULL");
+    else if (syserror(tcp) || !verbose(tcp))
+       tprintf("%#lx", addr);
+    else if (umove(tcp, addr, &ru) < 0)
+       tprintf("{...}");
+    else if (!abbrev(tcp)) {
+       tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
+               (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
+               (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
+       tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
+               ru.ru_maxrss, ru.ru_ixrss);
+       tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
+               ru.ru_idrss, ru.ru_isrss);
+       tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
+               ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
+       tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
+               ru.ru_inblock, ru.ru_oublock);
+       tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
+               ru.ru_msgsnd, ru.ru_msgrcv);
+       tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
+               ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
+    }
+    else {
+       tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
+               (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
+               (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
+    }
+}
+#endif
+
 void
 printrusage(tcp, addr)
 struct tcb *tcp;
@@ -192,6 +326,21 @@ struct tcb *tcp;
        return 0;
 }
 
+#ifdef ALPHA
+int
+sys_osf_getrusage(tcp)
+struct tcb *tcp;
+{
+    if (entering(tcp)) {
+       printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
+       tprintf(", ");
+    }
+    else
+       printrusage32(tcp, tcp->u_arg[1]);
+    return 0;
+}
+#endif /* ALPHA */
+
 #endif /* !SVR4 */
 
 #ifdef LINUX
@@ -289,14 +438,85 @@ struct tcb *tcp;
 
 #endif /* !SUNOS4 */
 
-#ifdef SUNOS4
+#ifdef LINUX
+
+static struct xlat quotacmds[] = {
+       { Q_QUOTAON,    "Q_QUOTAON"     },
+       { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
+       { Q_GETQUOTA,   "Q_GETQUOTA"    },
+       { Q_SETQUOTA,   "Q_SETQUOTA"    },
+       { Q_SETUSE,     "Q_SETUSE"      },
+       { Q_SYNC,       "Q_SYNC"        },
+       { Q_SETQLIM,    "Q_SETQLIM"     },
+       { Q_GETSTATS,   "Q_GETSTATS"    },
+       { Q_RSQUASH,    "Q_RSQUASH"     },
+       { 0,            NULL            },
+};
+
+static struct xlat quotatypes[] = {
+       { USRQUOTA,     "USRQUOTA"      },
+       { GRPQUOTA,     "GRPQUOTA"      },
+       { 0,            NULL            },
+};
+
+int
+sys_quotactl(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               printxval(quotacmds, tcp->u_arg[0] >> SUBCMDSHIFT, "Q_???");
+               tprintf("|");
+               printxval(quotatypes, tcp->u_arg[0] & SUBCMDMASK, "???QUOTA");
+               tprintf(", ");
+               printstr(tcp, tcp->u_arg[1], -1);
+               tprintf(", %lu, ", tcp->u_arg[2]);
+       }
+       else {
+               struct dqblk dq;
+
+               if (!tcp->u_arg[3])
+                       tprintf("NULL");
+               else if (!verbose(tcp))
+                       tprintf("%#lx", tcp->u_arg[3]);
+                else if (umoven(tcp, tcp->u_arg[3], sizeof(struct dqblk),   
+                    (char *) &dq) < 0)
+                        tprintf("???");
+               else {
+                        tprintf("{");
+                       tprintf("%u, ", dq.dqb_bhardlimit);
+                       tprintf("%u, ", dq.dqb_bsoftlimit);
+                       tprintf("%u, ", dq.dqb_curblocks);
+                       tprintf("%u, ", dq.dqb_ihardlimit);
+                       tprintf("%u, ", dq.dqb_isoftlimit);
+                       tprintf("%u, ", dq.dqb_curinodes);
+                       tprintf("%lu, ", dq.dqb_btime);
+                       tprintf("%lu", dq.dqb_itime);
+                        tprintf("}");
+               }
+
+       }
+       return 0;
+}
+
+#endif /* Linux */
+
+#if defined(SUNOS4) || defined(FREEBSD)
+
+#ifdef FREEBSD
+#include <ufs/ufs/quota.h>
+#endif
 
 static struct xlat quotacmds[] = {
        { Q_QUOTAON,    "Q_QUOTAON"     },
        { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
        { Q_GETQUOTA,   "Q_GETQUOTA"    },
        { Q_SETQUOTA,   "Q_SETQUOTA"    },
+#ifdef Q_SETQLIM
        { Q_SETQLIM,    "Q_SETQLIM"     },
+#endif
+#ifdef Q_SETUSE
+       { Q_SETUSE,     "Q_SETUSE"      },
+#endif
        { Q_SYNC,       "Q_SYNC"        },
        { 0,            NULL            },
 };
@@ -307,12 +527,19 @@ struct tcb *tcp;
 {
        /* fourth arg (addr) not interpreted here */
        if (entering(tcp)) {
+#ifdef SUNOS4
                printxval(quotacmds, tcp->u_arg[0], "Q_???");
                tprintf(", ");
                printstr(tcp, tcp->u_arg[1], -1);
+#endif
+#ifdef FREEBSD
+               printpath(tcp, tcp->u_arg[0]);
+               tprintf(", ");
+               printxval(quotacmds, tcp->u_arg[1], "Q_???");
+#endif         
                tprintf(", %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
        }
        return 0;
 }
 
-#endif /* SUNOS4 */
+#endif /* SUNOS4 || FREEBSD */