Index: head/usr.bin/procstat/procstat.c =================================================================== --- head/usr.bin/procstat/procstat.c (revision 249674) +++ head/usr.bin/procstat/procstat.c (revision 249675) @@ -1,279 +1,279 @@ /*- * Copyright (c) 2007, 2011 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include "procstat.h" static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, sflag; static int tflag, vflag, xflag; int hflag, nflag, Cflag; static void usage(void) { fprintf(stderr, "usage: procstat [-h] [-C] [-M core] [-N system] " "[-w interval] \n"); fprintf(stderr, " [-b | -c | -e | -f | -i | -j | -k | " "-l | -s | -t | -v | -x] [-a | pid ...]\n"); exit(EX_USAGE); } static void procstat(struct procstat *prstat, struct kinfo_proc *kipp) { if (bflag) procstat_bin(kipp); else if (cflag) procstat_args(kipp); else if (eflag) procstat_env(kipp); else if (fflag) procstat_files(prstat, kipp); else if (iflag) procstat_sigs(prstat, kipp); else if (jflag) procstat_threads_sigs(prstat, kipp); else if (kflag) procstat_kstack(kipp, kflag); else if (lflag) - procstat_rlimit(kipp); + procstat_rlimit(prstat, kipp); else if (sflag) procstat_cred(prstat, kipp); else if (tflag) procstat_threads(prstat, kipp); else if (vflag) procstat_vm(prstat, kipp); else if (xflag) procstat_auxv(kipp); else procstat_basic(kipp); } /* * Sort processes first by pid and then tid. */ static int kinfo_proc_compare(const void *a, const void *b) { int i; i = ((const struct kinfo_proc *)a)->ki_pid - ((const struct kinfo_proc *)b)->ki_pid; if (i != 0) return (i); i = ((const struct kinfo_proc *)a)->ki_tid - ((const struct kinfo_proc *)b)->ki_tid; return (i); } void kinfo_proc_sort(struct kinfo_proc *kipp, int count) { qsort(kipp, count, sizeof(*kipp), kinfo_proc_compare); } int main(int argc, char *argv[]) { int ch, interval, tmp; int i; struct kinfo_proc *p; struct procstat *prstat; long l; pid_t pid; char *dummy; char *nlistf, *memf; int cnt; interval = 0; memf = nlistf = NULL; while ((ch = getopt(argc, argv, "CN:M:abcefijklhstvw:x")) != -1) { switch (ch) { case 'C': Cflag++; break; case 'M': memf = optarg; break; case 'N': nlistf = optarg; break; case 'a': aflag++; break; case 'b': bflag++; break; case 'c': cflag++; break; case 'e': eflag++; break; case 'f': fflag++; break; case 'i': iflag++; break; case 'j': jflag++; break; case 'k': kflag++; break; case 'l': lflag++; break; case 'n': nflag++; break; case 'h': hflag++; break; case 's': sflag++; break; case 't': tflag++; break; case 'v': vflag++; break; case 'w': l = strtol(optarg, &dummy, 10); if (*dummy != '\0') usage(); if (l < 1 || l > INT_MAX) usage(); interval = l; break; case 'x': xflag++; break; case '?': default: usage(); } } argc -= optind; argv += optind; /* We require that either 0 or 1 mode flags be set. */ tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) + lflag + sflag + tflag + vflag + xflag; if (!(tmp == 0 || tmp == 1)) usage(); /* We allow -k to be specified up to twice, but not more. */ if (kflag > 2) usage(); /* Must specify either the -a flag or a list of pids. */ if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0)) usage(); /* Only allow -C with -f. */ if (Cflag && !fflag) usage(); if (memf != NULL) prstat = procstat_open_kvm(nlistf, memf); else prstat = procstat_open_sysctl(); if (prstat == NULL) errx(1, "procstat_open()"); do { if (aflag) { p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt); if (p == NULL) errx(1, "procstat_getprocs()"); kinfo_proc_sort(p, cnt); for (i = 0; i < cnt; i++) { procstat(prstat, &p[i]); /* Suppress header after first process. */ hflag = 1; } procstat_freeprocs(prstat, p); } for (i = 0; i < argc; i++) { l = strtol(argv[i], &dummy, 10); if (*dummy != '\0') usage(); if (l < 0) usage(); pid = l; p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt); if (p == NULL) errx(1, "procstat_getprocs()"); if (cnt != 0) procstat(prstat, p); procstat_freeprocs(prstat, p); /* Suppress header after first process. */ hflag = 1; } if (interval) sleep(interval); } while (interval); procstat_close(prstat); exit(0); } Index: head/usr.bin/procstat/procstat.h =================================================================== --- head/usr.bin/procstat/procstat.h (revision 249674) +++ head/usr.bin/procstat/procstat.h (revision 249675) @@ -1,51 +1,51 @@ /*- * Copyright (c) 2007 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef PROCSTAT_H #define PROCSTAT_H extern int hflag, nflag, Cflag; struct kinfo_proc; void kinfo_proc_sort(struct kinfo_proc *kipp, int count); void procstat_args(struct kinfo_proc *kipp); void procstat_auxv(struct kinfo_proc *kipp); void procstat_basic(struct kinfo_proc *kipp); void procstat_bin(struct kinfo_proc *kipp); void procstat_cred(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_env(struct kinfo_proc *kipp); void procstat_files(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_kstack(struct kinfo_proc *kipp, int kflag); -void procstat_rlimit(struct kinfo_proc *kipp); +void procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_threads(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_threads_sigs(struct procstat *prstat, struct kinfo_proc *kipp); void procstat_vm(struct procstat *prstat, struct kinfo_proc *kipp); #endif /* !PROCSTAT_H */ Index: head/usr.bin/procstat/procstat_rlimit.c =================================================================== --- head/usr.bin/procstat/procstat_rlimit.c (revision 249674) +++ head/usr.bin/procstat/procstat_rlimit.c (revision 249675) @@ -1,119 +1,106 @@ /*- * Copyright (c) 2011 Mikolaj Golub * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "procstat.h" static struct { const char *name; const char *suffix; } rlimit_param[13] = { {"cputime", "sec"}, {"filesize", "B "}, {"datasize", "B "}, {"stacksize", "B "}, {"coredumpsize", "B "}, {"memoryuse", "B "}, {"memorylocked", "B "}, {"maxprocesses", " "}, {"openfiles", " "}, {"sbsize", "B "}, {"vmemoryuse", "B "}, {"pseudo-terminals", " "}, {"swapuse", "B "}, }; #if RLIM_NLIMITS > 13 #error "Resource limits have grown. Add new entries to rlimit_param[]." #endif static const char * humanize_rlimit(int indx, rlim_t limit) { static char buf[14]; int scale; if (limit == RLIM_INFINITY) return ("infinity "); scale = humanize_number(buf, sizeof(buf) - 1, (int64_t)limit, rlimit_param[indx].suffix, HN_AUTOSCALE | HN_GETSCALE, HN_DECIMAL); (void)humanize_number(buf, sizeof(buf) - 1, (int64_t)limit, rlimit_param[indx].suffix, HN_AUTOSCALE, HN_DECIMAL); /* Pad with one space if there is no suffix prefix. */ if (scale == 0) sprintf(buf + strlen(buf), " "); return (buf); } void -procstat_rlimit(struct kinfo_proc *kipp) +procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp) { struct rlimit rlimit; - int error, i, name[5]; - size_t len; + int i; if (!hflag) { printf("%5s %-16s %-16s %16s %16s\n", "PID", "COMM", "RLIMIT", "SOFT ", "HARD "); } - len = sizeof(struct rlimit); - name[0] = CTL_KERN; - name[1] = KERN_PROC; - name[2] = KERN_PROC_RLIMIT; - name[3] = kipp->ki_pid; for (i = 0; i < RLIM_NLIMITS; i++) { - name[4] = i; - error = sysctl(name, 5, &rlimit, &len, NULL, 0); - if (error < 0 && errno != ESRCH) { - warn("sysctl: kern.proc.rlimit: %d", kipp->ki_pid); + if (procstat_getrlimit(prstat, kipp, i, &rlimit) == -1) return; - } - if (error < 0 || len != sizeof(struct rlimit)) - return; - printf("%5d %-16s %-16s ", kipp->ki_pid, kipp->ki_comm, rlimit_param[i].name); printf("%16s ", humanize_rlimit(i, rlimit.rlim_cur)); printf("%16s\n", humanize_rlimit(i, rlimit.rlim_max)); } }