summaryrefslogtreecommitdiffstats
path: root/usr.bin/procstat
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2009-07-24 19:12:19 +0000
committerbrooks <brooks@FreeBSD.org>2009-07-24 19:12:19 +0000
commitd91fda355ee8239b1a125f7d226b0832e81c0057 (patch)
tree90ae3d5c9e2e933a2c805eaad537cdb35cf8f668 /usr.bin/procstat
parent5b6f89676ef99f8a802a7b7ae533edccf870e319 (diff)
downloadFreeBSD-src-d91fda355ee8239b1a125f7d226b0832e81c0057.zip
FreeBSD-src-d91fda355ee8239b1a125f7d226b0832e81c0057.tar.gz
Introduce a new sysctl process mib, kern.proc.groups which adds the
ability to retrieve the group list of each process. Modify procstat's -s option to query this mib when the kinfo_proc reports that the field has been truncated. If the mib does not exist, fall back to the truncated list. Reviewed by: rwatson Approved by: re (kib) MFC after: 2 weeks
Diffstat (limited to 'usr.bin/procstat')
-rw-r--r--usr.bin/procstat/procstat_cred.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/usr.bin/procstat/procstat_cred.c b/usr.bin/procstat/procstat_cred.c
index a84924a..1e91a94 100644
--- a/usr.bin/procstat/procstat_cred.c
+++ b/usr.bin/procstat/procstat_cred.c
@@ -31,7 +31,9 @@
#include <sys/user.h>
#include <err.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
#include "procstat.h"
@@ -39,6 +41,10 @@ void
procstat_cred(pid_t pid, struct kinfo_proc *kipp)
{
int i;
+ int mib[4];
+ int ngroups;
+ size_t len;
+ gid_t *groups = NULL;
if (!hflag)
printf("%5s %-16s %5s %5s %5s %5s %5s %5s %-20s\n", "PID",
@@ -53,7 +59,39 @@ procstat_cred(pid_t pid, struct kinfo_proc *kipp)
printf("%5d ", kipp->ki_groups[0]);
printf("%5d ", kipp->ki_rgid);
printf("%5d ", kipp->ki_svgid);
- for (i = 0; i < kipp->ki_ngroups; i++)
- printf("%s%d", (i > 0) ? "," : "", kipp->ki_groups[i]);
+
+ /*
+ * We may have too many groups to fit in kinfo_proc's statically
+ * sized storage. If that occurs, attempt to retrieve them via
+ * sysctl.
+ */
+ if (kipp->ki_cr_flags & KI_CRF_GRP_OVERFLOW) {
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_GROUPS;
+ mib[3] = pid;
+
+ ngroups = sysconf(_SC_NGROUPS_MAX) + 1;
+ len = ngroups * sizeof(gid_t);
+ if((groups = malloc(len)) == NULL)
+ err(-1, "malloc");
+
+ if (sysctl(mib, 4, groups, &len, NULL, 0) == -1) {
+ warn("sysctl: kern.proc.groups: %d "
+ "group list truncated", pid);
+ free(groups);
+ groups = NULL;
+ }
+ ngroups = len / sizeof(gid_t);
+ }
+ if (groups == NULL) {
+ ngroups = kipp->ki_ngroups;
+ groups = kipp->ki_groups;
+ }
+ for (i = 0; i < ngroups; i++)
+ printf("%s%d", (i > 0) ? "," : "", groups[i]);
+ if (groups != kipp->ki_groups)
+ free(groups);
+
printf("\n");
}
OpenPOWER on IntegriCloud