diff --git a/usr.bin/ipcs/ipcs.1 b/usr.bin/ipcs/ipcs.1 index 0fa25d20fe15..cbb970670f10 100644 --- a/usr.bin/ipcs/ipcs.1 +++ b/usr.bin/ipcs/ipcs.1 @@ -131,6 +131,11 @@ using .Xr kvm 3 will require read privileges to .Pa /dev/kmem . +.It Fl u Ar user +Display information about IPC mechanisms owned by +.Pa user . +User specification can be in the form of a numeric UID or +a login name. .El .Pp If none of the diff --git a/usr.bin/ipcs/ipcs.c b/usr.bin/ipcs/ipcs.c index a51f17e32474..ce2a759468b5 100644 --- a/usr.bin/ipcs/ipcs.c +++ b/usr.bin/ipcs/ipcs.c @@ -74,6 +74,7 @@ void cvt_time(time_t, char *); void sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vec); void kget(int idx, void *addr, size_t size); void usage(void); +uid_t user2uid(char *username); static struct nlist symbols[] = { {"sema"}, @@ -188,11 +189,12 @@ main(argc, argv) { int display = SHMINFO | MSGINFO | SEMINFO; int option = 0; - char *core = NULL, *namelist = NULL; + char *core = NULL, *user = NULL, *namelist = NULL; char kvmoferr[_POSIX2_LINE_MAX]; /* Error buf for kvm_openfiles. */ int i; + uid_t uid; - while ((i = getopt(argc, argv, "MmQqSsabC:cN:optTy")) != -1) + while ((i = getopt(argc, argv, "MmQqSsabC:cN:optTu:y")) != -1) switch (i) { case 'M': display = SHMTOTAL; @@ -242,6 +244,10 @@ main(argc, argv) case 'y': use_sysctl = 0; break; + case 'u': + user = optarg; + uid = user2uid(user); + break; default: usage(); } @@ -320,6 +326,9 @@ main(argc, argv) ctime_buf[100]; struct msqid_ds *msqptr = &xmsqids[i]; + if (user) + if (uid != msqptr->msg_perm.uid) + continue; cvt_time(msqptr->msg_stime, stime_buf); cvt_time(msqptr->msg_rtime, rtime_buf); cvt_time(msqptr->msg_ctime, ctime_buf); @@ -409,6 +418,9 @@ main(argc, argv) ctime_buf[100]; struct shmid_ds *shmptr = &xshmids[i]; + if (user) + if (uid != shmptr->shm_perm.uid) + continue; cvt_time(shmptr->shm_atime, atime_buf); cvt_time(shmptr->shm_dtime, dtime_buf); cvt_time(shmptr->shm_ctime, ctime_buf); @@ -502,6 +514,9 @@ main(argc, argv) char ctime_buf[100], otime_buf[100]; struct semid_ds *semaptr = &xsema[i]; + if (user) + if (uid != semaptr->sem_perm.uid) + continue; cvt_time(semaptr->sem_otime, otime_buf); cvt_time(semaptr->sem_ctime, ctime_buf); @@ -649,11 +664,27 @@ kget(idx, addr, size) } } +uid_t +user2uid(char *username) +{ + struct passwd *pwd; + uid_t uid; + char *r; + + uid = strtoul(username, &r, 0); + if (!*r && r != username) + return (uid); + if ((pwd = getpwnam(username)) == NULL) + errx(1, "getpwnam failed: No such user"); + endpwent(); + return (pwd->pw_uid); +} + void usage() { fprintf(stderr, - "usage: ipcs [-abcmopqstyMQST] [-C corefile] [-N namelist]\n"); + "usage: ipcs [-abcmopqstyMQST] [-C corefile] [-N namelist] [-u user]\n"); exit(1); }