3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
29 */
30
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
33
34 /*
35 * ps -- print things about processes.
36 */
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <pwd.h>
59 #include <libw.h>
60 #include <stdarg.h>
61 #include <sys/proc.h>
62 #include <sys/pset.h>
63 #include <project.h>
64 #include <zone.h>
65
66 #define min(a, b) ((a) > (b) ? (b) : (a))
67 #define max(a, b) ((a) < (b) ? (b) : (a))
68
69 #define NTTYS 20 /* initial size of table for -t option */
70 #define SIZ 30 /* initial size of tables for -p, -s, -g, -h and -z */
71
72 /*
73 * Size of buffer holding args for t, p, s, g, u, U, G, z options.
74 * Set to ZONENAME_MAX, the minimum value needed to allow any
75 * zone to be specified.
76 */
77 #define ARGSIZ ZONENAME_MAX
78
79 #define MAXUGNAME 10 /* max chars in a user/group name or printed u/g id */
80
81 /* Structure for storing user or group info */
82 struct ugdata {
83 id_t id; /* numeric user-id or group-id */
84 char name[MAXUGNAME+1]; /* user/group name, null terminated */
85 };
86
87 struct ughead {
88 size_t size; /* number of ugdata structs allocated */
89 size_t nent; /* number of active entries */
90 struct ugdata *ent; /* pointer to array of actual entries */
91 };
92
93 enum fname { /* enumeration of field names */
94 F_USER, /* effective user of the process */
95 F_RUSER, /* real user of the process */
96 F_GROUP, /* effective group of the process */
97 F_RGROUP, /* real group of the process */
98 F_UID, /* numeric effective uid of the process */
99 F_RUID, /* numeric real uid of the process */
207 { "pset", "PSET", 3, 3 },
208 { "zone", "ZONE", 8, 8 },
209 { "zoneid", "ZONEID", 5, 5 },
210 { "ctid", "CTID", 5, 5 },
211 { "lgrp", "LGRP", 4, 2 },
212 { "dmodel", "DMODEL", 6, 6 },
213 };
214
215 #define NFIELDS (sizeof (fname) / sizeof (fname[0]))
216
217 static int retcode = 1;
218 static int lflg;
219 static int Aflg;
220 static int uflg;
221 static int Uflg;
222 static int Gflg;
223 static int aflg;
224 static int dflg;
225 static int Lflg;
226 static int Pflg;
227 static int yflg;
228 static int pflg;
229 static int fflg;
230 static int cflg;
231 static int jflg;
232 static int gflg;
233 static int sflg;
234 static int tflg;
235 static int zflg;
236 static int Zflg;
237 static int hflg;
238 static int Hflg;
239 static uid_t tuid = (uid_t)-1;
240 static int errflg;
241
242 static int ndev; /* number of devices */
243 static int maxdev; /* number of devl structures allocated */
244
245 #define DNINCR 100
246 #define DNSIZE 14
407 pidwidth = 1;
408 while ((id /= 10) > 0)
409 ++pidwidth;
410 pidwidth = pidwidth < 5 ? 5 : pidwidth;
411
412 fname[F_PID].width = fname[F_PPID].width = pidwidth;
413 fname[F_PGID].width = fname[F_SID].width = pidwidth;
414
415 /*
416 * TRANSLATION_NOTE
417 * Specify the printf format with width and precision for
418 * the STIME field.
419 */
420 len = snprintf(loc_stime_str, sizeof (loc_stime_str),
421 dcgettext(NULL, "%8.8s", LC_TIME), "STIME");
422 if (len >= sizeof (loc_stime_str))
423 len = sizeof (loc_stime_str) - 1;
424
425 fname[F_STIME].width = fname[F_STIME].minwidth = len;
426
427 while ((c = getopt(argc, argv, "jlfceAadLPyZHh:t:p:g:u:U:G:n:s:o:z:"))
428 != EOF)
429 switch (c) {
430 case 'H': /* Show home lgroups */
431 Hflg++;
432 break;
433 case 'h':
434 /*
435 * Show processes/threads with given home lgroups
436 */
437 hflg++;
438 p1 = optarg;
439 do {
440 int id;
441
442 /*
443 * Get all IDs in the list, verify for
444 * correctness and place in lgrps array.
445 */
446 parg = getarg(&p1);
447 /* Convert string to integer */
501 Aflg++;
502 tflg = Gflg = Uflg = uflg = pflg = gflg = sflg = 0;
503 zflg = hflg = 0;
504 break;
505 case 'a':
506 /*
507 * Same as 'e' except no session group leaders
508 * and no non-terminal processes.
509 */
510 aflg++;
511 break;
512 case 'd': /* same as e except no session leaders */
513 dflg++;
514 break;
515 case 'L': /* show lwps */
516 Lflg++;
517 break;
518 case 'P': /* show bound processor */
519 Pflg++;
520 break;
521 case 'y': /* omit F & ADDR, report RSS & SZ in Kby */
522 yflg++;
523 break;
524 case 'n': /* no longer needed; retain as no-op */
525 (void) fprintf(stderr,
526 gettext("ps: warning: -n option ignored\n"));
527 break;
528 case 't': /* terminals */
529 #define TSZ 30
530 tflg++;
531 p1 = optarg;
532 do {
533 char nambuf[TSZ+6]; /* for "/dev/" + '\0' */
534 struct stat64 s;
535 parg = getarg(&p1);
536 p = Realloc(NULL, TSZ+1); /* for '\0' */
537 /* zero the buffer before using it */
538 p[0] = '\0';
539 size = TSZ;
540 if (isdigit(*parg)) {
1040 }
1041 return (0);
1042 }
1043
1044 static int
1045 field_cmp(const void *l, const void *r)
1046 {
1047 struct def_field *lhs = *((struct def_field **)l);
1048 struct def_field *rhs = *((struct def_field **)r);
1049
1050 return (strcmp(lhs->fname, rhs->fname));
1051 }
1052
1053 static void
1054 usage(void) /* print usage message and quit */
1055 {
1056 struct def_field *df, *sorted[NFIELDS];
1057 int pos = 80, i = 0;
1058
1059 static char usage1[] =
1060 "ps [ -aAdefHlcjLPyZ ] [ -o format ] [ -t termlist ]";
1061 static char usage2[] =
1062 "\t[ -u userlist ] [ -U userlist ] [ -G grouplist ]";
1063 static char usage3[] =
1064 "\t[ -p proclist ] [ -g pgrplist ] [ -s sidlist ]";
1065 static char usage4[] =
1066 "\t[ -z zonelist ] [-h lgrplist]";
1067 static char usage5[] =
1068 " 'format' is one or more of:";
1069
1070 (void) fprintf(stderr,
1071 gettext("usage: %s\n%s\n%s\n%s\n%s"),
1072 gettext(usage1), gettext(usage2), gettext(usage3),
1073 gettext(usage4), gettext(usage5));
1074
1075 /*
1076 * Now print out the possible output formats such that they neatly fit
1077 * into eighty columns. Note that the fact that we are determining
1078 * this output programmatically means that a gettext() is impossible --
1079 * but it would be a mistake to localize the output formats anyway as
1080 * they are tokens for input, not output themselves.
1378 */
1379 if (fields != NULL) {
1380 pr_fields(psinfo, ttyp, print_field);
1381 return;
1382 }
1383
1384 /*
1385 * All fields before 'PID' are printed with a trailing space as a
1386 * separator, rather than keeping track of which column is first. All
1387 * other fields are printed with a leading space.
1388 */
1389 if (lflg) {
1390 if (!yflg)
1391 (void) printf("%2x ", psinfo->pr_flag & 0377); /* F */
1392 (void) printf("%c ", psinfo->pr_lwp.pr_sname); /* S */
1393 }
1394
1395 if (Zflg) { /* ZONE */
1396 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
1397 sizeof (zonename)) < 0) {
1398 (void) printf(" %7.7d ", ((int)psinfo->pr_zoneid));
1399 } else {
1400 (void) printf("%8.8s ", zonename);
1401 }
1402 }
1403
1404 if (fflg) { /* UID */
1405 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL)
1406 (void) printf("%8.8s ", pwd->pw_name);
1407 else
1408 (void) printf(" %7.7u ", psinfo->pr_euid);
1409 } else if (lflg) {
1410 (void) printf("%6u ", psinfo->pr_euid);
1411 }
1412 (void) printf("%*d", pidwidth, (int)psinfo->pr_pid); /* PID */
1413 if (lflg || fflg)
1414 (void) printf(" %*d", pidwidth,
1415 (int)psinfo->pr_ppid); /* PPID */
1416 if (jflg) {
1417 (void) printf(" %*d", pidwidth,
1418 (int)psinfo->pr_pgid); /* PGID */
1419 (void) printf(" %*d", pidwidth,
1420 (int)psinfo->pr_sid); /* SID */
1421 }
1422 if (Lflg)
1423 (void) printf(" %5d", (int)psinfo->pr_lwp.pr_lwpid); /* LWP */
1424 if (Pflg) {
1425 if (psinfo->pr_lwp.pr_bindpro == PBIND_NONE) /* PSR */
1426 (void) printf(" -");
1427 else
1428 (void) printf(" %3d", psinfo->pr_lwp.pr_bindpro);
1429 }
1611 static void
1612 print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
1613 {
1614 int width = f->width;
1615 struct passwd *pwd;
1616 struct group *grp;
1617 time_t cputime;
1618 int bytesleft;
1619 int wcnt;
1620 wchar_t wchar;
1621 char *cp;
1622 int length;
1623 ulong_t mask;
1624 char c, *csave;
1625 int zombie_lwp;
1626
1627 zombie_lwp = (Lflg && psinfo->pr_lwp.pr_sname == 'Z');
1628
1629 switch (f->fname) {
1630 case F_RUSER:
1631 if ((pwd = getpwuid(psinfo->pr_uid)) != NULL)
1632 (void) printf("%*s", width, pwd->pw_name);
1633 else
1634 (void) printf("%*u", width, psinfo->pr_uid);
1635 break;
1636 case F_USER:
1637 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL)
1638 (void) printf("%*s", width, pwd->pw_name);
1639 else
1640 (void) printf("%*u", width, psinfo->pr_euid);
1641 break;
1642 case F_RGROUP:
1643 if ((grp = getgrgid(psinfo->pr_gid)) != NULL)
1644 (void) printf("%*s", width, grp->gr_name);
1645 else
1646 (void) printf("%*u", width, psinfo->pr_gid);
1647 break;
1648 case F_GROUP:
1649 if ((grp = getgrgid(psinfo->pr_egid)) != NULL)
1650 (void) printf("%*s", width, grp->gr_name);
1651 else
1652 (void) printf("%*u", width, psinfo->pr_egid);
1653 break;
1654 case F_RUID:
1655 (void) printf("%*u", width, psinfo->pr_uid);
1656 break;
1657 case F_UID:
1658 (void) printf("%*u", width, psinfo->pr_euid);
1659 break;
1660 case F_RGID:
1862 (void) printf("%-*.*s", width, wcnt,
1863 psinfo->pr_psargs);
1864 else
1865 (void) printf("%-.*s", wcnt,
1866 psinfo->pr_psargs);
1867 if (f->fname == F_COMM && csave)
1868 *csave = c;
1869 break;
1870 case F_TASKID:
1871 (void) printf("%*d", width, (int)psinfo->pr_taskid);
1872 break;
1873 case F_PROJID:
1874 (void) printf("%*d", width, (int)psinfo->pr_projid);
1875 break;
1876 case F_PROJECT:
1877 {
1878 struct project cproj;
1879 char proj_buf[PROJECT_BUFSZ];
1880
1881 if ((getprojbyid(psinfo->pr_projid, &cproj,
1882 (void *)&proj_buf, PROJECT_BUFSZ)) == NULL)
1883 (void) printf("%*d", width,
1884 (int)psinfo->pr_projid);
1885 else
1886 (void) printf("%*s", width,
1887 (cproj.pj_name != NULL) ?
1888 cproj.pj_name : "---");
1889 }
1890 break;
1891 case F_PSET:
1892 if (zombie_lwp || psinfo->pr_lwp.pr_bindpset == PS_NONE)
1893 (void) printf("%*s", width, "-");
1894 else
1895 (void) printf("%*d", width, psinfo->pr_lwp.pr_bindpset);
1896 break;
1897 case F_ZONEID:
1898 (void) printf("%*d", width, (int)psinfo->pr_zoneid);
1899 break;
1900 case F_ZONE:
1901 {
1902 char zonename[ZONENAME_MAX];
1903
1904 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
1905 sizeof (zonename)) < 0) {
1906 (void) printf("%*d", width,
1907 ((int)psinfo->pr_zoneid));
1908 } else {
1909 (void) printf("%*s", width, zonename);
1910 }
1911 }
1912 break;
1913 case F_CTID:
1914 if (psinfo->pr_contract == -1)
1915 (void) printf("%*s", width, "-");
1916 else
1917 (void) printf("%*ld", width, (long)psinfo->pr_contract);
1918 break;
1919 case F_LGRP:
1920 /* Display home lgroup */
1921 (void) printf("%*d", width, (int)psinfo->pr_lwp.pr_lgrp);
1922 break;
1923
1924 case F_DMODEL:
1925 (void) printf("%*s", width,
1926 psinfo->pr_dmodel == PR_MODEL_LP64 ? "_LP64" : "_ILP32");
1927 break;
1928 }
2164 static void
2165 przom(psinfo_t *psinfo)
2166 {
2167 long tm;
2168 struct passwd *pwd;
2169 char zonename[ZONENAME_MAX];
2170
2171 /*
2172 * All fields before 'PID' are printed with a trailing space as a
2173 * spearator, rather than keeping track of which column is first. All
2174 * other fields are printed with a leading space.
2175 */
2176 if (lflg) { /* F S */
2177 if (!yflg)
2178 (void) printf("%2x ", psinfo->pr_flag & 0377); /* F */
2179 (void) printf("%c ", psinfo->pr_lwp.pr_sname); /* S */
2180 }
2181 if (Zflg) {
2182 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
2183 sizeof (zonename)) < 0) {
2184 (void) printf(" %7.7d ", ((int)psinfo->pr_zoneid));
2185 } else {
2186 (void) printf("%8.8s ", zonename);
2187 }
2188 }
2189 if (Hflg) {
2190 /* Display home lgroup */
2191 (void) printf(" %6d", (int)psinfo->pr_lwp.pr_lgrp); /* LGRP */
2192 }
2193 if (fflg) {
2194 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL)
2195 (void) printf("%8.8s ", pwd->pw_name);
2196 else
2197 (void) printf(" %7.7u ", psinfo->pr_euid);
2198 } else if (lflg)
2199 (void) printf("%6u ", psinfo->pr_euid);
2200
2201 (void) printf("%*d", pidwidth, (int)psinfo->pr_pid); /* PID */
2202 if (lflg || fflg)
2203 (void) printf(" %*d", pidwidth,
2204 (int)psinfo->pr_ppid); /* PPID */
2205
2206 if (jflg) {
2207 (void) printf(" %*d", pidwidth,
2208 (int)psinfo->pr_pgid); /* PGID */
2209 (void) printf(" %*d", pidwidth,
2210 (int)psinfo->pr_sid); /* SID */
2211 }
2212
2213 if (Lflg)
2214 (void) printf(" %5d", 0); /* LWP */
2215 if (Pflg)
2216 (void) printf(" -"); /* PSR */
2217 if (Lflg && fflg)
2218 (void) printf(" %5d", 0); /* NLWP */
2219
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2013 Gary Mills
24 *
25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28
29 /*
30 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
31 */
32
33 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
34 /* All Rights Reserved */
35
36 /*
37 * ps -- print things about processes.
38 */
39 #include <stdio.h>
40 #include <ctype.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <pwd.h>
61 #include <libw.h>
62 #include <stdarg.h>
63 #include <sys/proc.h>
64 #include <sys/pset.h>
65 #include <project.h>
66 #include <zone.h>
67
68 #define min(a, b) ((a) > (b) ? (b) : (a))
69 #define max(a, b) ((a) < (b) ? (b) : (a))
70
71 #define NTTYS 20 /* initial size of table for -t option */
72 #define SIZ 30 /* initial size of tables for -p, -s, -g, -h and -z */
73
74 /*
75 * Size of buffer holding args for t, p, s, g, u, U, G, z options.
76 * Set to ZONENAME_MAX, the minimum value needed to allow any
77 * zone to be specified.
78 */
79 #define ARGSIZ ZONENAME_MAX
80
81 #define MAXUGNAME (LOGNAME_MAX+2) /* max chars in a user/group */
82 /* name or printed u/g id */
83
84 /* Structure for storing user or group info */
85 struct ugdata {
86 id_t id; /* numeric user-id or group-id */
87 char name[MAXUGNAME+1]; /* user/group name, null terminated */
88 };
89
90 struct ughead {
91 size_t size; /* number of ugdata structs allocated */
92 size_t nent; /* number of active entries */
93 struct ugdata *ent; /* pointer to array of actual entries */
94 };
95
96 enum fname { /* enumeration of field names */
97 F_USER, /* effective user of the process */
98 F_RUSER, /* real user of the process */
99 F_GROUP, /* effective group of the process */
100 F_RGROUP, /* real group of the process */
101 F_UID, /* numeric effective uid of the process */
102 F_RUID, /* numeric real uid of the process */
210 { "pset", "PSET", 3, 3 },
211 { "zone", "ZONE", 8, 8 },
212 { "zoneid", "ZONEID", 5, 5 },
213 { "ctid", "CTID", 5, 5 },
214 { "lgrp", "LGRP", 4, 2 },
215 { "dmodel", "DMODEL", 6, 6 },
216 };
217
218 #define NFIELDS (sizeof (fname) / sizeof (fname[0]))
219
220 static int retcode = 1;
221 static int lflg;
222 static int Aflg;
223 static int uflg;
224 static int Uflg;
225 static int Gflg;
226 static int aflg;
227 static int dflg;
228 static int Lflg;
229 static int Pflg;
230 static int Wflg;
231 static int yflg;
232 static int pflg;
233 static int fflg;
234 static int cflg;
235 static int jflg;
236 static int gflg;
237 static int sflg;
238 static int tflg;
239 static int zflg;
240 static int Zflg;
241 static int hflg;
242 static int Hflg;
243 static uid_t tuid = (uid_t)-1;
244 static int errflg;
245
246 static int ndev; /* number of devices */
247 static int maxdev; /* number of devl structures allocated */
248
249 #define DNINCR 100
250 #define DNSIZE 14
411 pidwidth = 1;
412 while ((id /= 10) > 0)
413 ++pidwidth;
414 pidwidth = pidwidth < 5 ? 5 : pidwidth;
415
416 fname[F_PID].width = fname[F_PPID].width = pidwidth;
417 fname[F_PGID].width = fname[F_SID].width = pidwidth;
418
419 /*
420 * TRANSLATION_NOTE
421 * Specify the printf format with width and precision for
422 * the STIME field.
423 */
424 len = snprintf(loc_stime_str, sizeof (loc_stime_str),
425 dcgettext(NULL, "%8.8s", LC_TIME), "STIME");
426 if (len >= sizeof (loc_stime_str))
427 len = sizeof (loc_stime_str) - 1;
428
429 fname[F_STIME].width = fname[F_STIME].minwidth = len;
430
431 while ((c = getopt(argc, argv, "jlfceAadLPWyZHh:t:p:g:u:U:G:n:s:o:z:"))
432 != EOF)
433 switch (c) {
434 case 'H': /* Show home lgroups */
435 Hflg++;
436 break;
437 case 'h':
438 /*
439 * Show processes/threads with given home lgroups
440 */
441 hflg++;
442 p1 = optarg;
443 do {
444 int id;
445
446 /*
447 * Get all IDs in the list, verify for
448 * correctness and place in lgrps array.
449 */
450 parg = getarg(&p1);
451 /* Convert string to integer */
505 Aflg++;
506 tflg = Gflg = Uflg = uflg = pflg = gflg = sflg = 0;
507 zflg = hflg = 0;
508 break;
509 case 'a':
510 /*
511 * Same as 'e' except no session group leaders
512 * and no non-terminal processes.
513 */
514 aflg++;
515 break;
516 case 'd': /* same as e except no session leaders */
517 dflg++;
518 break;
519 case 'L': /* show lwps */
520 Lflg++;
521 break;
522 case 'P': /* show bound processor */
523 Pflg++;
524 break;
525 case 'W': /* truncate long names */
526 Wflg++;
527 break;
528 case 'y': /* omit F & ADDR, report RSS & SZ in Kby */
529 yflg++;
530 break;
531 case 'n': /* no longer needed; retain as no-op */
532 (void) fprintf(stderr,
533 gettext("ps: warning: -n option ignored\n"));
534 break;
535 case 't': /* terminals */
536 #define TSZ 30
537 tflg++;
538 p1 = optarg;
539 do {
540 char nambuf[TSZ+6]; /* for "/dev/" + '\0' */
541 struct stat64 s;
542 parg = getarg(&p1);
543 p = Realloc(NULL, TSZ+1); /* for '\0' */
544 /* zero the buffer before using it */
545 p[0] = '\0';
546 size = TSZ;
547 if (isdigit(*parg)) {
1047 }
1048 return (0);
1049 }
1050
1051 static int
1052 field_cmp(const void *l, const void *r)
1053 {
1054 struct def_field *lhs = *((struct def_field **)l);
1055 struct def_field *rhs = *((struct def_field **)r);
1056
1057 return (strcmp(lhs->fname, rhs->fname));
1058 }
1059
1060 static void
1061 usage(void) /* print usage message and quit */
1062 {
1063 struct def_field *df, *sorted[NFIELDS];
1064 int pos = 80, i = 0;
1065
1066 static char usage1[] =
1067 "ps [ -aAdefHlcjLPWyZ ] [ -o format ] [ -t termlist ]";
1068 static char usage2[] =
1069 "\t[ -u userlist ] [ -U userlist ] [ -G grouplist ]";
1070 static char usage3[] =
1071 "\t[ -p proclist ] [ -g pgrplist ] [ -s sidlist ]";
1072 static char usage4[] =
1073 "\t[ -z zonelist ] [-h lgrplist]";
1074 static char usage5[] =
1075 " 'format' is one or more of:";
1076
1077 (void) fprintf(stderr,
1078 gettext("usage: %s\n%s\n%s\n%s\n%s"),
1079 gettext(usage1), gettext(usage2), gettext(usage3),
1080 gettext(usage4), gettext(usage5));
1081
1082 /*
1083 * Now print out the possible output formats such that they neatly fit
1084 * into eighty columns. Note that the fact that we are determining
1085 * this output programmatically means that a gettext() is impossible --
1086 * but it would be a mistake to localize the output formats anyway as
1087 * they are tokens for input, not output themselves.
1385 */
1386 if (fields != NULL) {
1387 pr_fields(psinfo, ttyp, print_field);
1388 return;
1389 }
1390
1391 /*
1392 * All fields before 'PID' are printed with a trailing space as a
1393 * separator, rather than keeping track of which column is first. All
1394 * other fields are printed with a leading space.
1395 */
1396 if (lflg) {
1397 if (!yflg)
1398 (void) printf("%2x ", psinfo->pr_flag & 0377); /* F */
1399 (void) printf("%c ", psinfo->pr_lwp.pr_sname); /* S */
1400 }
1401
1402 if (Zflg) { /* ZONE */
1403 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
1404 sizeof (zonename)) < 0) {
1405 if (snprintf(NULL, 0, "%d",
1406 ((int)psinfo->pr_zoneid)) > 7)
1407 (void) printf(" %6.6d%c ",
1408 ((int)psinfo->pr_zoneid), '*');
1409 else
1410 (void) printf(" %7.7d ",
1411 ((int)psinfo->pr_zoneid));
1412 } else {
1413 if (strlen(zonename) > 8)
1414 (void) printf("%7.7s%c ", zonename, '*');
1415 else
1416 (void) printf("%8.8s ", zonename);
1417 }
1418 }
1419
1420 if (fflg) { /* UID */
1421 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL) {
1422 if (strlen(pwd->pw_name) > 8)
1423 (void) printf("%7.7s%c ", pwd->pw_name, '*');
1424 else
1425 (void) printf("%8.8s ", pwd->pw_name);
1426 } else {
1427 if (snprintf(NULL, 0, "%u",
1428 ((int)psinfo->pr_euid)) > 7)
1429 (void) printf(" %6.6u%c ", psinfo->pr_euid,
1430 '*');
1431 else
1432 (void) printf(" %7.7u ", psinfo->pr_euid);
1433 }
1434 } else if (lflg) {
1435 if (snprintf(NULL, 0, "%u", ((int)psinfo->pr_euid)) > 6)
1436 (void) printf("%5.5u%c ", psinfo->pr_euid, '*');
1437 else
1438 (void) printf("%6u ", psinfo->pr_euid);
1439 }
1440 (void) printf("%*d", pidwidth, (int)psinfo->pr_pid); /* PID */
1441 if (lflg || fflg)
1442 (void) printf(" %*d", pidwidth,
1443 (int)psinfo->pr_ppid); /* PPID */
1444 if (jflg) {
1445 (void) printf(" %*d", pidwidth,
1446 (int)psinfo->pr_pgid); /* PGID */
1447 (void) printf(" %*d", pidwidth,
1448 (int)psinfo->pr_sid); /* SID */
1449 }
1450 if (Lflg)
1451 (void) printf(" %5d", (int)psinfo->pr_lwp.pr_lwpid); /* LWP */
1452 if (Pflg) {
1453 if (psinfo->pr_lwp.pr_bindpro == PBIND_NONE) /* PSR */
1454 (void) printf(" -");
1455 else
1456 (void) printf(" %3d", psinfo->pr_lwp.pr_bindpro);
1457 }
1639 static void
1640 print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
1641 {
1642 int width = f->width;
1643 struct passwd *pwd;
1644 struct group *grp;
1645 time_t cputime;
1646 int bytesleft;
1647 int wcnt;
1648 wchar_t wchar;
1649 char *cp;
1650 int length;
1651 ulong_t mask;
1652 char c, *csave;
1653 int zombie_lwp;
1654
1655 zombie_lwp = (Lflg && psinfo->pr_lwp.pr_sname == 'Z');
1656
1657 switch (f->fname) {
1658 case F_RUSER:
1659 if ((pwd = getpwuid(psinfo->pr_uid)) != NULL) {
1660 if (Wflg && strlen(pwd->pw_name) > width)
1661 (void) printf("%.*s%c", width - 1,
1662 pwd->pw_name, '*');
1663 else
1664 (void) printf("%*s", width, pwd->pw_name);
1665 } else {
1666 if (Wflg && snprintf(NULL, 0, "%u",
1667 ((int)psinfo->pr_uid)) > width)
1668
1669 (void) printf("%*u%c", width - 1,
1670 psinfo->pr_uid, '*');
1671 else
1672 (void) printf("%*u", width, psinfo->pr_uid);
1673 }
1674 break;
1675 case F_USER:
1676 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL) {
1677 if (Wflg && strlen(pwd->pw_name) > width)
1678 (void) printf("%.*s%c", width - 1,
1679 pwd->pw_name, '*');
1680 else
1681 (void) printf("%*s", width, pwd->pw_name);
1682 } else {
1683 if (Wflg && snprintf(NULL, 0, "%u",
1684 ((int)psinfo->pr_euid)) > width)
1685
1686 (void) printf("%*u%c", width - 1,
1687 psinfo->pr_euid, '*');
1688 else
1689 (void) printf("%*u", width, psinfo->pr_euid);
1690 }
1691 break;
1692 case F_RGROUP:
1693 if ((grp = getgrgid(psinfo->pr_gid)) != NULL)
1694 (void) printf("%*s", width, grp->gr_name);
1695 else
1696 (void) printf("%*u", width, psinfo->pr_gid);
1697 break;
1698 case F_GROUP:
1699 if ((grp = getgrgid(psinfo->pr_egid)) != NULL)
1700 (void) printf("%*s", width, grp->gr_name);
1701 else
1702 (void) printf("%*u", width, psinfo->pr_egid);
1703 break;
1704 case F_RUID:
1705 (void) printf("%*u", width, psinfo->pr_uid);
1706 break;
1707 case F_UID:
1708 (void) printf("%*u", width, psinfo->pr_euid);
1709 break;
1710 case F_RGID:
1912 (void) printf("%-*.*s", width, wcnt,
1913 psinfo->pr_psargs);
1914 else
1915 (void) printf("%-.*s", wcnt,
1916 psinfo->pr_psargs);
1917 if (f->fname == F_COMM && csave)
1918 *csave = c;
1919 break;
1920 case F_TASKID:
1921 (void) printf("%*d", width, (int)psinfo->pr_taskid);
1922 break;
1923 case F_PROJID:
1924 (void) printf("%*d", width, (int)psinfo->pr_projid);
1925 break;
1926 case F_PROJECT:
1927 {
1928 struct project cproj;
1929 char proj_buf[PROJECT_BUFSZ];
1930
1931 if ((getprojbyid(psinfo->pr_projid, &cproj,
1932 (void *)&proj_buf, PROJECT_BUFSZ)) == NULL) {
1933 if (Wflg && snprintf(NULL, 0, "%d",
1934 ((int)psinfo->pr_projid)) > width)
1935 (void) printf("%.*d%c", width - 1,
1936 ((int)psinfo->pr_projid), '*');
1937 else
1938 (void) printf("%*d", width,
1939 (int)psinfo->pr_projid);
1940 } else {
1941 if (Wflg && cproj.pj_name != NULL &&
1942 strlen(cproj.pj_name) > width)
1943 (void) printf("%.*s%c", width - 1,
1944 cproj.pj_name, '*');
1945 else
1946 (void) printf("%*s", width,
1947 (cproj.pj_name != NULL) ?
1948 cproj.pj_name : "---");
1949 }
1950 }
1951 break;
1952 case F_PSET:
1953 if (zombie_lwp || psinfo->pr_lwp.pr_bindpset == PS_NONE)
1954 (void) printf("%*s", width, "-");
1955 else
1956 (void) printf("%*d", width, psinfo->pr_lwp.pr_bindpset);
1957 break;
1958 case F_ZONEID:
1959 (void) printf("%*d", width, (int)psinfo->pr_zoneid);
1960 break;
1961 case F_ZONE:
1962 {
1963 char zonename[ZONENAME_MAX];
1964
1965 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
1966 sizeof (zonename)) < 0) {
1967 if (Wflg && snprintf(NULL, 0, "%d",
1968 ((int)psinfo->pr_zoneid)) > width)
1969 (void) printf("%.*d%c", width - 1,
1970 ((int)psinfo->pr_zoneid), '*');
1971 else
1972 (void) printf("%*d", width,
1973 (int)psinfo->pr_zoneid);
1974 } else {
1975 if (Wflg && strlen(zonename) > width)
1976 (void) printf("%.*s%c", width - 1,
1977 zonename, '*');
1978 else
1979 (void) printf("%*s", width, zonename);
1980 }
1981 }
1982 break;
1983 case F_CTID:
1984 if (psinfo->pr_contract == -1)
1985 (void) printf("%*s", width, "-");
1986 else
1987 (void) printf("%*ld", width, (long)psinfo->pr_contract);
1988 break;
1989 case F_LGRP:
1990 /* Display home lgroup */
1991 (void) printf("%*d", width, (int)psinfo->pr_lwp.pr_lgrp);
1992 break;
1993
1994 case F_DMODEL:
1995 (void) printf("%*s", width,
1996 psinfo->pr_dmodel == PR_MODEL_LP64 ? "_LP64" : "_ILP32");
1997 break;
1998 }
2234 static void
2235 przom(psinfo_t *psinfo)
2236 {
2237 long tm;
2238 struct passwd *pwd;
2239 char zonename[ZONENAME_MAX];
2240
2241 /*
2242 * All fields before 'PID' are printed with a trailing space as a
2243 * spearator, rather than keeping track of which column is first. All
2244 * other fields are printed with a leading space.
2245 */
2246 if (lflg) { /* F S */
2247 if (!yflg)
2248 (void) printf("%2x ", psinfo->pr_flag & 0377); /* F */
2249 (void) printf("%c ", psinfo->pr_lwp.pr_sname); /* S */
2250 }
2251 if (Zflg) {
2252 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
2253 sizeof (zonename)) < 0) {
2254 if (snprintf(NULL, 0, "%d",
2255 ((int)psinfo->pr_zoneid)) > 7)
2256 (void) printf(" %6.6d%c ",
2257 ((int)psinfo->pr_zoneid), '*');
2258 else
2259 (void) printf(" %7.7d ",
2260 ((int)psinfo->pr_zoneid));
2261 } else {
2262 if (strlen(zonename) > 8)
2263 (void) printf("%7.7s%c ", zonename, '*');
2264 else
2265 (void) printf("%8.8s ", zonename);
2266 }
2267 }
2268 if (Hflg) {
2269 /* Display home lgroup */
2270 (void) printf(" %6d", (int)psinfo->pr_lwp.pr_lgrp); /* LGRP */
2271 }
2272 if (fflg) {
2273 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL) {
2274 if (strlen(pwd->pw_name) > 8)
2275 (void) printf("%7.7s%c ", pwd->pw_name, '*');
2276 else
2277 (void) printf("%8.8s ", pwd->pw_name);
2278 } else {
2279 if (snprintf(NULL, 0, "%u",
2280 ((int)psinfo->pr_euid)) > 7)
2281 (void) printf(" %6.6u%c ", psinfo->pr_euid,
2282 '*');
2283 else
2284 (void) printf(" %7.7u ", psinfo->pr_euid);
2285 }
2286 } else if (lflg) {
2287 if (snprintf(NULL, 0, "%u", ((int)psinfo->pr_euid)) > 6)
2288 (void) printf("%5.5u%c ", psinfo->pr_euid, '*');
2289 else
2290 (void) printf("%6u ", psinfo->pr_euid);
2291 }
2292
2293 (void) printf("%*d", pidwidth, (int)psinfo->pr_pid); /* PID */
2294 if (lflg || fflg)
2295 (void) printf(" %*d", pidwidth,
2296 (int)psinfo->pr_ppid); /* PPID */
2297
2298 if (jflg) {
2299 (void) printf(" %*d", pidwidth,
2300 (int)psinfo->pr_pgid); /* PGID */
2301 (void) printf(" %*d", pidwidth,
2302 (int)psinfo->pr_sid); /* SID */
2303 }
2304
2305 if (Lflg)
2306 (void) printf(" %5d", 0); /* LWP */
2307 if (Pflg)
2308 (void) printf(" -"); /* PSR */
2309 if (Lflg && fflg)
2310 (void) printf(" %5d", 0); /* NLWP */
2311
|