summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2000-09-26 01:03:16 +0000
committerbrian <brian@FreeBSD.org>2000-09-26 01:03:16 +0000
commit83939ad7a04f777c47adb3b7d408b1b9c3bfb9bb (patch)
tree85a648d7305f70b65e5fa8d26ee6d781f75a0c21 /bin
parent52664bd5ff415cd7ec29ae2100286597cb326acc (diff)
downloadFreeBSD-src-83939ad7a04f777c47adb3b7d408b1b9c3bfb9bb.zip
FreeBSD-src-83939ad7a04f777c47adb3b7d408b1b9c3bfb9bb.tar.gz
Support multiple (comma separated) names as arguments to -U
PR: 11051
Diffstat (limited to 'bin')
-rw-r--r--bin/ps/ps.16
-rw-r--r--bin/ps/ps.c82
2 files changed, 73 insertions, 15 deletions
diff --git a/bin/ps/ps.1 b/bin/ps/ps.1
index f89f8da..5510c42 100644
--- a/bin/ps/ps.1
+++ b/bin/ps/ps.1
@@ -47,7 +47,9 @@
.Op Fl o Ar fmt
.Op Fl p Ar pid
.Op Fl t Ar tty
-.Op Fl U Ar username
+.Oo Fl U Ar username Ns
+.Op , Ns Ar username Ns No ...
+.Oc
.Op Fl W Ar swap
.Nm ps
.Op Fl L
@@ -145,7 +147,7 @@ Display information about processes attached to the specified terminal
device.
.It Fl U
Display the processes belonging to the specified
-.Tn username .
+.Tn username Ns No (s).
.It Fl u
Display information associated with the following keywords:
user, pid, %cpu, %mem, vsz, rss, tt, state, start, time and command.
diff --git a/bin/ps/ps.c b/bin/ps/ps.c
index a3411e1..9f513b2 100644
--- a/bin/ps/ps.c
+++ b/bin/ps/ps.c
@@ -67,9 +67,12 @@ static const char rcsid[] =
#include <unistd.h>
#include <locale.h>
#include <pwd.h>
+#include <utmp.h>
#include "ps.h"
+#define SEP ", \t" /* username separators */
+
KINFO *kinfo;
struct varent *vhead, *vtail;
@@ -98,6 +101,7 @@ static void scanvars __P((void));
static void dynsizevars __P((KINFO *));
static void sizevars __P((void));
static void usage __P((void));
+static uid_t *getuids(const char *, int *);
char dfmt[] = "pid tt state time command";
char jfmt[] = "user pid ppid pgid sess jobc state tt time command";
@@ -117,12 +121,11 @@ main(argc, argv)
struct kinfo_proc *kp;
struct varent *vent;
struct winsize ws;
- struct passwd *pwd;
dev_t ttydev;
pid_t pid;
- uid_t uid;
+ uid_t *uids;
int all, ch, flag, i, fmt, lineno, nentries, dropgid;
- int prtheader, wflag, what, xflg;
+ int prtheader, wflag, what, xflg, uid, nuids;
char *nlistf, *memf, *swapf, errbuf[_POSIX2_LINE_MAX];
(void) setlocale(LC_ALL, "");
@@ -140,7 +143,8 @@ main(argc, argv)
all = fmt = prtheader = wflag = xflg = 0;
pid = -1;
- uid = (uid_t) -1;
+ nuids = 0;
+ uids = NULL;
ttydev = NODEV;
dropgid = 0;
memf = nlistf = swapf = _PATH_DEVNULL;
@@ -242,11 +246,7 @@ main(argc, argv)
break;
}
case 'U':
- pwd = getpwnam(optarg);
- if (pwd == NULL)
- errx(1, "%s: no such user", optarg);
- uid = pwd->pw_uid;
- endpwent();
+ uids = getuids(optarg, &nuids);
xflg++; /* XXX: intuitive? */
break;
case 'u':
@@ -310,8 +310,12 @@ main(argc, argv)
parsefmt(dfmt);
/* XXX - should be cleaner */
- if (!all && ttydev == NODEV && pid == -1 && uid == (uid_t)-1)
- uid = getuid();
+ if (!all && ttydev == NODEV && pid == -1 && !nuids) {
+ if ((uids = malloc(sizeof (*uids))) == NULL)
+ errx(1, "malloc: %s", strerror(errno));
+ nuids = 1;
+ *uids = getuid();
+ }
/*
* scan requested variables, noting what structures are needed,
@@ -321,9 +325,9 @@ main(argc, argv)
/*
* get proc list
*/
- if (uid != (uid_t) -1) {
+ if (nuids == 1) {
what = KERN_PROC_UID;
- flag = uid;
+ flag = *uids;
} else if (ttydev != NODEV) {
what = KERN_PROC_TTY;
flag = ttydev;
@@ -367,6 +371,14 @@ main(argc, argv)
if (xflg == 0 && (KI_EPROC(&kinfo[i])->e_tdev == NODEV ||
(KI_PROC(&kinfo[i])->p_flag & P_CONTROLT ) == 0))
continue;
+ if (nuids > 1) {
+ for (uid = 0; uid < nuids; uid++)
+ if (KI_EPROC(&kinfo[i])->e_ucred.cr_uid ==
+ uids[uid])
+ break;
+ if (uid == nuids)
+ continue;
+ }
for (vent = vhead; vent; vent = vent->next) {
(vent->var->oproc)(&kinfo[i], vent);
if (vent->next != NULL)
@@ -379,9 +391,53 @@ main(argc, argv)
lineno = 0;
}
}
+ free(uids);
+
exit(eval);
}
+uid_t *
+getuids(const char *arg, int *nuids)
+{
+ char name[UT_NAMESIZE + 1];
+ struct passwd *pwd;
+ uid_t *uids, *moreuids;
+ int l, alloc;
+
+
+ alloc = 0;
+ *nuids = 0;
+ uids = NULL;
+ for (; (l = strcspn(arg, SEP)) > 0; arg += l + strspn(arg + l, SEP)) {
+ if (l >= sizeof name) {
+ warnx("%.*s: name too long", l, arg);
+ continue;
+ }
+ strncpy(name, arg, l);
+ name[l] = '\0';
+ if ((pwd = getpwnam(name)) == NULL) {
+ warnx("%s: no such user", name);
+ continue;
+ }
+ if (*nuids >= alloc) {
+ alloc = (alloc + 1) << 1;
+ moreuids = realloc(uids, alloc * sizeof (*uids));
+ if (moreuids == NULL) {
+ free(uids);
+ errx(1, "realloc: %s", strerror(errno));
+ }
+ uids = moreuids;
+ }
+ uids[(*nuids)++] = pwd->pw_uid;
+ }
+ endpwent();
+
+ if (!*nuids)
+ errx(1, "No users specified");
+
+ return uids;
+}
+
static void
scanvars()
{
OpenPOWER on IntegriCloud