18a6db36fa14b74e6b993f616b2618f2877168f8
[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  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19  * Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <dirent.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <termios.h>
31 #include <sys/ioctl.h>
32 #include "busybox.h"
33 #ifdef CONFIG_SELINUX
34 #include <selinux/selinux.h>  /* for is_selinux_enabled()  */
35 #endif
36
37 static const int TERMINAL_WIDTH = 79;      /* not 80 in case terminal has linefold bug */
38
39
40
41 extern int ps_main(int argc, char **argv)
42 {
43         procps_status_t * p;
44         int i, len;
45         int terminal_width = TERMINAL_WIDTH;
46
47 #ifdef CONFIG_SELINUX
48         int use_selinux = 0;
49         security_context_t sid=NULL;
50         if(is_selinux_enabled() && argv[1] && !strcmp(argv[1], "-c") )
51                 use_selinux = 1;
52 #endif
53
54         get_terminal_width_height(0, &terminal_width, NULL);
55         /* Go one less... */
56         terminal_width--;
57
58 #ifdef CONFIG_SELINUX
59         if (use_selinux)
60           printf("  PID Context                          Stat Command\n");
61         else
62 #endif
63           printf("  PID  Uid     VmSize Stat Command\n");
64
65         while ((p = procps_scan(1)) != 0)  {
66                 char *namecmd = p->cmd;
67 #ifdef CONFIG_SELINUX
68                 if ( use_selinux )
69                   {
70                         char sbuf[128];
71                         len = sizeof(sbuf);
72
73                         if (is_selinux_enabled()) {
74                           if (getpidcon(p->pid,&sid)<0)
75                             sid=NULL;
76                         }
77
78                         if (sid) {
79                           /*  I assume sid initilized with NULL  */
80                           len = strlen(sid)+1;
81                           safe_strncpy(sbuf, sid, len);
82                           freecon(sid);
83                           sid=NULL;
84                         }else {
85                           safe_strncpy(sbuf, "unknown",7);
86                         }
87                         len = printf("%5d %-32s %s ", p->pid, sbuf, p->state);
88                 } 
89                 else
90 #endif
91                   if(p->rss == 0)
92                     len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
93                   else
94                     len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
95                 i = terminal_width-len;
96
97                 if(namecmd != 0 && namecmd[0] != 0) {
98                         if(i < 0)
99                 i = 0;
100                         if(strlen(namecmd) > 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) > (i-2))
108                                 namecmd[i-2] = 0;
109                         printf("[%s]\n", namecmd);
110                 }
111                 free(p->cmd);
112         }
113         return EXIT_SUCCESS;
114 }
115