top: add support for -b, -n <iterations>
[oweals/busybox.git] / procps / ps.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini ps implementation(s) for busybox
4  *
5  * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6  *
7  * Licensed under the GPL version 2, see the file LICENSE in this tarball.
8  */
9
10 #include "busybox.h"
11
12 int ps_main(int argc, char **argv)
13 {
14         procps_status_t * p;
15         int i, len;
16
17 #if ENABLE_SELINUX
18         int use_selinux = 0;
19         security_context_t sid = NULL;
20 #endif
21
22 #if ENABLE_FEATURE_PS_WIDE
23         int terminal_width;
24         int w_count = 0;
25
26         bb_opt_complementally = "-:ww";
27 #else
28 # define terminal_width 79
29 #endif
30
31 #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX
32         /* handle arguments */
33 #if ENABLE_FEATURE_PS_WIDE && ENABLE_SELINUX
34         i = bb_getopt_ulflags(argc, argv, "wc", &w_count);
35 #elif ENABLE_FEATURE_PS_WIDE && !ENABLE_SELINUX
36         bb_getopt_ulflags(argc, argv, "w", &w_count);
37 #else /* !ENABLE_FEATURE_PS_WIDE && ENABLE_SELINUX */
38         i = bb_getopt_ulflags(argc, argv, "c");
39 #endif
40 #if ENABLE_FEATURE_PS_WIDE
41         /* if w is given once, GNU ps sets the width to 132,
42          * if w is given more than once, it is "unlimited"
43          */
44         if(w_count) {
45                 terminal_width = (w_count==1) ? 132 : INT_MAX;
46         } else {
47                 get_terminal_width_height(1, &terminal_width, NULL);
48                 /* Go one less... */
49                 terminal_width--;
50         }
51 #endif
52 #if ENABLE_SELINUX
53         if ((i & (1+ENABLE_FEATURE_PS_WIDE)) && is_selinux_enabled())
54                 use_selinux = 1;
55 #endif
56 #endif  /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */
57
58 #if ENABLE_SELINUX
59         if (use_selinux)
60                 puts("  PID Context                          Stat Command");
61         else
62 #endif
63                 puts("  PID  Uid     VmSize Stat Command");
64
65         while ((p = procps_scan(1)) != 0)  {
66                 char *namecmd = p->cmd;
67 #if ENABLE_SELINUX
68                 if (use_selinux) {
69                         char sbuf[128];
70                         len = sizeof(sbuf);
71
72                         if (is_selinux_enabled()) {
73                                 if (getpidcon(p->pid,&sid) < 0)
74                                         sid = NULL;
75                         }
76
77                         if (sid) {
78                                 /*  I assume sid initilized with NULL  */
79                                 len = strlen(sid)+1;
80                                 safe_strncpy(sbuf, sid, len);
81                                 freecon(sid);
82                                 sid = NULL;
83                         } else {
84                                 safe_strncpy(sbuf, "unknown", 7);
85                         }
86                         len = printf("%5d %-32s %s ", p->pid, sbuf, p->state);
87                 }
88                 else
89 #endif
90                         if(p->rss == 0)
91                                 len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
92                         else
93                                 len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
94
95                 i = terminal_width-len;
96
97                 if(namecmd && namecmd[0]) {
98                         if(i < 0)
99                                 i = 0;
100                         if(strlen(namecmd) > (size_t)i)
101                                 namecmd[i] = 0;
102                         printf("%s\n", namecmd);
103                 } else {
104                         namecmd = p->short_cmd;
105                         if(i < 2)
106                                 i = 2;
107                         if(strlen(namecmd) > ((size_t)i-2))
108                                 namecmd[i-2] = 0;
109                         printf("[%s]\n", namecmd);
110                 }
111                 /* no check needed, but to make valgrind happy..  */
112                 if (ENABLE_FEATURE_CLEAN_UP && p->cmd)
113                         free(p->cmd);
114         }
115         return EXIT_SUCCESS;
116 }