diff options
Diffstat (limited to 'procps/ps.c')
-rw-r--r-- | procps/ps.c | 128 |
1 files changed, 22 insertions, 106 deletions
diff --git a/procps/ps.c b/procps/ps.c index 6036ffc1e..cf2f2b0c4 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -44,82 +44,10 @@ static const int TERMINAL_WIDTH = 79; /* not 80 in case terminal has linefo | |||
44 | 44 | ||
45 | #if ! defined CONFIG_FEATURE_USE_DEVPS_PATCH | 45 | #if ! defined CONFIG_FEATURE_USE_DEVPS_PATCH |
46 | 46 | ||
47 | /* The following is the first ps implementation -- | ||
48 | * the one using the /proc virtual filesystem. | ||
49 | */ | ||
50 | |||
51 | typedef struct proc_s { | ||
52 | char cmd[16]; /* basename of executable file in call to exec(2) */ | ||
53 | int ruid; /* real only (sorry) */ | ||
54 | int pid; /* process id */ | ||
55 | int ppid; /* pid of parent process */ | ||
56 | char state; /* single-char code for process state (S=sleeping) */ | ||
57 | unsigned int vmsize; /* size of process as far as the vm is concerned */ | ||
58 | } proc_t; | ||
59 | |||
60 | |||
61 | |||
62 | static int file2str(char *filename, char *ret, int cap) | ||
63 | { | ||
64 | int fd, num_read; | ||
65 | |||
66 | if ((fd = open(filename, O_RDONLY, 0)) == -1) | ||
67 | return -1; | ||
68 | if ((num_read = read(fd, ret, cap - 1)) <= 0) | ||
69 | return -1; | ||
70 | ret[num_read] = 0; | ||
71 | close(fd); | ||
72 | return num_read; | ||
73 | } | ||
74 | |||
75 | |||
76 | static void parse_proc_status(char *S, proc_t * P) | ||
77 | { | ||
78 | char *tmp; | ||
79 | |||
80 | memset(P->cmd, 0, sizeof P->cmd); | ||
81 | sscanf(S, "Name:\t%15c", P->cmd); | ||
82 | tmp = strchr(P->cmd, '\n'); | ||
83 | if (tmp) | ||
84 | *tmp = '\0'; | ||
85 | tmp = strstr(S, "State"); | ||
86 | sscanf(tmp, "State:\t%c", &P->state); | ||
87 | |||
88 | P->pid = 0; | ||
89 | P->ppid = 0; | ||
90 | tmp = strstr(S, "Pid:"); | ||
91 | if (tmp) | ||
92 | sscanf(tmp, "Pid:\t%d\n" "PPid:\t%d\n", &P->pid, &P->ppid); | ||
93 | else | ||
94 | error_msg("Internal error!"); | ||
95 | |||
96 | /* For busybox, ignoring effective, saved, etc. */ | ||
97 | P->ruid = 0; | ||
98 | tmp = strstr(S, "Uid:"); | ||
99 | if (tmp) | ||
100 | sscanf(tmp, "Uid:\t%d", &P->ruid); | ||
101 | else | ||
102 | error_msg("Internal error!"); | ||
103 | |||
104 | P->vmsize = 0; | ||
105 | tmp = strstr(S, "VmSize:"); | ||
106 | if (tmp) | ||
107 | sscanf(tmp, "VmSize:\t%d", &P->vmsize); | ||
108 | #if 0 | ||
109 | else | ||
110 | error_msg("Internal error!"); | ||
111 | #endif | ||
112 | } | ||
113 | |||
114 | extern int ps_main(int argc, char **argv) | 47 | extern int ps_main(int argc, char **argv) |
115 | { | 48 | { |
116 | proc_t p; | 49 | procps_status_t * p; |
117 | DIR *dir; | 50 | int i, len; |
118 | FILE *file; | ||
119 | struct dirent *entry; | ||
120 | char path[32], sbuf[512]; | ||
121 | char uidName[9]; | ||
122 | int len, i, c; | ||
123 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 51 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
124 | struct winsize win = { 0, 0, 0, 0 }; | 52 | struct winsize win = { 0, 0, 0, 0 }; |
125 | int terminal_width = TERMINAL_WIDTH; | 53 | int terminal_width = TERMINAL_WIDTH; |
@@ -128,11 +56,6 @@ extern int ps_main(int argc, char **argv) | |||
128 | #endif | 56 | #endif |
129 | 57 | ||
130 | 58 | ||
131 | |||
132 | dir = opendir("/proc"); | ||
133 | if (!dir) | ||
134 | error_msg_and_die("Can't open /proc"); | ||
135 | |||
136 | #ifdef CONFIG_FEATURE_AUTOWIDTH | 59 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
137 | ioctl(fileno(stdout), TIOCGWINSZ, &win); | 60 | ioctl(fileno(stdout), TIOCGWINSZ, &win); |
138 | if (win.ws_col > 0) | 61 | if (win.ws_col > 0) |
@@ -140,38 +63,31 @@ extern int ps_main(int argc, char **argv) | |||
140 | #endif | 63 | #endif |
141 | 64 | ||
142 | printf(" PID Uid VmSize Stat Command\n"); | 65 | printf(" PID Uid VmSize Stat Command\n"); |
143 | while ((entry = readdir(dir)) != NULL) { | 66 | while ((p = procps_scan(1)) != 0) { |
144 | if (!isdigit(*entry->d_name)) | 67 | char *namecmd = p->cmd; |
145 | continue; | ||
146 | sprintf(path, "/proc/%s/status", entry->d_name); | ||
147 | if ((file2str(path, sbuf, sizeof sbuf)) != -1) { | ||
148 | parse_proc_status(sbuf, &p); | ||
149 | } | ||
150 | 68 | ||
151 | /* Make some adjustments as needed */ | 69 | if(p->rss == 0) |
152 | my_getpwuid(uidName, p.ruid); | 70 | len = printf("%5d %-8s %s ", p->pid, p->user, p->state); |
71 | else | ||
72 | len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state); | ||
73 | i = terminal_width-len; | ||
153 | 74 | ||
154 | sprintf(path, "/proc/%s/cmdline", entry->d_name); | 75 | if(namecmd != 0 && namecmd[0] != 0) { |
155 | file = fopen(path, "r"); | 76 | if(i < 0) |
156 | if (file == NULL) | ||
157 | continue; | ||
158 | i = 0; | 77 | i = 0; |
159 | if(p.vmsize == 0) | 78 | if(strlen(namecmd) > i) |
160 | len = printf("%5d %-8s %c ", p.pid, uidName, p.state); | 79 | namecmd[i] = 0; |
161 | else | 80 | printf("%s\n", namecmd); |
162 | len = printf("%5d %-8s %6d %c ", p.pid, uidName, p.vmsize, p.state); | 81 | } else { |
163 | while (((c = getc(file)) != EOF) && (i < (terminal_width-len))) { | 82 | namecmd = p->short_cmd; |
164 | i++; | 83 | if(i < 2) |
165 | if (c == '\0') | 84 | i = 2; |
166 | c = ' '; | 85 | if(strlen(namecmd) > (i-2)) |
167 | putc(c, stdout); | 86 | namecmd[i-2] = 0; |
87 | printf("[%s]\n", namecmd); | ||
168 | } | 88 | } |
169 | fclose(file); | 89 | free(p->cmd); |
170 | if (i == 0) | ||
171 | printf("[%s]", p.cmd); | ||
172 | putchar('\n'); | ||
173 | } | 90 | } |
174 | closedir(dir); | ||
175 | return EXIT_SUCCESS; | 91 | return EXIT_SUCCESS; |
176 | } | 92 | } |
177 | 93 | ||