diff options
Diffstat (limited to 'usr/src/cmd/pgrep/pgrep.c')
-rw-r--r-- | usr/src/cmd/pgrep/pgrep.c | 112 |
1 files changed, 81 insertions, 31 deletions
diff --git a/usr/src/cmd/pgrep/pgrep.c b/usr/src/cmd/pgrep/pgrep.c index 4531f11267..0fda6733fb 100644 --- a/usr/src/cmd/pgrep/pgrep.c +++ b/usr/src/cmd/pgrep/pgrep.c @@ -24,6 +24,10 @@ */ /* Copyright (c) 2012 by Delphix. All rights reserved */ +/* + * Copyright 2019 Joyent, Inc. + */ + #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> @@ -59,11 +63,11 @@ #define TEXT_DOMAIN "SYS_TEST" #endif -#define OPT_SETB 0x0001 /* Set the bits specified by o_bits */ -#define OPT_CLRB 0x0002 /* Clear the bits specified by o_bits */ -#define OPT_FUNC 0x0004 /* Call the function specified by o_func */ -#define OPT_STR 0x0008 /* Set the string specified by o_ptr */ -#define OPT_CRIT 0x0010 /* Option is part of selection criteria */ +#define OPT_SETB 0x0001 /* Set the bits specified by o_bits */ +#define OPT_CLRB 0x0002 /* Clear the bits specified by o_bits */ +#define OPT_FUNC 0x0004 /* Call the function specified by o_func */ +#define OPT_STR 0x0008 /* Set the string specified by o_ptr */ +#define OPT_CRIT 0x0010 /* Option is part of selection criteria */ #define F_LONG_FMT 0x0001 /* Match against long format cmd */ #define F_NEWEST 0x0002 /* Match only newest pid */ @@ -138,7 +142,7 @@ static optdesc_t g_optdtab[] = { { 0, 0, 0, 0 }, /* 'k' */ { OPT_SETB, F_LONG_OUT, 0, &g_flags }, /* 'l' */ { 0, 0, 0, 0 }, /* 'm' */ - { OPT_SETB, F_NEWEST, 0, &g_flags }, /* -n */ + { OPT_SETB, F_NEWEST, 0, &g_flags }, /* -n */ { OPT_SETB, F_OLDEST, 0, &g_flags }, /* -o */ { 0, 0, 0, 0 }, /* 'p' */ { 0, 0, 0, 0 }, /* 'q' */ @@ -173,7 +177,7 @@ static pid_t g_pid; /* Current pid */ static int g_signal = SIGTERM; /* Signal to send */ static void -print_proc(psinfo_t *psinfo) +print_proc(psinfo_t *psinfo, char *argv __unused, size_t len __unused) { if (g_flags & F_OUTPUT) (void) printf("%s%d", g_delim, (int)psinfo->pr_pid); @@ -183,7 +187,7 @@ print_proc(psinfo_t *psinfo) } } -static char * +static void mbstrip(char *buf, size_t nbytes) { wchar_t wc; @@ -191,6 +195,7 @@ mbstrip(char *buf, size_t nbytes) int n; buf[nbytes - 1] = '\0'; + p = buf; while (*p != '\0') { @@ -212,30 +217,23 @@ mbstrip(char *buf, size_t nbytes) p += n; } } - - return (buf); } static void -print_proc_long(psinfo_t *psinfo) +print_proc_long(psinfo_t *psinfo, char *argv, size_t len) { - char *name; - - if (g_flags & F_LONG_FMT) - name = mbstrip(psinfo->pr_psargs, PRARGSZ); - else - name = psinfo->pr_fname; + mbstrip(argv, len); if (g_flags & F_OUTPUT) - (void) printf("%s%5d %s", g_delim, (int)psinfo->pr_pid, name); + (void) printf("%s%5d %s", g_delim, (int)psinfo->pr_pid, argv); else { - (void) printf("%5d %s", (int)psinfo->pr_pid, name); + (void) printf("%5d %s", (int)psinfo->pr_pid, argv); g_flags |= F_OUTPUT; } } static void -kill_proc(psinfo_t *psinfo) +kill_proc(psinfo_t *psinfo, char *argv __unused, size_t len __unused) { if (psinfo->pr_pid > 0 && kill(psinfo->pr_pid, g_signal) == -1) uu_warn(gettext("Failed to signal pid %d"), @@ -268,6 +266,46 @@ open_proc_dir(const char *dirpath) return (dirp); } +static void +get_argv(int flags, psinfo_t *ps, char *buf, size_t bufsize) +{ + char *path = NULL; + ssize_t size = 0; + int fd; + + if (!(flags & F_LONG_FMT)) { + (void) strlcpy(buf, ps->pr_fname, bufsize); + return; + } + + if (getenv("SHORT_PSARGS") != NULL) { + (void) strlcpy(buf, ps->pr_psargs, bufsize); + return; + } + + if (asprintf(&path, "%s/%d/cmdline", g_procdir, + (int)ps->pr_pid) != -1 && (fd = open(path, O_RDONLY)) != -1) { + size = read(fd, buf, bufsize); + (void) close(fd); + } + + free(path); + + if (size <= 0) { + (void) strlcpy(buf, ps->pr_psargs, bufsize); + } else { + buf[bufsize - 1] = '\0'; + for (char *cp = buf; cp - buf < size; cp++) { + if (*cp == '\0' && (cp - buf) + 1 < size) + *cp = ' '; + } + } + + for (ssize_t i = strlen(buf) - 1; i >= 0 && isspace(buf[i]); i--) { + buf[i] = '\0'; + } +} + #define NEWER(ps1, ps2) \ ((ps1.pr_start.tv_sec > ps2.pr_start.tv_sec) || \ (ps1.pr_start.tv_sec == ps2.pr_start.tv_sec && \ @@ -275,9 +313,10 @@ open_proc_dir(const char *dirpath) static int scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, - void (*funcp)(psinfo_t *)) + void (*funcp)(psinfo_t *, char *, size_t)) { char procpath[MAXPATHLEN]; + char argv[PRMAXARGVLEN] = ""; psinfo_t ps, ops; dirent_t *dent; int procfd; @@ -285,9 +324,6 @@ scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, int reverse = (g_flags & F_REVERSE) ? 1 : 0; int ovalid = 0, nmatches = 0, flags = 0; - if (g_flags & F_LONG_FMT) - flags |= PSEXP_PSARGS; - if (g_flags & F_EXACT_MATCH) flags |= PSEXP_EXACT; @@ -302,12 +338,17 @@ scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, if ((procfd = open(procpath, O_RDONLY)) == -1) continue; - if ((read(procfd, &ps, sizeof (ps)) == sizeof (psinfo_t)) && - (ps.pr_nlwp != 0) && (ps.pr_pid != g_pid) && - (psexp_match(psexp, &ps, flags) ^ reverse)) { + if (read(procfd, &ps, sizeof (ps)) != sizeof (psinfo_t)) { + (void) close(procfd); + continue; + } + + get_argv(g_flags, &ps, argv, sizeof (argv)); + + if ((ps.pr_nlwp != 0) && (ps.pr_pid != g_pid) && + (psexp_match(psexp, &ps, argv, flags) ^ reverse)) { if (g_flags & F_NEWEST) { - /* LINTED - opsinfo use ok */ if (!ovalid || NEWER(ps, ops)) { (void) memcpy(&ops, &ps, sizeof (psinfo_t)); @@ -320,7 +361,7 @@ scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, ovalid = 1; } } else { - (*funcp)(&ps); + (*funcp)(&ps, argv, sizeof (argv)); nmatches++; } } @@ -329,7 +370,8 @@ scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp, } if ((g_flags & (F_NEWEST | F_OLDEST)) && ovalid) { - (*funcp)(&ops); + (*funcp)(&ops, argv, sizeof (argv)); + nmatches++; } @@ -592,11 +634,13 @@ print_usage(FILE *stream) int main(int argc, char *argv[]) { - void (*funcp)(psinfo_t *); + void (*funcp)(psinfo_t *, char *, size_t); const char *optstr; optdesc_t *optd; int nmatches, c; + const char *zroot; + char buf[PATH_MAX]; DIR *dirp; @@ -626,6 +670,12 @@ main(int argc, char *argv[]) opterr = 0; + zroot = zone_get_nroot(); + if (zroot != NULL) { + (void) snprintf(buf, sizeof (buf), "%s/%s", zroot, g_procdir); + g_procdir = buf; + } + while (optind < argc) { while ((c = getopt(argc, argv, optstr)) != (int)EOF) { |