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 }
1929 }
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 /* Max chars in a user/group name or printed u/g id */
82 #define MAXUGNAME (LOGNAME_MAX+2)
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 size_t nw;
1414
1415 nw = mbstowcs(NULL, zonename, 0);
1416 if (nw == (size_t)-1)
1417 (void) printf("%8.8s ", "ERROR");
1418 else if (nw > 8)
1419 (void) wprintf(L"%7.7s%c ", zonename, '*');
1420 else
1421 (void) wprintf(L"%8.8s ", zonename);
1422 }
1423 }
1424
1425 if (fflg) { /* UID */
1426 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL) {
1427 size_t nw;
1428
1429 nw = mbstowcs(NULL, pwd->pw_name, 0);
1430 if (nw == (size_t)-1)
1431 (void) printf("%8.8s ", "ERROR");
1432 else if (nw > 8)
1433 (void) wprintf(L"%7.7s%c ", pwd->pw_name, '*');
1434 else
1435 (void) wprintf(L"%8.8s ", pwd->pw_name);
1436 } else {
1437 if (snprintf(NULL, 0, "%u",
1438 (psinfo->pr_euid)) > 7)
1439 (void) printf(" %6.6u%c ", psinfo->pr_euid,
1440 '*');
1441 else
1442 (void) printf(" %7.7u ", psinfo->pr_euid);
1443 }
1444 } else if (lflg) {
1445 if (snprintf(NULL, 0, "%u", (psinfo->pr_euid)) > 6)
1446 (void) printf("%5.5u%c ", psinfo->pr_euid, '*');
1447 else
1448 (void) printf("%6u ", psinfo->pr_euid);
1449 }
1450 (void) printf("%*d", pidwidth, (int)psinfo->pr_pid); /* PID */
1451 if (lflg || fflg)
1452 (void) printf(" %*d", pidwidth,
1453 (int)psinfo->pr_ppid); /* PPID */
1454 if (jflg) {
1455 (void) printf(" %*d", pidwidth,
1456 (int)psinfo->pr_pgid); /* PGID */
1457 (void) printf(" %*d", pidwidth,
1458 (int)psinfo->pr_sid); /* SID */
1459 }
1460 if (Lflg)
1461 (void) printf(" %5d", (int)psinfo->pr_lwp.pr_lwpid); /* LWP */
1462 if (Pflg) {
1463 if (psinfo->pr_lwp.pr_bindpro == PBIND_NONE) /* PSR */
1464 (void) printf(" -");
1465 else
1466 (void) printf(" %3d", psinfo->pr_lwp.pr_bindpro);
1467 }
1649 static void
1650 print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
1651 {
1652 int width = f->width;
1653 struct passwd *pwd;
1654 struct group *grp;
1655 time_t cputime;
1656 int bytesleft;
1657 int wcnt;
1658 wchar_t wchar;
1659 char *cp;
1660 int length;
1661 ulong_t mask;
1662 char c, *csave;
1663 int zombie_lwp;
1664
1665 zombie_lwp = (Lflg && psinfo->pr_lwp.pr_sname == 'Z');
1666
1667 switch (f->fname) {
1668 case F_RUSER:
1669 if ((pwd = getpwuid(psinfo->pr_uid)) != NULL) {
1670 size_t nw;
1671
1672 nw = mbstowcs(NULL, pwd->pw_name, 0);
1673 if (nw == (size_t)-1)
1674 (void) printf("%*s ", width, "ERROR");
1675 else if (Wflg && nw > width)
1676 (void) wprintf(L"%.*s%c", width - 1,
1677 pwd->pw_name, '*');
1678 else
1679 (void) wprintf(L"%*s", width, pwd->pw_name);
1680 } else {
1681 if (Wflg && snprintf(NULL, 0, "%u",
1682 (psinfo->pr_uid)) > width)
1683
1684 (void) printf("%*u%c", width - 1,
1685 psinfo->pr_uid, '*');
1686 else
1687 (void) printf("%*u", width, psinfo->pr_uid);
1688 }
1689 break;
1690 case F_USER:
1691 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL) {
1692 size_t nw;
1693
1694 nw = mbstowcs(NULL, pwd->pw_name, 0);
1695 if (nw == (size_t)-1)
1696 (void) printf("%*s ", width, "ERROR");
1697 else if (Wflg && nw > width)
1698 (void) wprintf(L"%.*s%c", width - 1,
1699 pwd->pw_name, '*');
1700 else
1701 (void) wprintf(L"%*s", width, pwd->pw_name);
1702 } else {
1703 if (Wflg && snprintf(NULL, 0, "%u",
1704 (psinfo->pr_euid)) > width)
1705
1706 (void) printf("%*u%c", width - 1,
1707 psinfo->pr_euid, '*');
1708 else
1709 (void) printf("%*u", width, psinfo->pr_euid);
1710 }
1711 break;
1712 case F_RGROUP:
1713 if ((grp = getgrgid(psinfo->pr_gid)) != NULL)
1714 (void) printf("%*s", width, grp->gr_name);
1715 else
1716 (void) printf("%*u", width, psinfo->pr_gid);
1717 break;
1718 case F_GROUP:
1719 if ((grp = getgrgid(psinfo->pr_egid)) != NULL)
1720 (void) printf("%*s", width, grp->gr_name);
1721 else
1722 (void) printf("%*u", width, psinfo->pr_egid);
1723 break;
1724 case F_RUID:
1725 (void) printf("%*u", width, psinfo->pr_uid);
1726 break;
1727 case F_UID:
1728 (void) printf("%*u", width, psinfo->pr_euid);
1729 break;
1730 case F_RGID:
1932 (void) printf("%-*.*s", width, wcnt,
1933 psinfo->pr_psargs);
1934 else
1935 (void) printf("%-.*s", wcnt,
1936 psinfo->pr_psargs);
1937 if (f->fname == F_COMM && csave)
1938 *csave = c;
1939 break;
1940 case F_TASKID:
1941 (void) printf("%*d", width, (int)psinfo->pr_taskid);
1942 break;
1943 case F_PROJID:
1944 (void) printf("%*d", width, (int)psinfo->pr_projid);
1945 break;
1946 case F_PROJECT:
1947 {
1948 struct project cproj;
1949 char proj_buf[PROJECT_BUFSZ];
1950
1951 if ((getprojbyid(psinfo->pr_projid, &cproj,
1952 (void *)&proj_buf, PROJECT_BUFSZ)) == NULL) {
1953 if (Wflg && snprintf(NULL, 0, "%d",
1954 ((int)psinfo->pr_projid)) > width)
1955 (void) printf("%.*d%c", width - 1,
1956 ((int)psinfo->pr_projid), '*');
1957 else
1958 (void) printf("%*d", width,
1959 (int)psinfo->pr_projid);
1960 } else {
1961 size_t nw;
1962
1963 if (cproj.pj_name != NULL)
1964 nw = mbstowcs(NULL, cproj.pj_name, 0);
1965 if (cproj.pj_name == NULL)
1966 (void) printf("%*s ", width, "---");
1967 else if (nw == (size_t)-1)
1968 (void) printf("%*s ", width, "ERROR");
1969 else if (Wflg && nw > width)
1970 (void) wprintf(L"%.*s%c", width - 1,
1971 cproj.pj_name, '*');
1972 else
1973 (void) wprintf(L"%*s", width,
1974 cproj.pj_name);
1975 }
1976 }
1977 break;
1978 case F_PSET:
1979 if (zombie_lwp || psinfo->pr_lwp.pr_bindpset == PS_NONE)
1980 (void) printf("%*s", width, "-");
1981 else
1982 (void) printf("%*d", width, psinfo->pr_lwp.pr_bindpset);
1983 break;
1984 case F_ZONEID:
1985 (void) printf("%*d", width, (int)psinfo->pr_zoneid);
1986 break;
1987 case F_ZONE:
1988 {
1989 char zonename[ZONENAME_MAX];
1990
1991 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
1992 sizeof (zonename)) < 0) {
1993 if (Wflg && snprintf(NULL, 0, "%d",
1994 ((int)psinfo->pr_zoneid)) > width)
1995 (void) printf("%.*d%c", width - 1,
1996 ((int)psinfo->pr_zoneid), '*');
1997 else
1998 (void) printf("%*d", width,
1999 (int)psinfo->pr_zoneid);
2000 } else {
2001 size_t nw;
2002
2003 nw = mbstowcs(NULL, zonename, 0);
2004 if (nw == (size_t)-1)
2005 (void) printf("%*s ", width, "ERROR");
2006 else if (Wflg && nw > width)
2007 (void) wprintf(L"%.*s%c", width - 1,
2008 zonename, '*');
2009 else
2010 (void) wprintf(L"%*s", width, zonename);
2011 }
2012 }
2013 break;
2014 case F_CTID:
2015 if (psinfo->pr_contract == -1)
2016 (void) printf("%*s", width, "-");
2017 else
2018 (void) printf("%*ld", width, (long)psinfo->pr_contract);
2019 break;
2020 case F_LGRP:
2021 /* Display home lgroup */
2022 (void) printf("%*d", width, (int)psinfo->pr_lwp.pr_lgrp);
2023 break;
2024
2025 case F_DMODEL:
2026 (void) printf("%*s", width,
2027 psinfo->pr_dmodel == PR_MODEL_LP64 ? "_LP64" : "_ILP32");
2028 break;
2029 }
2030 }
2265 static void
2266 przom(psinfo_t *psinfo)
2267 {
2268 long tm;
2269 struct passwd *pwd;
2270 char zonename[ZONENAME_MAX];
2271
2272 /*
2273 * All fields before 'PID' are printed with a trailing space as a
2274 * spearator, rather than keeping track of which column is first. All
2275 * other fields are printed with a leading space.
2276 */
2277 if (lflg) { /* F S */
2278 if (!yflg)
2279 (void) printf("%2x ", psinfo->pr_flag & 0377); /* F */
2280 (void) printf("%c ", psinfo->pr_lwp.pr_sname); /* S */
2281 }
2282 if (Zflg) {
2283 if (getzonenamebyid(psinfo->pr_zoneid, zonename,
2284 sizeof (zonename)) < 0) {
2285 if (snprintf(NULL, 0, "%d",
2286 ((int)psinfo->pr_zoneid)) > 7)
2287 (void) printf(" %6.6d%c ",
2288 ((int)psinfo->pr_zoneid), '*');
2289 else
2290 (void) printf(" %7.7d ",
2291 ((int)psinfo->pr_zoneid));
2292 } else {
2293 size_t nw;
2294
2295 nw = mbstowcs(NULL, zonename, 0);
2296 if (nw == (size_t)-1)
2297 (void) printf("%8.8s ", "ERROR");
2298 else if (nw > 8)
2299 (void) wprintf(L"%7.7s%c ", zonename, '*');
2300 else
2301 (void) wprintf(L"%8.8s ", zonename);
2302 }
2303 }
2304 if (Hflg) {
2305 /* Display home lgroup */
2306 (void) printf(" %6d", (int)psinfo->pr_lwp.pr_lgrp); /* LGRP */
2307 }
2308 if (fflg) {
2309 if ((pwd = getpwuid(psinfo->pr_euid)) != NULL) {
2310 size_t nw;
2311
2312 nw = mbstowcs(NULL, pwd->pw_name, 0);
2313 if (nw == (size_t)-1)
2314 (void) printf("%8.8s ", "ERROR");
2315 else if (nw > 8)
2316 (void) wprintf(L"%7.7s%c ", pwd->pw_name, '*');
2317 else
2318 (void) wprintf(L"%8.8s ", pwd->pw_name);
2319 } else {
2320 if (snprintf(NULL, 0, "%u",
2321 (psinfo->pr_euid)) > 7)
2322 (void) printf(" %6.6u%c ", psinfo->pr_euid,
2323 '*');
2324 else
2325 (void) printf(" %7.7u ", psinfo->pr_euid);
2326 }
2327 } else if (lflg) {
2328 if (snprintf(NULL, 0, "%u", (psinfo->pr_euid)) > 6)
2329 (void) printf("%5.5u%c ", psinfo->pr_euid, '*');
2330 else
2331 (void) printf("%6u ", psinfo->pr_euid);
2332 }
2333
2334 (void) printf("%*d", pidwidth, (int)psinfo->pr_pid); /* PID */
2335 if (lflg || fflg)
2336 (void) printf(" %*d", pidwidth,
2337 (int)psinfo->pr_ppid); /* PPID */
2338
2339 if (jflg) {
2340 (void) printf(" %*d", pidwidth,
2341 (int)psinfo->pr_pgid); /* PGID */
2342 (void) printf(" %*d", pidwidth,
2343 (int)psinfo->pr_sid); /* SID */
2344 }
2345
2346 if (Lflg)
2347 (void) printf(" %5d", 0); /* LWP */
2348 if (Pflg)
2349 (void) printf(" -"); /* PSR */
2350 if (Lflg && fflg)
2351 (void) printf(" %5d", 0); /* NLWP */
2352
|