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 * Portions Copyright 2009 Chad Mynhier
27 * Copyright 2012 Joyent, Inc. All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/resource.h>
32 #include <sys/loadavg.h>
33 #include <sys/time.h>
34 #include <sys/pset.h>
35 #include <sys/vm_usage.h>
36 #include <zone.h>
37 #include <libzonecfg.h>
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <dirent.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <poll.h>
46 #include <ctype.h>
47 #include <fcntl.h>
48 #include <limits.h>
49 #include <signal.h>
50 #include <time.h>
51 #include <project.h>
52
53 #include <langinfo.h>
54 #include <libintl.h>
55 #include <locale.h>
56
57 #include "prstat.h"
58 #include "prutil.h"
59 #include "prtable.h"
60 #include "prsort.h"
61 #include "prfile.h"
62
63 /*
64 * x86 <sys/regs.h> ERR conflicts with <curses.h> ERR. For the purposes
65 * of this file, we care about the curses.h ERR so include that last.
66 */
67
68 #if defined(ERR)
69 #undef ERR
70 #endif
71
72 #ifndef TEXT_DOMAIN /* should be defined by cc -D */
73 #define TEXT_DOMAIN "SYS_TEST" /* use this only if it wasn't */
74 #endif
75
76 #include <curses.h>
101 #define PROJECT_HEADER_LWP \
102 "PROJID NLWP SWAP RSS MEMORY TIME CPU PROJECT "
103 #define ZONE_HEADER_PROC \
104 "ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE "
105 #define ZONE_HEADER_LWP \
106 "ZONEID NLWP SWAP RSS MEMORY TIME CPU ZONE "
107 #define PSINFO_LINE \
108 "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %-.16s/%d"
109 #define PSINFO_LINE_LGRP \
110 "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %-.16s/%d"
111 #define USAGE_LINE \
112 "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\
113 "%3.3s %-.12s/%d"
114 #define USER_LINE \
115 "%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%"
116 #define TASK_LINE \
117 "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
118 #define PROJECT_LINE \
119 "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
120 #define ZONE_LINE \
121 "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
122
123 #define TOTAL_LINE \
124 "Total: %d processes, %d lwps, load averages: %3.2f, %3.2f, %3.2f"
125
126 /* global variables */
127
128 static char *t_ulon; /* termcap: start underline */
129 static char *t_uloff; /* termcap: end underline */
130 static char *t_up; /* termcap: cursor 1 line up */
131 static char *t_eol; /* termcap: clear end of line */
132 static char *t_smcup; /* termcap: cursor mvcap on */
133 static char *t_rmcup; /* termcap: cursor mvcap off */
134 static char *t_home; /* termcap: move cursor home */
135 static char *movecur = NULL; /* termcap: move up string */
136 static char *empty_string = "\0"; /* termcap: empty string */
137 static uint_t print_movecur = FALSE; /* print movecur or not */
138 static int is_curses_on = FALSE; /* current curses state */
139
140 static table_t pid_tbl = {0, 0, NULL}; /* selected processes */
141 static table_t cpu_tbl = {0, 0, NULL}; /* selected processors */
148 static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */
149
150 static uint_t total_procs; /* total number of procs */
151 static uint_t total_lwps; /* total number of lwps */
152 static float total_cpu; /* total cpu usage */
153 static float total_mem; /* total memory usage */
154
155 static list_t lwps; /* list of lwps/processes */
156 static list_t users; /* list of users */
157 static list_t tasks; /* list of tasks */
158 static list_t projects; /* list of projects */
159 static list_t zones; /* list of zones */
160 static list_t lgroups; /* list of lgroups */
161
162 static volatile uint_t sigwinch = 0;
163 static volatile uint_t sigtstp = 0;
164 static volatile uint_t sigterm = 0;
165
166 static long pagesize;
167
168 /* default settings */
169
170 static optdesc_t opts = {
171 5, /* interval between updates, seconds */
172 15, /* number of lines in top part */
173 5, /* number of lines in bottom part */
174 -1, /* number of iterations; infinitely */
175 OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP,
176 -1 /* sort in decreasing order */
177 };
178
179 /*
180 * Print timestamp as decimal reprentation of time_t value (-d u was specified)
181 * or the standard date format (-d d was specified).
182 */
183 static void
184 print_timestamp(void)
185 {
186 time_t t = time(NULL);
187 static char *fmt = NULL;
466 PROJNAME_MAX,
467 opts.o_outpmode & OPT_NORESOLVE);
468 Format_size(psize, id->id_size, 6);
469 Format_size(prssize, id->id_rssize, 6);
470 Format_pct(pmem, mem, 4);
471 Format_pct(pcpu, cpu, 4);
472 Format_time(ptime, id->id_time, 10);
473 if (opts.o_outpmode & OPT_TTY)
474 (void) putchar('\r');
475 if (list->l_type == LT_PROJECTS)
476 (void) printf(PROJECT_LINE, (int)id->id_projid,
477 id->id_nproc, psize, prssize, pmem, ptime,
478 pcpu, projname);
479 else if (list->l_type == LT_TASKS)
480 (void) printf(TASK_LINE, (int)id->id_taskid,
481 id->id_nproc, psize, prssize, pmem, ptime,
482 pcpu, projname);
483 else if (list->l_type == LT_ZONES)
484 (void) printf(ZONE_LINE, (int)id->id_zoneid,
485 id->id_nproc, psize, prssize, pmem, ptime,
486 pcpu, zonename);
487 else
488 (void) printf(USER_LINE, id->id_nproc, pname,
489 psize, prssize, pmem, ptime, pcpu);
490 (void) putp(t_eol);
491 (void) putchar('\n');
492 break;
493 case LT_LWPS:
494 lwp = list->l_ptrs[i];
495 if (opts.o_outpmode & OPT_LWPS)
496 lwpid = lwp->li_info.pr_lwp.pr_lwpid;
497 else
498 lwpid = lwp->li_info.pr_nlwp +
499 lwp->li_info.pr_nzomb;
500 pwd_getname(lwp->li_info.pr_uid, pname, LOGNAME_MAX + 1,
501 opts.o_outpmode & OPT_NORESOLVE);
502 if (opts.o_outpmode & OPT_PSINFO) {
503 Format_size(psize, lwp->li_info.pr_size, 6);
504 Format_size(prssize, lwp->li_info.pr_rssize, 6);
505 Format_state(pstate,
506 lwp->li_info.pr_lwp.pr_sname,
818 TIME2NSEC(lwp->li_usage.pr_slptime))/period;
819 }
820 lwp->li_trp = (TIME2NSEC(usage->pr_ttime) -
821 TIME2NSEC(lwp->li_usage.pr_ttime))/period;
822 lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) -
823 TIME2NSEC(lwp->li_usage.pr_tftime))/period;
824 lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) -
825 TIME2NSEC(lwp->li_usage.pr_dftime))/period;
826 lwp->li_lck = (TIME2NSEC(usage->pr_ltime) -
827 TIME2NSEC(lwp->li_usage.pr_ltime))/period;
828 lwp->li_lat = (TIME2NSEC(usage->pr_wtime) -
829 TIME2NSEC(lwp->li_usage.pr_wtime))/period;
830 lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx;
831 lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx;
832 lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc;
833 lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs;
834 (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
835 }
836 }
837
838 static int
839 read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize)
840 {
841 char procfile[MAX_PROCFS_PATH];
842
843 (void) snprintf(procfile, MAX_PROCFS_PATH,
844 "/proc/%s/%s", pidstr, file);
845 if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL)
846 return (1);
847 if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) {
848 fd_close(*fd);
849 return (1);
850 }
851 return (0);
852 }
853
854 static void
855 add_proc(psinfo_t *psinfo)
856 {
857 lwp_info_t *lwp;
1359 int
1360 main(int argc, char **argv)
1361 {
1362 DIR *procdir;
1363 char *p;
1364 char *sortk = "cpu"; /* default sort key */
1365 int opt;
1366 int timeout;
1367 struct pollfd pollset;
1368 char key;
1369
1370 (void) setlocale(LC_ALL, "");
1371 (void) textdomain(TEXT_DOMAIN);
1372 Progname(argv[0]);
1373 lwpid_init();
1374 fd_init(Setrlimit());
1375
1376 pagesize = sysconf(_SC_PAGESIZE);
1377
1378 while ((opt = getopt(argc, argv,
1379 "vVcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJz:Z")) != (int)EOF) {
1380 switch (opt) {
1381 case 'r':
1382 opts.o_outpmode |= OPT_NORESOLVE;
1383 break;
1384 case 'R':
1385 opts.o_outpmode |= OPT_REALTIME;
1386 break;
1387 case 'c':
1388 opts.o_outpmode &= ~OPT_TERMCAP;
1389 opts.o_outpmode &= ~OPT_FULLSCREEN;
1390 break;
1391 case 'd':
1392 if (optarg) {
1393 if (*optarg == 'u')
1394 opts.o_outpmode |= OPT_UDATE;
1395 else if (*optarg == 'd')
1396 opts.o_outpmode |= OPT_DDATE;
1397 else
1398 Usage();
1399 } else {
1400 Usage();
|
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 * Portions Copyright 2009 Chad Mynhier
27 * Copyright 2013 Joyent, Inc. All rights reserved.
28 */
29
30 #include <sys/types.h>
31 #include <sys/resource.h>
32 #include <sys/loadavg.h>
33 #include <sys/time.h>
34 #include <sys/pset.h>
35 #include <sys/vm_usage.h>
36 #include <sys/queue.h>
37 #include <zone.h>
38 #include <libzonecfg.h>
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <dirent.h>
44 #include <string.h>
45 #include <strings.h>
46 #include <errno.h>
47 #include <poll.h>
48 #include <ctype.h>
49 #include <fcntl.h>
50 #include <limits.h>
51 #include <signal.h>
52 #include <time.h>
53 #include <project.h>
54
55 #include <langinfo.h>
56 #include <libintl.h>
57 #include <locale.h>
58
59 #include <sasl/saslutil.h>
60
61 #include "prstat.h"
62 #include "prutil.h"
63 #include "prtable.h"
64 #include "prsort.h"
65 #include "prfile.h"
66
67 /*
68 * x86 <sys/regs.h> ERR conflicts with <curses.h> ERR. For the purposes
69 * of this file, we care about the curses.h ERR so include that last.
70 */
71
72 #if defined(ERR)
73 #undef ERR
74 #endif
75
76 #ifndef TEXT_DOMAIN /* should be defined by cc -D */
77 #define TEXT_DOMAIN "SYS_TEST" /* use this only if it wasn't */
78 #endif
79
80 #include <curses.h>
105 #define PROJECT_HEADER_LWP \
106 "PROJID NLWP SWAP RSS MEMORY TIME CPU PROJECT "
107 #define ZONE_HEADER_PROC \
108 "ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE "
109 #define ZONE_HEADER_LWP \
110 "ZONEID NLWP SWAP RSS MEMORY TIME CPU ZONE "
111 #define PSINFO_LINE \
112 "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %-.16s/%d"
113 #define PSINFO_LINE_LGRP \
114 "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %-.16s/%d"
115 #define USAGE_LINE \
116 "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\
117 "%3.3s %-.12s/%d"
118 #define USER_LINE \
119 "%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%"
120 #define TASK_LINE \
121 "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
122 #define PROJECT_LINE \
123 "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
124 #define ZONE_LINE \
125 "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %-28s"
126
127 #define TOTAL_LINE \
128 "Total: %d processes, %d lwps, load averages: %3.2f, %3.2f, %3.2f"
129
130 /* global variables */
131
132 static char *t_ulon; /* termcap: start underline */
133 static char *t_uloff; /* termcap: end underline */
134 static char *t_up; /* termcap: cursor 1 line up */
135 static char *t_eol; /* termcap: clear end of line */
136 static char *t_smcup; /* termcap: cursor mvcap on */
137 static char *t_rmcup; /* termcap: cursor mvcap off */
138 static char *t_home; /* termcap: move cursor home */
139 static char *movecur = NULL; /* termcap: move up string */
140 static char *empty_string = "\0"; /* termcap: empty string */
141 static uint_t print_movecur = FALSE; /* print movecur or not */
142 static int is_curses_on = FALSE; /* current curses state */
143
144 static table_t pid_tbl = {0, 0, NULL}; /* selected processes */
145 static table_t cpu_tbl = {0, 0, NULL}; /* selected processors */
152 static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */
153
154 static uint_t total_procs; /* total number of procs */
155 static uint_t total_lwps; /* total number of lwps */
156 static float total_cpu; /* total cpu usage */
157 static float total_mem; /* total memory usage */
158
159 static list_t lwps; /* list of lwps/processes */
160 static list_t users; /* list of users */
161 static list_t tasks; /* list of tasks */
162 static list_t projects; /* list of projects */
163 static list_t zones; /* list of zones */
164 static list_t lgroups; /* list of lgroups */
165
166 static volatile uint_t sigwinch = 0;
167 static volatile uint_t sigtstp = 0;
168 static volatile uint_t sigterm = 0;
169
170 static long pagesize;
171
172 /*
173 * Cache for mapping 'alias' names (an attribute of the zone configuration) to
174 * zone names, for use in -Z output.
175 */
176 static uint_t enable_alias_cache = FALSE;
177 static SLIST_HEAD(alias_cache_head, alias_cache_entry) alias_cache =
178 SLIST_HEAD_INITIALIZER(alias_cache);
179
180 typedef struct alias_cache_entry {
181 char *ace_zonename;
182 char *ace_alias;
183
184 SLIST_ENTRY(alias_cache_entry) ace_linkage;
185 } alias_cache_entry_t;
186
187 static const char *lookup_zone_alias(const char *);
188
189 /* default settings */
190
191 static optdesc_t opts = {
192 5, /* interval between updates, seconds */
193 15, /* number of lines in top part */
194 5, /* number of lines in bottom part */
195 -1, /* number of iterations; infinitely */
196 OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP,
197 -1 /* sort in decreasing order */
198 };
199
200 /*
201 * Print timestamp as decimal reprentation of time_t value (-d u was specified)
202 * or the standard date format (-d d was specified).
203 */
204 static void
205 print_timestamp(void)
206 {
207 time_t t = time(NULL);
208 static char *fmt = NULL;
487 PROJNAME_MAX,
488 opts.o_outpmode & OPT_NORESOLVE);
489 Format_size(psize, id->id_size, 6);
490 Format_size(prssize, id->id_rssize, 6);
491 Format_pct(pmem, mem, 4);
492 Format_pct(pcpu, cpu, 4);
493 Format_time(ptime, id->id_time, 10);
494 if (opts.o_outpmode & OPT_TTY)
495 (void) putchar('\r');
496 if (list->l_type == LT_PROJECTS)
497 (void) printf(PROJECT_LINE, (int)id->id_projid,
498 id->id_nproc, psize, prssize, pmem, ptime,
499 pcpu, projname);
500 else if (list->l_type == LT_TASKS)
501 (void) printf(TASK_LINE, (int)id->id_taskid,
502 id->id_nproc, psize, prssize, pmem, ptime,
503 pcpu, projname);
504 else if (list->l_type == LT_ZONES)
505 (void) printf(ZONE_LINE, (int)id->id_zoneid,
506 id->id_nproc, psize, prssize, pmem, ptime,
507 pcpu, lookup_zone_alias(zonename));
508 else
509 (void) printf(USER_LINE, id->id_nproc, pname,
510 psize, prssize, pmem, ptime, pcpu);
511 (void) putp(t_eol);
512 (void) putchar('\n');
513 break;
514 case LT_LWPS:
515 lwp = list->l_ptrs[i];
516 if (opts.o_outpmode & OPT_LWPS)
517 lwpid = lwp->li_info.pr_lwp.pr_lwpid;
518 else
519 lwpid = lwp->li_info.pr_nlwp +
520 lwp->li_info.pr_nzomb;
521 pwd_getname(lwp->li_info.pr_uid, pname, LOGNAME_MAX + 1,
522 opts.o_outpmode & OPT_NORESOLVE);
523 if (opts.o_outpmode & OPT_PSINFO) {
524 Format_size(psize, lwp->li_info.pr_size, 6);
525 Format_size(prssize, lwp->li_info.pr_rssize, 6);
526 Format_state(pstate,
527 lwp->li_info.pr_lwp.pr_sname,
839 TIME2NSEC(lwp->li_usage.pr_slptime))/period;
840 }
841 lwp->li_trp = (TIME2NSEC(usage->pr_ttime) -
842 TIME2NSEC(lwp->li_usage.pr_ttime))/period;
843 lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) -
844 TIME2NSEC(lwp->li_usage.pr_tftime))/period;
845 lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) -
846 TIME2NSEC(lwp->li_usage.pr_dftime))/period;
847 lwp->li_lck = (TIME2NSEC(usage->pr_ltime) -
848 TIME2NSEC(lwp->li_usage.pr_ltime))/period;
849 lwp->li_lat = (TIME2NSEC(usage->pr_wtime) -
850 TIME2NSEC(lwp->li_usage.pr_wtime))/period;
851 lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx;
852 lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx;
853 lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc;
854 lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs;
855 (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
856 }
857 }
858
859 static alias_cache_entry_t *
860 fetch_zone_alias(const char *zonen)
861 {
862 zone_dochandle_t zch;
863 alias_cache_entry_t *ace;
864 struct zone_attrtab attrtab;
865 char out[4 * sizeof (attrtab.zone_attr_value)];
866 unsigned outlen = 0;
867 int err;
868
869 /*
870 * Get handle to zone configuration:
871 */
872 if ((zch = zonecfg_init_handle()) == NULL)
873 return (NULL);
874 if (zonecfg_get_handle(zonen, zch) != Z_OK) {
875 zonecfg_fini_handle(zch);
876 return (NULL);
877 }
878
879 /*
880 * Lookup the 'alias' attribute:
881 */
882 bzero(&attrtab, sizeof (attrtab));
883 (void) strlcpy(attrtab.zone_attr_name, "alias",
884 sizeof (attrtab.zone_attr_name));
885 if ((zonecfg_lookup_attr(zch, &attrtab)) != Z_OK) {
886 zonecfg_fini_handle(zch);
887 return (NULL);
888 }
889 zonecfg_fini_handle(zch);
890
891 /*
892 * Attempt to base64 decode the 'alias' attribute value:
893 */
894 if ((err = sasl_decode64(attrtab.zone_attr_value,
895 strlen(attrtab.zone_attr_value), out, sizeof (out), &outlen)) !=
896 SASL_OK) {
897 if (err == SASL_BADPROT) {
898 /*
899 * If it was invalid base64, hand the raw value on:
900 */
901 (void) strlcpy(out, attrtab.zone_attr_value,
902 sizeof (out));
903 } else {
904 /*
905 * If we failed for any other reason, error out:
906 */
907 return (NULL);
908 }
909 }
910
911 /*
912 * Store it in the cache:
913 */
914 if ((ace = calloc(1, sizeof (*ace))) == NULL) {
915 return (NULL);
916 }
917 if ((ace->ace_zonename = strdup(zonen)) == NULL) {
918 free(ace);
919 return (NULL);
920 }
921 if ((ace->ace_alias = strdup(out)) == NULL) {
922 free(ace->ace_zonename);
923 free(ace);
924 return (NULL);
925 }
926
927 SLIST_INSERT_HEAD(&alias_cache, ace, ace_linkage);
928
929 return (ace);
930 }
931
932 static const char *
933 lookup_zone_alias(const char *zonen)
934 {
935 alias_cache_entry_t *ace;
936
937 if (enable_alias_cache != TRUE)
938 return (zonen);
939
940 /*
941 * Check if we have a value cached:
942 */
943 SLIST_FOREACH(ace, &alias_cache, ace_linkage) {
944 if (strcmp(ace->ace_zonename, zonen) == 0)
945 return (ace->ace_alias);
946 }
947
948 /*
949 * If not, try and fetch it from libzonecfg:
950 */
951 if ((ace = fetch_zone_alias(zonen)) != NULL)
952 return (ace->ace_alias);
953
954 return (zonen);
955 }
956
957 static int
958 read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize)
959 {
960 char procfile[MAX_PROCFS_PATH];
961
962 (void) snprintf(procfile, MAX_PROCFS_PATH,
963 "/proc/%s/%s", pidstr, file);
964 if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL)
965 return (1);
966 if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) {
967 fd_close(*fd);
968 return (1);
969 }
970 return (0);
971 }
972
973 static void
974 add_proc(psinfo_t *psinfo)
975 {
976 lwp_info_t *lwp;
1478 int
1479 main(int argc, char **argv)
1480 {
1481 DIR *procdir;
1482 char *p;
1483 char *sortk = "cpu"; /* default sort key */
1484 int opt;
1485 int timeout;
1486 struct pollfd pollset;
1487 char key;
1488
1489 (void) setlocale(LC_ALL, "");
1490 (void) textdomain(TEXT_DOMAIN);
1491 Progname(argv[0]);
1492 lwpid_init();
1493 fd_init(Setrlimit());
1494
1495 pagesize = sysconf(_SC_PAGESIZE);
1496
1497 while ((opt = getopt(argc, argv,
1498 "vVcd:HmAarRLtu:U:n:p:C:P:h:s:S:j:k:TJz:Z")) != (int)EOF) {
1499 switch (opt) {
1500 case 'A':
1501 enable_alias_cache = TRUE;
1502 break;
1503 case 'r':
1504 opts.o_outpmode |= OPT_NORESOLVE;
1505 break;
1506 case 'R':
1507 opts.o_outpmode |= OPT_REALTIME;
1508 break;
1509 case 'c':
1510 opts.o_outpmode &= ~OPT_TERMCAP;
1511 opts.o_outpmode &= ~OPT_FULLSCREEN;
1512 break;
1513 case 'd':
1514 if (optarg) {
1515 if (*optarg == 'u')
1516 opts.o_outpmode |= OPT_UDATE;
1517 else if (*optarg == 'd')
1518 opts.o_outpmode |= OPT_DDATE;
1519 else
1520 Usage();
1521 } else {
1522 Usage();
|