Deleted Added
full compact
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 ---