ps.c (90110) | ps.c (90143) |
---|---|
1/*- 2 * Copyright (c) 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 | 1/*- 2 * Copyright (c) 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 |
34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: head/bin/ps/ps.c 90143 2002-02-03 14:43:04Z markm $"); 36 |
|
34#ifndef lint | 37#ifndef lint |
35static char const copyright[] = | 38static const char copyright[] = |
36"@(#) Copyright (c) 1990, 1993, 1994\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 | 39"@(#) Copyright (c) 1990, 1993, 1994\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 |
40#ifndef lint | |
41#if 0 | 43#if 0 |
44#ifndef lint |
|
42static char sccsid[] = "@(#)ps.c 8.4 (Berkeley) 4/2/94"; | 45static char sccsid[] = "@(#)ps.c 8.4 (Berkeley) 4/2/94"; |
43#endif 44static const char rcsid[] = 45 "$FreeBSD: head/bin/ps/ps.c 90110 2002-02-02 06:48:10Z imp $"; | |
46#endif /* not lint */ | 46#endif /* not lint */ |
47#endif |
|
47 48#include <sys/param.h> 49#include <sys/user.h> | 48 49#include <sys/param.h> 50#include <sys/user.h> |
50#include <sys/time.h> 51#include <sys/resource.h> | |
52#include <sys/stat.h> 53#include <sys/ioctl.h> 54#include <sys/sysctl.h> 55 56#include <ctype.h> 57#include <err.h> | 51#include <sys/stat.h> 52#include <sys/ioctl.h> 53#include <sys/sysctl.h> 54 55#include <ctype.h> 56#include <err.h> |
58#include <errno.h> | |
59#include <fcntl.h> 60#include <kvm.h> 61#include <limits.h> 62#include <locale.h> | 57#include <fcntl.h> 58#include <kvm.h> 59#include <limits.h> 60#include <locale.h> |
63#include <nlist.h> | |
64#include <paths.h> | 61#include <paths.h> |
62#include <pwd.h> |
|
65#include <stdio.h> 66#include <stdlib.h> 67#include <string.h> 68#include <unistd.h> | 63#include <stdio.h> 64#include <stdlib.h> 65#include <string.h> 66#include <unistd.h> |
69#include <pwd.h> | |
70#include <utmp.h> 71 72#include "lomac.h" 73#include "ps.h" 74 75#define SEP ", \t" /* username separators */ 76 | 67#include <utmp.h> 68 69#include "lomac.h" 70#include "ps.h" 71 72#define SEP ", \t" /* username separators */ 73 |
77KINFO *kinfo; 78struct varent *vhead, *vtail; | 74static KINFO *kinfo; 75struct varent *vhead; |
79 80int eval; /* exit value */ 81int cflag; /* -c */ 82int rawcpu; /* -C */ 83int sumrusage; /* -S */ 84int termwidth; /* width of screen (0 == infinity) */ 85int totwidth; /* calculated width of requested variables */ 86 87static int needuser, needcomm, needenv; 88#if defined(LAZY_PS) 89static int forceuread=0; 90#else 91static int forceuread=1; 92#endif 93 | 76 77int eval; /* exit value */ 78int cflag; /* -c */ 79int rawcpu; /* -C */ 80int sumrusage; /* -S */ 81int termwidth; /* width of screen (0 == infinity) */ 82int totwidth; /* calculated width of requested variables */ 83 84static int needuser, needcomm, needenv; 85#if defined(LAZY_PS) 86static int forceuread=0; 87#else 88static int forceuread=1; 89#endif 90 |
94enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT; | 91static enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT; |
95 | 92 |
96static char *fmt(char **(*)(kvm_t *, const struct kinfo_proc *, int), | 93static const char *fmt(char **(*)(kvm_t *, const struct kinfo_proc *, int), |
97 KINFO *, char *, int); 98static char *kludge_oldps_options(char *); 99static int pscomp(const void *, const void *); 100static void saveuser(KINFO *); 101static void scanvars(void); 102static void dynsizevars(KINFO *); 103static void sizevars(void); 104static void usage(void); 105static uid_t *getuids(const char *, int *); 106 | 94 KINFO *, char *, int); 95static char *kludge_oldps_options(char *); 96static int pscomp(const void *, const void *); 97static void saveuser(KINFO *); 98static void scanvars(void); 99static void dynsizevars(KINFO *); 100static void sizevars(void); 101static void usage(void); 102static uid_t *getuids(const char *, int *); 103 |
107char dfmt[] = "pid tt state time command"; 108char jfmt[] = "user pid ppid pgid jobc state tt time command"; 109char lfmt[] = "uid pid ppid cpu pri nice vsz rss wchan state tt time command"; 110char o1[] = "pid"; 111char o2[] = "tt state time command"; 112char ufmt[] = "user pid %cpu %mem vsz rss tt state start time command"; 113char vfmt[] = "pid state time sl re pagein vsz rss lim tsiz %cpu %mem command"; 114char Zfmt[] = "lvl"; | 104static char dfmt[] = "pid tt state time command"; 105static char jfmt[] = "user pid ppid pgid jobc state tt time command"; 106static char lfmt[] = "uid pid ppid cpu pri nice vsz rss wchan state tt time command"; 107static char o1[] = "pid"; 108static char o2[] = "tt state time command"; 109static char ufmt[] = "user pid %cpu %mem vsz rss tt state start time command"; 110static char vfmt[] = "pid state time sl re pagein vsz rss lim tsiz %cpu %mem command"; 111static char Zfmt[] = "lvl"; |
115 | 112 |
116kvm_t *kd; | 113static kvm_t *kd; |
117 118int 119main(int argc, char *argv[]) 120{ 121 struct kinfo_proc *kp; 122 struct varent *vent; 123 struct winsize ws; 124 dev_t ttydev; 125 pid_t pid; 126 uid_t *uids; | 114 115int 116main(int argc, char *argv[]) 117{ 118 struct kinfo_proc *kp; 119 struct varent *vent; 120 struct winsize ws; 121 dev_t ttydev; 122 pid_t pid; 123 uid_t *uids; |
127 int all, ch, flag, i, fmt, lineno, nentries, dropgid; | 124 int all, ch, flag, i, _fmt, lineno, nentries, dropgid; |
128 int prtheader, wflag, what, xflg, uid, nuids; | 125 int prtheader, wflag, what, xflg, uid, nuids; |
129 char *nlistf, *memf, errbuf[_POSIX2_LINE_MAX]; | 126 char errbuf[_POSIX2_LINE_MAX]; 127 const char *nlistf, *memf; |
130 131 (void) setlocale(LC_ALL, ""); 132 133 if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 && 134 ioctl(STDERR_FILENO, TIOCGWINSZ, (char *)&ws) == -1 && 135 ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&ws) == -1) || 136 ws.ws_col == 0) 137 termwidth = 79; 138 else 139 termwidth = ws.ws_col - 1; 140 141 if (argc > 1) 142 argv[1] = kludge_oldps_options(argv[1]); 143 | 128 129 (void) setlocale(LC_ALL, ""); 130 131 if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 && 132 ioctl(STDERR_FILENO, TIOCGWINSZ, (char *)&ws) == -1 && 133 ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&ws) == -1) || 134 ws.ws_col == 0) 135 termwidth = 79; 136 else 137 termwidth = ws.ws_col - 1; 138 139 if (argc > 1) 140 argv[1] = kludge_oldps_options(argv[1]); 141 |
144 all = fmt = prtheader = wflag = xflg = 0; | 142 all = _fmt = prtheader = wflag = xflg = 0; |
145 pid = -1; 146 nuids = 0; 147 uids = NULL; 148 ttydev = NODEV; 149 dropgid = 0; 150 memf = nlistf = _PATH_DEVNULL; 151 while ((ch = getopt(argc, argv, 152#if defined(LAZY_PS) --- 16 unchanged lines hidden (view full) --- 169 break; 170 case 'g': 171 break; /* no-op */ 172 case 'h': 173 prtheader = ws.ws_row > 5 ? ws.ws_row : 22; 174 break; 175 case 'j': 176 parsefmt(jfmt); | 143 pid = -1; 144 nuids = 0; 145 uids = NULL; 146 ttydev = NODEV; 147 dropgid = 0; 148 memf = nlistf = _PATH_DEVNULL; 149 while ((ch = getopt(argc, argv, 150#if defined(LAZY_PS) --- 16 unchanged lines hidden (view full) --- 167 break; 168 case 'g': 169 break; /* no-op */ 170 case 'h': 171 prtheader = ws.ws_row > 5 ? ws.ws_row : 22; 172 break; 173 case 'j': 174 parsefmt(jfmt); |
177 fmt = 1; | 175 _fmt = 1; |
178 jfmt[0] = '\0'; 179 break; 180 case 'L': 181 showkey(); 182 exit(0); 183 case 'l': 184 parsefmt(lfmt); | 176 jfmt[0] = '\0'; 177 break; 178 case 'L': 179 showkey(); 180 exit(0); 181 case 'l': 182 parsefmt(lfmt); |
185 fmt = 1; | 183 _fmt = 1; |
186 lfmt[0] = '\0'; 187 break; 188 case 'M': 189 memf = optarg; 190 dropgid = 1; 191 break; 192 case 'm': 193 sortby = SORTMEM; 194 break; 195 case 'N': 196 nlistf = optarg; 197 dropgid = 1; 198 break; 199 case 'O': 200 parsefmt(o1); 201 parsefmt(optarg); 202 parsefmt(o2); 203 o1[0] = o2[0] = '\0'; | 184 lfmt[0] = '\0'; 185 break; 186 case 'M': 187 memf = optarg; 188 dropgid = 1; 189 break; 190 case 'm': 191 sortby = SORTMEM; 192 break; 193 case 'N': 194 nlistf = optarg; 195 dropgid = 1; 196 break; 197 case 'O': 198 parsefmt(o1); 199 parsefmt(optarg); 200 parsefmt(o2); 201 o1[0] = o2[0] = '\0'; |
204 fmt = 1; | 202 _fmt = 1; |
205 break; 206 case 'o': 207 parsefmt(optarg); | 203 break; 204 case 'o': 205 parsefmt(optarg); |
208 fmt = 1; | 206 _fmt = 1; |
209 break; 210#if defined(LAZY_PS) 211 case 'f': 212 if (getuid() == 0 || getgid() == 0) 213 forceuread = 1; 214 break; 215#endif 216 case 'p': --- 10 unchanged lines hidden (view full) --- 227 if ((optarg = ttyname(STDIN_FILENO)) == NULL) 228 errx(1, "stdin: not a terminal"); 229 /* FALLTHROUGH */ 230 case 't': { 231 struct stat sb; 232 char *ttypath, pathbuf[PATH_MAX]; 233 234 if (strcmp(optarg, "co") == 0) | 207 break; 208#if defined(LAZY_PS) 209 case 'f': 210 if (getuid() == 0 || getgid() == 0) 211 forceuread = 1; 212 break; 213#endif 214 case 'p': --- 10 unchanged lines hidden (view full) --- 225 if ((optarg = ttyname(STDIN_FILENO)) == NULL) 226 errx(1, "stdin: not a terminal"); 227 /* FALLTHROUGH */ 228 case 't': { 229 struct stat sb; 230 char *ttypath, pathbuf[PATH_MAX]; 231 232 if (strcmp(optarg, "co") == 0) |
235 ttypath = _PATH_CONSOLE; | 233 ttypath = strdup(_PATH_CONSOLE); |
236 else if (*optarg != '/') 237 (void)snprintf(ttypath = pathbuf, 238 sizeof(pathbuf), "%s%s", _PATH_TTY, optarg); 239 else 240 ttypath = optarg; 241 if (stat(ttypath, &sb) == -1) 242 err(1, "%s", ttypath); 243 if (!S_ISCHR(sb.st_mode)) 244 errx(1, "%s: not a terminal", ttypath); 245 ttydev = sb.st_rdev; 246 break; 247 } 248 case 'U': 249 uids = getuids(optarg, &nuids); 250 xflg++; /* XXX: intuitive? */ 251 break; 252 case 'u': 253 parsefmt(ufmt); 254 sortby = SORTCPU; | 234 else if (*optarg != '/') 235 (void)snprintf(ttypath = pathbuf, 236 sizeof(pathbuf), "%s%s", _PATH_TTY, optarg); 237 else 238 ttypath = optarg; 239 if (stat(ttypath, &sb) == -1) 240 err(1, "%s", ttypath); 241 if (!S_ISCHR(sb.st_mode)) 242 errx(1, "%s: not a terminal", ttypath); 243 ttydev = sb.st_rdev; 244 break; 245 } 246 case 'U': 247 uids = getuids(optarg, &nuids); 248 xflg++; /* XXX: intuitive? */ 249 break; 250 case 'u': 251 parsefmt(ufmt); 252 sortby = SORTCPU; |
255 fmt = 1; | 253 _fmt = 1; |
256 ufmt[0] = '\0'; 257 break; 258 case 'v': 259 parsefmt(vfmt); 260 sortby = SORTMEM; | 254 ufmt[0] = '\0'; 255 break; 256 case 'v': 257 parsefmt(vfmt); 258 sortby = SORTMEM; |
261 fmt = 1; | 259 _fmt = 1; |
262 vfmt[0] = '\0'; 263 break; 264 case 'w': 265 if (wflag) 266 termwidth = UNLIMITED; 267 else if (termwidth < 131) 268 termwidth = 131; 269 wflag++; --- 29 unchanged lines hidden (view full) --- 299 setgid(getgid()); 300 setuid(getuid()); 301 } 302 303 kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 304 if (kd == 0) 305 errx(1, "%s", errbuf); 306 | 260 vfmt[0] = '\0'; 261 break; 262 case 'w': 263 if (wflag) 264 termwidth = UNLIMITED; 265 else if (termwidth < 131) 266 termwidth = 131; 267 wflag++; --- 29 unchanged lines hidden (view full) --- 297 setgid(getgid()); 298 setuid(getuid()); 299 } 300 301 kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 302 if (kd == 0) 303 errx(1, "%s", errbuf); 304 |
307 if (!fmt) | 305 if (!_fmt) |
308 parsefmt(dfmt); 309 310 /* XXX - should be cleaner */ 311 if (!all && ttydev == NODEV && pid == -1 && !nuids) { 312 if ((uids = malloc(sizeof (*uids))) == NULL) 313 errx(1, "malloc: %s", strerror(errno)); 314 nuids = 1; 315 *uids = getuid(); --- 79 unchanged lines hidden (view full) --- 395} 396 397uid_t * 398getuids(const char *arg, int *nuids) 399{ 400 char name[UT_NAMESIZE + 1]; 401 struct passwd *pwd; 402 uid_t *uids, *moreuids; | 306 parsefmt(dfmt); 307 308 /* XXX - should be cleaner */ 309 if (!all && ttydev == NODEV && pid == -1 && !nuids) { 310 if ((uids = malloc(sizeof (*uids))) == NULL) 311 errx(1, "malloc: %s", strerror(errno)); 312 nuids = 1; 313 *uids = getuid(); --- 79 unchanged lines hidden (view full) --- 393} 394 395uid_t * 396getuids(const char *arg, int *nuids) 397{ 398 char name[UT_NAMESIZE + 1]; 399 struct passwd *pwd; 400 uid_t *uids, *moreuids; |
403 int l, alloc; | 401 int alloc; 402 size_t l; |
404 405 406 alloc = 0; 407 *nuids = 0; 408 uids = NULL; 409 for (; (l = strcspn(arg, SEP)) > 0; arg += l + strspn(arg + l, SEP)) { 410 if (l >= sizeof name) { | 403 404 405 alloc = 0; 406 *nuids = 0; 407 uids = NULL; 408 for (; (l = strcspn(arg, SEP)) > 0; arg += l + strspn(arg + l, SEP)) { 409 if (l >= sizeof name) { |
411 warnx("%.*s: name too long", l, arg); | 410 warnx("%.*s: name too long", (int)l, arg); |
412 continue; 413 } 414 strncpy(name, arg, l); 415 name[l] = '\0'; 416 if ((pwd = getpwnam(name)) == NULL) { 417 warnx("%s: no such user", name); 418 continue; 419 } --- 66 unchanged lines hidden (view full) --- 486 i = strlen(v->header); 487 if (v->width < i) 488 v->width = i; 489 totwidth += v->width + 1; /* +1 for space */ 490 } 491 totwidth--; 492} 493 | 411 continue; 412 } 413 strncpy(name, arg, l); 414 name[l] = '\0'; 415 if ((pwd = getpwnam(name)) == NULL) { 416 warnx("%s: no such user", name); 417 continue; 418 } --- 66 unchanged lines hidden (view full) --- 485 i = strlen(v->header); 486 if (v->width < i) 487 v->width = i; 488 totwidth += v->width + 1; /* +1 for space */ 489 } 490 totwidth--; 491} 492 |
494static char * | 493static const char * |
495fmt(char **(*fn)(kvm_t *, const struct kinfo_proc *, int), KINFO *ki, 496 char *comm, int maxlen) 497{ | 494fmt(char **(*fn)(kvm_t *, const struct kinfo_proc *, int), KINFO *ki, 495 char *comm, int maxlen) 496{ |
498 char *s; | 497 const char *s; |
499 | 498 |
500 if ((s = 501 fmt_argv((*fn)(kd, ki->ki_p, termwidth), comm, maxlen)) == NULL) | 499 s = fmt_argv((*fn)(kd, ki->ki_p, termwidth), comm, maxlen); 500 if (s == NULL) |
502 err(1, NULL); 503 return (s); 504} 505 506#define UREADOK(ki) (forceuread || (ki->ki_p->ki_sflag & PS_INMEM)) 507 508static void 509saveuser(KINFO *ki) --- 8 unchanged lines hidden (view full) --- 518 */ 519 ki->ki_valid = 1; 520 } else 521 ki->ki_valid = 0; 522 /* 523 * save arguments if needed 524 */ 525 if (needcomm && (UREADOK(ki) || (ki->ki_p->ki_args != NULL))) { | 501 err(1, NULL); 502 return (s); 503} 504 505#define UREADOK(ki) (forceuread || (ki->ki_p->ki_sflag & PS_INMEM)) 506 507static void 508saveuser(KINFO *ki) --- 8 unchanged lines hidden (view full) --- 517 */ 518 ki->ki_valid = 1; 519 } else 520 ki->ki_valid = 0; 521 /* 522 * save arguments if needed 523 */ 524 if (needcomm && (UREADOK(ki) || (ki->ki_p->ki_args != NULL))) { |
526 ki->ki_args = fmt(kvm_getargv, ki, ki->ki_p->ki_comm, 527 MAXCOMLEN); | 525 ki->ki_args = strdup(fmt(kvm_getargv, ki, ki->ki_p->ki_comm, 526 MAXCOMLEN)); |
528 } else if (needcomm) { | 527 } else if (needcomm) { |
529 ki->ki_args = malloc(strlen(ki->ki_p->ki_comm) + 3); 530 sprintf(ki->ki_args, "(%s)", ki->ki_p->ki_comm); | 528 asprintf(&ki->ki_args, "(%s)", ki->ki_p->ki_comm); |
531 } else { 532 ki->ki_args = NULL; 533 } 534 if (needenv && UREADOK(ki)) { | 529 } else { 530 ki->ki_args = NULL; 531 } 532 if (needenv && UREADOK(ki)) { |
535 ki->ki_env = fmt(kvm_getenvv, ki, (char *)NULL, 0); | 533 ki->ki_env = strdup(fmt(kvm_getenvv, ki, (char *)NULL, 0)); |
536 } else if (needenv) { 537 ki->ki_env = malloc(3); 538 strcpy(ki->ki_env, "()"); 539 } else { 540 ki->ki_env = NULL; 541 } 542} 543 544static int 545pscomp(const void *a, const void *b) 546{ 547 int i; 548#define VSIZE(k) ((k)->ki_p->ki_dsize + (k)->ki_p->ki_ssize + \ 549 (k)->ki_p->ki_tsize) 550 551 if (sortby == SORTCPU) | 534 } else if (needenv) { 535 ki->ki_env = malloc(3); 536 strcpy(ki->ki_env, "()"); 537 } else { 538 ki->ki_env = NULL; 539 } 540} 541 542static int 543pscomp(const void *a, const void *b) 544{ 545 int i; 546#define VSIZE(k) ((k)->ki_p->ki_dsize + (k)->ki_p->ki_ssize + \ 547 (k)->ki_p->ki_tsize) 548 549 if (sortby == SORTCPU) |
552 return (getpcpu((KINFO *)b) - getpcpu((KINFO *)a)); | 550 return (getpcpu((const KINFO *)b) - getpcpu((const KINFO *)a)); |
553 if (sortby == SORTMEM) | 551 if (sortby == SORTMEM) |
554 return (VSIZE((KINFO *)b) - VSIZE((KINFO *)a)); 555 i = ((KINFO *)a)->ki_p->ki_tdev - ((KINFO *)b)->ki_p->ki_tdev; | 552 return (VSIZE((const KINFO *)b) - VSIZE((const KINFO *)a)); 553 i = (int)((const KINFO *)a)->ki_p->ki_tdev - (int)((const KINFO *)b)->ki_p->ki_tdev; |
556 if (i == 0) | 554 if (i == 0) |
557 i = ((KINFO *)a)->ki_p->ki_pid - ((KINFO *)b)->ki_p->ki_pid; | 555 i = ((const KINFO *)a)->ki_p->ki_pid - ((const KINFO *)b)->ki_p->ki_pid; |
558 return (i); 559} 560 561/* 562 * ICK (all for getopt), would rather hide the ugliness 563 * here than taint the main code. 564 * 565 * ps foo -> ps -foo --- 69 unchanged lines hidden --- | 556 return (i); 557} 558 559/* 560 * ICK (all for getopt), would rather hide the ugliness 561 * here than taint the main code. 562 * 563 * ps foo -> ps -foo --- 69 unchanged lines hidden --- |