From 7f1d14e6e67f6c42b23d598a811cb3593302f6c4 Mon Sep 17 00:00:00 2001 From: Mikolaj Golub Date: Sat, 20 Apr 2013 07:54:07 +0000 Subject: [PATCH] Add procstat_getgroups function to retrieve process groups. MFC after: 1 month --- lib/libprocstat/Symbol.map | 2 ++ lib/libprocstat/core.c | 4 +++ lib/libprocstat/core.h | 1 + lib/libprocstat/libprocstat.3 | 27 ++++++++++++++ lib/libprocstat/libprocstat.c | 67 +++++++++++++++++++++++++++++++++++ lib/libprocstat/libprocstat.h | 3 ++ 6 files changed, 104 insertions(+) diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map index aa7465989c90..5ac5ee1f08ed 100644 --- a/lib/libprocstat/Symbol.map +++ b/lib/libprocstat/Symbol.map @@ -16,8 +16,10 @@ FBSD_1.2 { }; FBSD_1.3 { + procstat_freegroups; procstat_freevmmap; procstat_get_shm_info; + procstat_getgroups; procstat_getvmmap; procstat_open_core; }; diff --git a/lib/libprocstat/core.c b/lib/libprocstat/core.c index 1ada45927de3..afaa76c000fb 100644 --- a/lib/libprocstat/core.c +++ b/lib/libprocstat/core.c @@ -167,6 +167,10 @@ procstat_core_get(struct procstat_core *core, enum psc_type type, void *buf, n_type = NT_PROCSTAT_VMMAP; structsize = sizeof(struct kinfo_vmentry); break; + case PSC_TYPE_GROUPS: + n_type = NT_PROCSTAT_GROUPS; + structsize = sizeof(gid_t); + break; default: warnx("unknown core stat type: %d", type); return (NULL); diff --git a/lib/libprocstat/core.h b/lib/libprocstat/core.h index 8e2dd13ff4d1..54efa29464bc 100644 --- a/lib/libprocstat/core.h +++ b/lib/libprocstat/core.h @@ -33,6 +33,7 @@ enum psc_type { PSC_TYPE_PROC, PSC_TYPE_FILES, PSC_TYPE_VMMAP, + PSC_TYPE_GROUPS, }; struct procstat_core; diff --git a/lib/libprocstat/libprocstat.3 b/lib/libprocstat/libprocstat.3 index 18dc1e9f1b23..b38ce1c44baf 100644 --- a/lib/libprocstat/libprocstat.3 +++ b/lib/libprocstat/libprocstat.3 @@ -33,9 +33,11 @@ .Nm procstat_open_sysctl , .Nm procstat_close , .Nm procstat_getfiles , +.Nm procstat_getgroups , .Nm procstat_getprocs , .Nm procstat_getvmmap , .Nm procstat_freefiles , +.Nm procstat_freegroups , .Nm procstat_freeprocs , .Nm procstat_freevmmap , .Nm procstat_get_pipe_info , @@ -52,12 +54,18 @@ .In libprocstat.h .Ft void .Fn procstat_close "struct procstat *procstat" +.Fc .Ft void .Fo procstat_freefiles .Fa "struct procstat *procstat" .Fa "struct filestat_list *head" .Fc .Ft void +.Fo procstat_freegroups +.Fa "struct procstat *procstat" +.Fa "gid_t *groups" +.Fc +.Ft void .Fn procstat_freeprocs "struct procstat *procstat" "struct kinfo_proc *p" .Ft void .Fo procstat_freevmmap @@ -105,6 +113,12 @@ .Fa "struct kinfo_proc *kp" .Fa "int mmapped" .Fc +.Ft "gid_t *" +.Fo procstat_getgroups +.Fa "struct procstat *procstat" +.Fa "struct kinfo_proc *kp" +.Fa "unsigned int *count" +.Fc .Ft "struct kinfo_proc *" .Fo procstat_getprocs .Fa "struct procstat *procstat" @@ -227,6 +241,19 @@ The caller is responsible to free the allocated memory with a subsequent function call. .Pp The +.Fn procstat_getgroups +function gets a pointer to the +.Vt procstat +structure, a pointer to +.Vt kinfo_proc +structure, and returns the process groups as a dynamically allocated array of +.Vt gid_t +elements. +The caller is responsible to free the allocated memory with a subsequent +.Fn procstat_freegroups +function call. +.Pp +The .Fn procstat_getvmmap function gets a pointer to the .Vt procstat diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index 283f80281831..b300b1f01086 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -132,6 +132,9 @@ static int procstat_get_vnode_info_kvm(kvm_t *kd, struct filestat *fst, struct vnstat *vn, char *errbuf); static int procstat_get_vnode_info_sysctl(struct filestat *fst, struct vnstat *vn, char *errbuf); +static gid_t *procstat_getgroups_core(struct procstat_core *core, + unsigned int *count); +static gid_t *procstat_getgroups_sysctl(pid_t pid, unsigned int *count); static int vntype2psfsttype(int type); void @@ -1588,3 +1591,67 @@ procstat_freevmmap(struct procstat *procstat __unused, free(vmmap); } + +static gid_t * +procstat_getgroups_sysctl(pid_t pid, unsigned int *cntp) +{ + int mib[4]; + size_t len; + gid_t *groups; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_GROUPS; + mib[3] = pid; + len = (sysconf(_SC_NGROUPS_MAX) + 1) * sizeof(gid_t); + groups = malloc(len); + if (groups == NULL) { + warn("malloc(%zu)", len); + return (NULL); + } + if (sysctl(mib, 4, groups, &len, NULL, 0) == -1) { + warn("sysctl: kern.proc.groups: %d", pid); + free(groups); + return (NULL); + } + *cntp = len / sizeof(gid_t); + return (groups); +} + +static gid_t * +procstat_getgroups_core(struct procstat_core *core, unsigned int *cntp) +{ + size_t len; + gid_t *groups; + + groups = procstat_core_get(core, PSC_TYPE_GROUPS, NULL, &len); + if (groups == NULL) + return (NULL); + *cntp = len / sizeof(gid_t); + return (groups); +} + +gid_t * +procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp, + unsigned int *cntp) +{ + switch(procstat->type) { + case PROCSTAT_KVM: + warnx("kvm method is not supported"); + return (NULL); + case PROCSTAT_SYSCTL: + return (procstat_getgroups_sysctl(kp->ki_pid, cntp)); + case PROCSTAT_CORE: + return (procstat_getgroups_core(procstat->core, cntp)); + default: + warnx("unknown access method: %d", procstat->type); + return (NULL); + } +} + +void +procstat_freegroups(struct procstat *procstat __unused, gid_t *groups) +{ + + free(groups); +} diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h index 71d85a11bb5f..0c4e77a6c8e9 100644 --- a/lib/libprocstat/libprocstat.h +++ b/lib/libprocstat/libprocstat.h @@ -146,6 +146,7 @@ STAILQ_HEAD(filestat_list, filestat); __BEGIN_DECLS void procstat_close(struct procstat *procstat); +void procstat_freegroups(struct procstat *procstat, gid_t *groups); void procstat_freeprocs(struct procstat *procstat, struct kinfo_proc *p); void procstat_freefiles(struct procstat *procstat, struct filestat_list *head); @@ -165,6 +166,8 @@ int procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, struct sockstat *sock, char *errbuf); int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, struct vnstat *vn, char *errbuf); +gid_t *procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp, + unsigned int *count); struct kinfo_vmentry *procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp, unsigned int *count); struct procstat *procstat_open_core(const char *filename);