diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-08 03:06:04 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-08 03:06:04 +0200 |
commit | 4ac9819263114edb9b5b638ffa6d2e41a4bb46e7 (patch) | |
tree | f0c5bc9c7a2bf3a384b85350bfe4c9ca5ec4858f /libbb | |
parent | 5b807cd5acd1f27b3e7aa36aac2728be27c5907c (diff) | |
download | busybox-w32-4ac9819263114edb9b5b638ffa6d2e41a4bb46e7.tar.gz busybox-w32-4ac9819263114edb9b5b638ffa6d2e41a4bb46e7.tar.bz2 busybox-w32-4ac9819263114edb9b5b638ffa6d2e41a4bb46e7.zip |
apply post-1.15.1 fixes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/lineedit.c | 49 | ||||
-rw-r--r-- | libbb/procps.c | 133 | ||||
-rw-r--r-- | libbb/recursive_action.c | 17 |
3 files changed, 111 insertions, 88 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 9a773b4b8..071fc5bce 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -114,8 +114,8 @@ struct lineedit_statics { | |||
114 | unsigned cmdedit_prmt_len; /* length of prompt (without colors etc) */ | 114 | unsigned cmdedit_prmt_len; /* length of prompt (without colors etc) */ |
115 | 115 | ||
116 | unsigned cursor; | 116 | unsigned cursor; |
117 | unsigned command_len; | 117 | int command_len; /* must be signed (^D returns -1 len) */ |
118 | /* *int* maxsize: we want x in "if (x > S.maxsize)" | 118 | /* signed maxsize: we want x in "if (x > S.maxsize)" |
119 | * to _not_ be promoted to unsigned */ | 119 | * to _not_ be promoted to unsigned */ |
120 | int maxsize; | 120 | int maxsize; |
121 | CHAR_T *command_ps; | 121 | CHAR_T *command_ps; |
@@ -1095,15 +1095,15 @@ static void save_command_ps_at_cur_history(void) | |||
1095 | int cur = state->cur_history; | 1095 | int cur = state->cur_history; |
1096 | free(state->history[cur]); | 1096 | free(state->history[cur]); |
1097 | 1097 | ||
1098 | #if ENABLE_FEATURE_ASSUME_UNICODE | 1098 | # if ENABLE_FEATURE_ASSUME_UNICODE |
1099 | { | 1099 | { |
1100 | char tbuf[MAX_LINELEN]; | 1100 | char tbuf[MAX_LINELEN]; |
1101 | save_string(tbuf, sizeof(tbuf)); | 1101 | save_string(tbuf, sizeof(tbuf)); |
1102 | state->history[cur] = xstrdup(tbuf); | 1102 | state->history[cur] = xstrdup(tbuf); |
1103 | } | 1103 | } |
1104 | #else | 1104 | # else |
1105 | state->history[cur] = xstrdup(command_ps); | 1105 | state->history[cur] = xstrdup(command_ps); |
1106 | #endif | 1106 | # endif |
1107 | } | 1107 | } |
1108 | } | 1108 | } |
1109 | 1109 | ||
@@ -1131,7 +1131,7 @@ static int get_next_history(void) | |||
1131 | return 0; | 1131 | return 0; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1134 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY |
1135 | /* We try to ensure that concurrent additions to the history | 1135 | /* We try to ensure that concurrent additions to the history |
1136 | * do not overwrite each other. | 1136 | * do not overwrite each other. |
1137 | * Otherwise shell users get unhappy. | 1137 | * Otherwise shell users get unhappy. |
@@ -1256,10 +1256,10 @@ static void save_history(char *str) | |||
1256 | free_line_input_t(st_temp); | 1256 | free_line_input_t(st_temp); |
1257 | } | 1257 | } |
1258 | } | 1258 | } |
1259 | #else | 1259 | # else |
1260 | #define load_history(a) ((void)0) | 1260 | # define load_history(a) ((void)0) |
1261 | #define save_history(a) ((void)0) | 1261 | # define save_history(a) ((void)0) |
1262 | #endif /* FEATURE_COMMAND_SAVEHISTORY */ | 1262 | # endif /* FEATURE_COMMAND_SAVEHISTORY */ |
1263 | 1263 | ||
1264 | static void remember_in_history(char *str) | 1264 | static void remember_in_history(char *str) |
1265 | { | 1265 | { |
@@ -1290,15 +1290,15 @@ static void remember_in_history(char *str) | |||
1290 | /* i <= MAX_HISTORY */ | 1290 | /* i <= MAX_HISTORY */ |
1291 | state->cur_history = i; | 1291 | state->cur_history = i; |
1292 | state->cnt_history = i; | 1292 | state->cnt_history = i; |
1293 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1293 | # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY |
1294 | if ((state->flags & SAVE_HISTORY) && state->hist_file) | 1294 | if ((state->flags & SAVE_HISTORY) && state->hist_file) |
1295 | save_history(str); | 1295 | save_history(str); |
1296 | #endif | 1296 | # endif |
1297 | IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) | 1297 | IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) |
1298 | } | 1298 | } |
1299 | 1299 | ||
1300 | #else /* MAX_HISTORY == 0 */ | 1300 | #else /* MAX_HISTORY == 0 */ |
1301 | #define remember_in_history(a) ((void)0) | 1301 | # define remember_in_history(a) ((void)0) |
1302 | #endif /* MAX_HISTORY */ | 1302 | #endif /* MAX_HISTORY */ |
1303 | 1303 | ||
1304 | 1304 | ||
@@ -1476,11 +1476,11 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1476 | c = *prmt_ptr++; | 1476 | c = *prmt_ptr++; |
1477 | 1477 | ||
1478 | switch (c) { | 1478 | switch (c) { |
1479 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | 1479 | # if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR |
1480 | case 'u': | 1480 | case 'u': |
1481 | pbuf = user_buf ? user_buf : (char*)""; | 1481 | pbuf = user_buf ? user_buf : (char*)""; |
1482 | break; | 1482 | break; |
1483 | #endif | 1483 | # endif |
1484 | case 'h': | 1484 | case 'h': |
1485 | pbuf = free_me = safe_gethostname(); | 1485 | pbuf = free_me = safe_gethostname(); |
1486 | *strchrnul(pbuf, '.') = '\0'; | 1486 | *strchrnul(pbuf, '.') = '\0'; |
@@ -1488,7 +1488,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1488 | case '$': | 1488 | case '$': |
1489 | c = (geteuid() == 0 ? '#' : '$'); | 1489 | c = (geteuid() == 0 ? '#' : '$'); |
1490 | break; | 1490 | break; |
1491 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | 1491 | # if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR |
1492 | case 'w': | 1492 | case 'w': |
1493 | /* /home/user[/something] -> ~[/something] */ | 1493 | /* /home/user[/something] -> ~[/something] */ |
1494 | pbuf = cwd_buf; | 1494 | pbuf = cwd_buf; |
@@ -1501,7 +1501,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1501 | pbuf = free_me = xasprintf("~%s", cwd_buf + l); | 1501 | pbuf = free_me = xasprintf("~%s", cwd_buf + l); |
1502 | } | 1502 | } |
1503 | break; | 1503 | break; |
1504 | #endif | 1504 | # endif |
1505 | case 'W': | 1505 | case 'W': |
1506 | pbuf = cwd_buf; | 1506 | pbuf = cwd_buf; |
1507 | cp = strrchr(pbuf, '/'); | 1507 | cp = strrchr(pbuf, '/'); |
@@ -1688,13 +1688,15 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1688 | 1688 | ||
1689 | /* With null flags, no other fields are ever used */ | 1689 | /* With null flags, no other fields are ever used */ |
1690 | state = st ? st : (line_input_t*) &const_int_0; | 1690 | state = st ? st : (line_input_t*) &const_int_0; |
1691 | #if ENABLE_FEATURE_EDITING_SAVEHISTORY | 1691 | #if MAX_HISTORY > 0 |
1692 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | ||
1692 | if ((state->flags & SAVE_HISTORY) && state->hist_file) | 1693 | if ((state->flags & SAVE_HISTORY) && state->hist_file) |
1693 | if (state->cnt_history == 0) | 1694 | if (state->cnt_history == 0) |
1694 | load_history(state); | 1695 | load_history(state); |
1695 | #endif | 1696 | # endif |
1696 | if (state->flags & DO_HISTORY) | 1697 | if (state->flags & DO_HISTORY) |
1697 | state->cur_history = state->cnt_history; | 1698 | state->cur_history = state->cnt_history; |
1699 | #endif | ||
1698 | 1700 | ||
1699 | /* prepare before init handlers */ | 1701 | /* prepare before init handlers */ |
1700 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | 1702 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ |
@@ -1716,7 +1718,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1716 | new_settings.c_cc[VTIME] = 0; | 1718 | new_settings.c_cc[VTIME] = 0; |
1717 | /* Turn off CTRL-C, so we can trap it */ | 1719 | /* Turn off CTRL-C, so we can trap it */ |
1718 | #ifndef _POSIX_VDISABLE | 1720 | #ifndef _POSIX_VDISABLE |
1719 | #define _POSIX_VDISABLE '\0' | 1721 | # define _POSIX_VDISABLE '\0' |
1720 | #endif | 1722 | #endif |
1721 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; | 1723 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; |
1722 | tcsetattr_stdin_TCSANOW(&new_settings); | 1724 | tcsetattr_stdin_TCSANOW(&new_settings); |
@@ -2037,7 +2039,8 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
2037 | rewrite_line: | 2039 | rewrite_line: |
2038 | /* Rewrite the line with the selected history item */ | 2040 | /* Rewrite the line with the selected history item */ |
2039 | /* change command */ | 2041 | /* change command */ |
2040 | command_len = load_string(state->history[state->cur_history] ? : "", maxsize); | 2042 | command_len = load_string(state->history[state->cur_history] ? |
2043 | state->history[state->cur_history] : "", maxsize); | ||
2041 | /* redraw and go to eol (bol, in vi) */ | 2044 | /* redraw and go to eol (bol, in vi) */ |
2042 | redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); | 2045 | redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); |
2043 | break; | 2046 | break; |
@@ -2121,7 +2124,9 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
2121 | #undef command | 2124 | #undef command |
2122 | 2125 | ||
2123 | #if ENABLE_FEATURE_ASSUME_UNICODE | 2126 | #if ENABLE_FEATURE_ASSUME_UNICODE |
2124 | command_len = save_string(command, maxsize - 1); | 2127 | command[0] = '\0'; |
2128 | if (command_len > 0) | ||
2129 | command_len = save_string(command, maxsize - 1); | ||
2125 | free(command_ps); | 2130 | free(command_ps); |
2126 | #endif | 2131 | #endif |
2127 | 2132 | ||
diff --git a/libbb/procps.c b/libbb/procps.c index 307d8d622..7276f60ef 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -134,8 +134,8 @@ static unsigned long fast_strtoul_16(char **endptr) | |||
134 | return n; | 134 | return n; |
135 | } | 135 | } |
136 | /* TOPMEM uses fast_strtoul_10, so... */ | 136 | /* TOPMEM uses fast_strtoul_10, so... */ |
137 | #undef ENABLE_FEATURE_FAST_TOP | 137 | # undef ENABLE_FEATURE_FAST_TOP |
138 | #define ENABLE_FEATURE_FAST_TOP 1 | 138 | # define ENABLE_FEATURE_FAST_TOP 1 |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #if ENABLE_FEATURE_FAST_TOP | 141 | #if ENABLE_FEATURE_FAST_TOP |
@@ -198,14 +198,16 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
198 | if (errno) | 198 | if (errno) |
199 | continue; | 199 | continue; |
200 | 200 | ||
201 | /* After this point we have to break, not continue | 201 | /* After this point we can: |
202 | * ("continue" would mean that current /proc/NNN | 202 | * "break": stop parsing, return the data |
203 | * is not a valid process info) */ | 203 | * "continue": try next /proc/XXX |
204 | */ | ||
204 | 205 | ||
205 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); | 206 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); |
206 | 207 | ||
207 | sp->pid = pid; | 208 | sp->pid = pid; |
208 | if (!(flags & ~PSSCAN_PID)) break; | 209 | if (!(flags & ~PSSCAN_PID)) |
210 | break; /* we needed only pid, we got it */ | ||
209 | 211 | ||
210 | #if ENABLE_SELINUX | 212 | #if ENABLE_SELINUX |
211 | if (flags & PSSCAN_CONTEXT) { | 213 | if (flags & PSSCAN_CONTEXT) { |
@@ -218,7 +220,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
218 | 220 | ||
219 | if (flags & PSSCAN_UIDGID) { | 221 | if (flags & PSSCAN_UIDGID) { |
220 | if (stat(filename, &sb)) | 222 | if (stat(filename, &sb)) |
221 | break; | 223 | continue; /* process probably exited */ |
222 | /* Effective UID/GID, not real */ | 224 | /* Effective UID/GID, not real */ |
223 | sp->uid = sb.st_uid; | 225 | sp->uid = sb.st_uid; |
224 | sp->gid = sb.st_gid; | 226 | sp->gid = sb.st_gid; |
@@ -234,10 +236,10 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
234 | strcpy(filename_tail, "stat"); | 236 | strcpy(filename_tail, "stat"); |
235 | n = read_to_buf(filename, buf); | 237 | n = read_to_buf(filename, buf); |
236 | if (n < 0) | 238 | if (n < 0) |
237 | break; | 239 | continue; /* process probably exited */ |
238 | cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */ | 240 | cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */ |
239 | /*if (!cp || cp[1] != ' ') | 241 | /*if (!cp || cp[1] != ' ') |
240 | break;*/ | 242 | continue;*/ |
241 | cp[0] = '\0'; | 243 | cp[0] = '\0'; |
242 | if (sizeof(sp->comm) < 16) | 244 | if (sizeof(sp->comm) < 16) |
243 | BUG_comm_size(); | 245 | BUG_comm_size(); |
@@ -257,12 +259,12 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
257 | "%lu " /* start_time */ | 259 | "%lu " /* start_time */ |
258 | "%lu " /* vsize */ | 260 | "%lu " /* vsize */ |
259 | "%lu " /* rss */ | 261 | "%lu " /* rss */ |
260 | #if ENABLE_FEATURE_TOP_SMP_PROCESS | 262 | # if ENABLE_FEATURE_TOP_SMP_PROCESS |
261 | "%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ | 263 | "%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ |
262 | "%*s %*s %*s %*s " /*signal, blocked, sigignore, sigcatch */ | 264 | "%*s %*s %*s %*s " /*signal, blocked, sigignore, sigcatch */ |
263 | "%*s %*s %*s %*s " /*wchan, nswap, cnswap, exit_signal */ | 265 | "%*s %*s %*s %*s " /*wchan, nswap, cnswap, exit_signal */ |
264 | "%d" /*cpu last seen on*/ | 266 | "%d" /*cpu last seen on*/ |
265 | #endif | 267 | # endif |
266 | , | 268 | , |
267 | sp->state, &sp->ppid, | 269 | sp->state, &sp->ppid, |
268 | &sp->pgid, &sp->sid, &tty, | 270 | &sp->pgid, &sp->sid, &tty, |
@@ -271,17 +273,17 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
271 | &sp->start_time, | 273 | &sp->start_time, |
272 | &vsz, | 274 | &vsz, |
273 | &rss | 275 | &rss |
274 | #if ENABLE_FEATURE_TOP_SMP_PROCESS | 276 | # if ENABLE_FEATURE_TOP_SMP_PROCESS |
275 | , &sp->last_seen_on_cpu | 277 | , &sp->last_seen_on_cpu |
276 | #endif | 278 | # endif |
277 | ); | 279 | ); |
278 | 280 | ||
279 | if (n < 11) | 281 | if (n < 11) |
280 | break; | 282 | continue; /* bogus data, get next /proc/XXX */ |
281 | #if ENABLE_FEATURE_TOP_SMP_PROCESS | 283 | # if ENABLE_FEATURE_TOP_SMP_PROCESS |
282 | if (n < 11+15) | 284 | if (n < 11+15) |
283 | sp->last_seen_on_cpu = 0; | 285 | sp->last_seen_on_cpu = 0; |
284 | #endif | 286 | # endif |
285 | 287 | ||
286 | /* vsz is in bytes and we want kb */ | 288 | /* vsz is in bytes and we want kb */ |
287 | sp->vsz = vsz >> 10; | 289 | sp->vsz = vsz >> 10; |
@@ -311,14 +313,14 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
311 | sp->vsz = fast_strtoul_10(&cp) >> 10; | 313 | sp->vsz = fast_strtoul_10(&cp) >> 10; |
312 | /* vsz is in bytes but rss is in *PAGES*! Can you believe that? */ | 314 | /* vsz is in bytes but rss is in *PAGES*! Can you believe that? */ |
313 | sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb; | 315 | sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb; |
314 | #if ENABLE_FEATURE_TOP_SMP_PROCESS | 316 | # if ENABLE_FEATURE_TOP_SMP_PROCESS |
315 | /* (6): rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ | 317 | /* (6): rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ |
316 | /* (4): signal, blocked, sigignore, sigcatch */ | 318 | /* (4): signal, blocked, sigignore, sigcatch */ |
317 | /* (4): wchan, nswap, cnswap, exit_signal */ | 319 | /* (4): wchan, nswap, cnswap, exit_signal */ |
318 | cp = skip_fields(cp, 14); | 320 | cp = skip_fields(cp, 14); |
319 | //FIXME: is it safe to assume this field exists? | 321 | //FIXME: is it safe to assume this field exists? |
320 | sp->last_seen_on_cpu = fast_strtoul_10(&cp); | 322 | sp->last_seen_on_cpu = fast_strtoul_10(&cp); |
321 | #endif | 323 | # endif |
322 | #endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */ | 324 | #endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */ |
323 | 325 | ||
324 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS | 326 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS |
@@ -343,48 +345,48 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
343 | 345 | ||
344 | strcpy(filename_tail, "smaps"); | 346 | strcpy(filename_tail, "smaps"); |
345 | file = fopen_for_read(filename); | 347 | file = fopen_for_read(filename); |
346 | if (!file) | 348 | if (file) { |
347 | break; | 349 | while (fgets(buf, sizeof(buf), file)) { |
348 | while (fgets(buf, sizeof(buf), file)) { | 350 | unsigned long sz; |
349 | unsigned long sz; | 351 | char *tp; |
350 | char *tp; | 352 | char w; |
351 | char w; | ||
352 | #define SCAN(str, name) \ | 353 | #define SCAN(str, name) \ |
353 | if (strncmp(buf, str, sizeof(str)-1) == 0) { \ | 354 | if (strncmp(buf, str, sizeof(str)-1) == 0) { \ |
354 | tp = skip_whitespace(buf + sizeof(str)-1); \ | 355 | tp = skip_whitespace(buf + sizeof(str)-1); \ |
355 | sp->name += fast_strtoul_10(&tp); \ | 356 | sp->name += fast_strtoul_10(&tp); \ |
356 | continue; \ | 357 | continue; \ |
357 | } | 358 | } |
358 | SCAN("Shared_Clean:" , shared_clean ); | 359 | SCAN("Shared_Clean:" , shared_clean ); |
359 | SCAN("Shared_Dirty:" , shared_dirty ); | 360 | SCAN("Shared_Dirty:" , shared_dirty ); |
360 | SCAN("Private_Clean:", private_clean); | 361 | SCAN("Private_Clean:", private_clean); |
361 | SCAN("Private_Dirty:", private_dirty); | 362 | SCAN("Private_Dirty:", private_dirty); |
362 | #undef SCAN | 363 | #undef SCAN |
363 | // f7d29000-f7d39000 rw-s ADR M:m OFS FILE | 364 | // f7d29000-f7d39000 rw-s ADR M:m OFS FILE |
364 | tp = strchr(buf, '-'); | 365 | tp = strchr(buf, '-'); |
365 | if (tp) { | 366 | if (tp) { |
366 | *tp = ' '; | 367 | *tp = ' '; |
367 | tp = buf; | 368 | tp = buf; |
368 | sz = fast_strtoul_16(&tp); /* start */ | 369 | sz = fast_strtoul_16(&tp); /* start */ |
369 | sz = (fast_strtoul_16(&tp) - sz) >> 10; /* end - start */ | 370 | sz = (fast_strtoul_16(&tp) - sz) >> 10; /* end - start */ |
370 | // tp -> "rw-s" string | 371 | // tp -> "rw-s" string |
371 | w = tp[1]; | 372 | w = tp[1]; |
372 | // skipping "rw-s ADR M:m OFS " | 373 | // skipping "rw-s ADR M:m OFS " |
373 | tp = skip_whitespace(skip_fields(tp, 4)); | 374 | tp = skip_whitespace(skip_fields(tp, 4)); |
374 | // filter out /dev/something (something != zero) | 375 | // filter out /dev/something (something != zero) |
375 | if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { | 376 | if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { |
376 | if (w == 'w') { | 377 | if (w == 'w') { |
377 | sp->mapped_rw += sz; | 378 | sp->mapped_rw += sz; |
378 | } else if (w == '-') { | 379 | } else if (w == '-') { |
379 | sp->mapped_ro += sz; | 380 | sp->mapped_ro += sz; |
381 | } | ||
380 | } | 382 | } |
381 | } | ||
382 | //else printf("DROPPING %s (%s)\n", buf, tp); | 383 | //else printf("DROPPING %s (%s)\n", buf, tp); |
383 | if (strcmp(tp, "[stack]\n") == 0) | 384 | if (strcmp(tp, "[stack]\n") == 0) |
384 | sp->stack += sz; | 385 | sp->stack += sz; |
386 | } | ||
385 | } | 387 | } |
388 | fclose(file); | ||
386 | } | 389 | } |
387 | fclose(file); | ||
388 | } | 390 | } |
389 | #endif /* TOPMEM */ | 391 | #endif /* TOPMEM */ |
390 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS | 392 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS |
@@ -393,23 +395,34 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
393 | 395 | ||
394 | strcpy(filename_tail, "status"); | 396 | strcpy(filename_tail, "status"); |
395 | file = fopen_for_read(filename); | 397 | file = fopen_for_read(filename); |
396 | if (!file) | 398 | if (file) { |
397 | break; | 399 | while (fgets(buf, sizeof(buf), file)) { |
398 | while (fgets(buf, sizeof(buf), file)) { | 400 | char *tp; |
399 | char *tp; | ||
400 | #define SCAN_TWO(str, name, statement) \ | 401 | #define SCAN_TWO(str, name, statement) \ |
401 | if (strncmp(buf, str, sizeof(str)-1) == 0) { \ | 402 | if (strncmp(buf, str, sizeof(str)-1) == 0) { \ |
402 | tp = skip_whitespace(buf + sizeof(str)-1); \ | 403 | tp = skip_whitespace(buf + sizeof(str)-1); \ |
403 | sscanf(tp, "%u", &sp->name); \ | 404 | sscanf(tp, "%u", &sp->name); \ |
404 | statement; \ | 405 | statement; \ |
405 | } | 406 | } |
406 | SCAN_TWO("Uid:", ruid, continue); | 407 | SCAN_TWO("Uid:", ruid, continue); |
407 | SCAN_TWO("Gid:", rgid, break); | 408 | SCAN_TWO("Gid:", rgid, break); |
408 | #undef SCAN_TWO | 409 | #undef SCAN_TWO |
410 | } | ||
411 | fclose(file); | ||
409 | } | 412 | } |
410 | fclose(file); | ||
411 | } | 413 | } |
412 | #endif /* PS_ADDITIONAL_COLUMNS */ | 414 | #endif /* PS_ADDITIONAL_COLUMNS */ |
415 | if (flags & PSSCAN_EXE) { | ||
416 | strcpy(filename_tail, "exe"); | ||
417 | free(sp->exe); | ||
418 | sp->exe = xmalloc_readlink(filename); | ||
419 | } | ||
420 | /* Note: if /proc/PID/cmdline is empty, | ||
421 | * code below "breaks". Therefore it must be | ||
422 | * the last code to parse /proc/PID/xxx data | ||
423 | * (we used to have /proc/PID/exe parsing after it | ||
424 | * and were getting stale sp->exe). | ||
425 | */ | ||
413 | #if 0 /* PSSCAN_CMD is not used */ | 426 | #if 0 /* PSSCAN_CMD is not used */ |
414 | if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) { | 427 | if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) { |
415 | free(sp->argv0); | 428 | free(sp->argv0); |
@@ -452,13 +465,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
452 | } | 465 | } |
453 | } | 466 | } |
454 | #endif | 467 | #endif |
455 | if (flags & PSSCAN_EXE) { | ||
456 | strcpy(filename_tail, "exe"); | ||
457 | free(sp->exe); | ||
458 | sp->exe = xmalloc_readlink(filename); | ||
459 | } | ||
460 | break; | 468 | break; |
461 | } | 469 | } /* for (;;) */ |
470 | |||
462 | return sp; | 471 | return sp; |
463 | } | 472 | } |
464 | 473 | ||
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index 3ec596a35..3a4eb28db 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c | |||
@@ -61,6 +61,7 @@ int FAST_FUNC recursive_action(const char *fileName, | |||
61 | unsigned depth) | 61 | unsigned depth) |
62 | { | 62 | { |
63 | struct stat statbuf; | 63 | struct stat statbuf; |
64 | unsigned follow; | ||
64 | int status; | 65 | int status; |
65 | DIR *dir; | 66 | DIR *dir; |
66 | struct dirent *next; | 67 | struct dirent *next; |
@@ -68,14 +69,22 @@ int FAST_FUNC recursive_action(const char *fileName, | |||
68 | if (!fileAction) fileAction = true_action; | 69 | if (!fileAction) fileAction = true_action; |
69 | if (!dirAction) dirAction = true_action; | 70 | if (!dirAction) dirAction = true_action; |
70 | 71 | ||
71 | status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */ | 72 | follow = ACTION_FOLLOWLINKS; |
72 | if (!depth) | 73 | if (depth == 0) |
73 | status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; | 74 | follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; |
74 | status = ((flags & status) ? stat : lstat)(fileName, &statbuf); | 75 | follow &= flags; |
76 | status = (follow ? stat : lstat)(fileName, &statbuf); | ||
75 | if (status < 0) { | 77 | if (status < 0) { |
76 | #ifdef DEBUG_RECURS_ACTION | 78 | #ifdef DEBUG_RECURS_ACTION |
77 | bb_error_msg("status=%d flags=%x", status, flags); | 79 | bb_error_msg("status=%d flags=%x", status, flags); |
78 | #endif | 80 | #endif |
81 | if ((flags & ACTION_DANGLING_OK) | ||
82 | && errno == ENOENT | ||
83 | && lstat(fileName, &statbuf) == 0 | ||
84 | ) { | ||
85 | /* Dangling link */ | ||
86 | return fileAction(fileName, &statbuf, userData, depth); | ||
87 | } | ||
79 | goto done_nak_warn; | 88 | goto done_nak_warn; |
80 | } | 89 | } |
81 | 90 | ||