From 5b9bcba971ab2c6bc9f1240e43ac8459e1de9075 Mon Sep 17 00:00:00 2001 From: Mikolaj Golub Date: Sat, 20 Apr 2013 07:57:08 +0000 Subject: [PATCH] Add procstat_getumask function to retrieve a process umask. MFC after: 1 month --- lib/libprocstat/Symbol.map | 1 + lib/libprocstat/core.c | 4 +++ lib/libprocstat/core.h | 1 + lib/libprocstat/libprocstat.3 | 15 +++++++++ lib/libprocstat/libprocstat.c | 57 +++++++++++++++++++++++++++++++++++ lib/libprocstat/libprocstat.h | 2 ++ 6 files changed, 80 insertions(+) diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map index 5ac5ee1f08ed..1970a7a2d944 100644 --- a/lib/libprocstat/Symbol.map +++ b/lib/libprocstat/Symbol.map @@ -20,6 +20,7 @@ FBSD_1.3 { procstat_freevmmap; procstat_get_shm_info; procstat_getgroups; + procstat_getumask; procstat_getvmmap; procstat_open_core; }; diff --git a/lib/libprocstat/core.c b/lib/libprocstat/core.c index afaa76c000fb..5732f406643f 100644 --- a/lib/libprocstat/core.c +++ b/lib/libprocstat/core.c @@ -171,6 +171,10 @@ procstat_core_get(struct procstat_core *core, enum psc_type type, void *buf, n_type = NT_PROCSTAT_GROUPS; structsize = sizeof(gid_t); break; + case PSC_TYPE_UMASK: + n_type = NT_PROCSTAT_UMASK; + structsize = sizeof(u_short); + break; default: warnx("unknown core stat type: %d", type); return (NULL); diff --git a/lib/libprocstat/core.h b/lib/libprocstat/core.h index 54efa29464bc..6e7ed027b0c4 100644 --- a/lib/libprocstat/core.h +++ b/lib/libprocstat/core.h @@ -34,6 +34,7 @@ enum psc_type { PSC_TYPE_FILES, PSC_TYPE_VMMAP, PSC_TYPE_GROUPS, + PSC_TYPE_UMASK, }; struct procstat_core; diff --git a/lib/libprocstat/libprocstat.3 b/lib/libprocstat/libprocstat.3 index b38ce1c44baf..06a66a06bca0 100644 --- a/lib/libprocstat/libprocstat.3 +++ b/lib/libprocstat/libprocstat.3 @@ -35,6 +35,7 @@ .Nm procstat_getfiles , .Nm procstat_getgroups , .Nm procstat_getprocs , +.Nm procstat_getumask , .Nm procstat_getvmmap , .Nm procstat_freefiles , .Nm procstat_freegroups , @@ -126,6 +127,12 @@ .Fa "int arg" .Fa "unsigned int *count" .Fc +.Ft "int" +.Fo procstat_getumask +.Fa "struct procstat *procstat" +.Fa "struct kinfo_proc *kp" +.Fa "unsigned short *maskp" +.Fc .Ft "struct kinfo_vmentry *" .Fo procstat_getvmmap .Fa "struct procstat *procstat" @@ -254,6 +261,14 @@ The caller is responsible to free the allocated memory with a subsequent function call. .Pp The +.Fn procstat_getumask +function gets a pointer to the +.Vt procstat +structure, a pointer to +.Vt kinfo_proc +structure, and returns the process umask in the 3rd reference parameter. +.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 b300b1f01086..1ee0f973bebc 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -135,6 +135,9 @@ static int procstat_get_vnode_info_sysctl(struct filestat *fst, 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 procstat_getumask_core(struct procstat_core *core, + unsigned short *maskp); +static int procstat_getumask_sysctl(pid_t pid, unsigned short *maskp); static int vntype2psfsttype(int type); void @@ -1655,3 +1658,57 @@ procstat_freegroups(struct procstat *procstat __unused, gid_t *groups) free(groups); } + +static int +procstat_getumask_sysctl(pid_t pid, unsigned short *maskp) +{ + int error; + int mib[4]; + size_t len; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_UMASK; + mib[3] = pid; + len = sizeof(*maskp); + error = sysctl(mib, 4, maskp, &len, NULL, 0); + if (error != 0 && errno != ESRCH) + warn("sysctl: kern.proc.umask: %d", pid); + return (error); +} + +static int +procstat_getumask_core(struct procstat_core *core, unsigned short *maskp) +{ + size_t len; + unsigned short *buf; + + buf = procstat_core_get(core, PSC_TYPE_UMASK, NULL, &len); + if (buf == NULL) + return (-1); + if (len < sizeof(*maskp)) { + free(buf); + return (-1); + } + *maskp = *buf; + free(buf); + return (0); +} + +int +procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp, + unsigned short *maskp) +{ + switch(procstat->type) { + case PROCSTAT_KVM: + warnx("kvm method is not supported"); + return (-1); + case PROCSTAT_SYSCTL: + return (procstat_getumask_sysctl(kp->ki_pid, maskp)); + case PROCSTAT_CORE: + return (procstat_getumask_core(procstat->core, maskp)); + default: + warnx("unknown access method: %d", procstat->type); + return (-1); + } +} diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h index 0c4e77a6c8e9..8d14d0fa8936 100644 --- a/lib/libprocstat/libprocstat.h +++ b/lib/libprocstat/libprocstat.h @@ -168,6 +168,8 @@ 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); +int procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp, + unsigned short* umask); struct kinfo_vmentry *procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp, unsigned int *count); struct procstat *procstat_open_core(const char *filename);