diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-20 22:17:13 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-20 22:17:13 +0000 |
commit | 83518d18a34a3ddfcaac1739930d8469f5bc2442 (patch) | |
tree | 2af665365a69f2689288cc13bb65efbb59e7d520 | |
parent | 0b28103cc774eb1ee62362cf61d52c32d44ec2cf (diff) | |
download | busybox-w32-83518d18a34a3ddfcaac1739930d8469f5bc2442.tar.gz busybox-w32-83518d18a34a3ddfcaac1739930d8469f5bc2442.tar.bz2 busybox-w32-83518d18a34a3ddfcaac1739930d8469f5bc2442.zip |
Compatibility fixes:
grep: support -z
find: support --mindepth
together +45 bytes
cpio: support -p (configurable, +230 bytes)
libbb: tweaks for cpio
-rw-r--r-- | TODO_config_nommu | 1 | ||||
-rw-r--r-- | archival/Config.in | 7 | ||||
-rw-r--r-- | archival/cpio.c | 81 | ||||
-rw-r--r-- | findutils/find.c | 22 | ||||
-rw-r--r-- | findutils/grep.c | 17 | ||||
-rw-r--r-- | include/libbb.h | 10 | ||||
-rw-r--r-- | include/usage.h | 35 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 19 | ||||
-rw-r--r-- | miscutils/setsid.c | 3 | ||||
-rw-r--r-- | scripts/defconfig | 1 |
10 files changed, 137 insertions, 59 deletions
diff --git a/TODO_config_nommu b/TODO_config_nommu index 428d9b300..2061bfd1c 100644 --- a/TODO_config_nommu +++ b/TODO_config_nommu | |||
@@ -110,6 +110,7 @@ CONFIG_BUNZIP2=y | |||
110 | CONFIG_BZIP2=y | 110 | CONFIG_BZIP2=y |
111 | CONFIG_CPIO=y | 111 | CONFIG_CPIO=y |
112 | CONFIG_FEATURE_CPIO_O=y | 112 | CONFIG_FEATURE_CPIO_O=y |
113 | CONFIG_FEATURE_CPIO_P=y | ||
113 | CONFIG_DPKG=y | 114 | CONFIG_DPKG=y |
114 | CONFIG_DPKG_DEB=y | 115 | CONFIG_DPKG_DEB=y |
115 | CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY=y | 116 | CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY=y |
diff --git a/archival/Config.in b/archival/Config.in index 0b5cf3750..64b44c218 100644 --- a/archival/Config.in +++ b/archival/Config.in | |||
@@ -110,6 +110,13 @@ config FEATURE_CPIO_O | |||
110 | This implementation of cpio can create cpio archives in the "newc" | 110 | This implementation of cpio can create cpio archives in the "newc" |
111 | format only. | 111 | format only. |
112 | 112 | ||
113 | config FEATURE_CPIO_P | ||
114 | bool "Support for passthrough mode" | ||
115 | default n | ||
116 | depends on FEATURE_CPIO_O | ||
117 | help | ||
118 | Passthrough mode. Rarely used. | ||
119 | |||
113 | config DPKG | 120 | config DPKG |
114 | bool "dpkg" | 121 | bool "dpkg" |
115 | default n | 122 | default n |
diff --git a/archival/cpio.c b/archival/cpio.c index 1c30d89a8..929d544ff 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -259,8 +259,9 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
259 | CPIO_OPT_FILE = (1 << 4), | 259 | CPIO_OPT_FILE = (1 << 4), |
260 | CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), | 260 | CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), |
261 | CPIO_OPT_PRESERVE_MTIME = (1 << 6), | 261 | CPIO_OPT_PRESERVE_MTIME = (1 << 6), |
262 | CPIO_OPT_CREATE = (1 << 7), | 262 | CPIO_OPT_CREATE = (1 << 7) * ENABLE_FEATURE_CPIO_O, |
263 | CPIO_OPT_FORMAT = (1 << 8), | 263 | CPIO_OPT_FORMAT = (1 << 8) * ENABLE_FEATURE_CPIO_O, |
264 | CPIO_OPT_PASSTHROUGH = (1 << 9) * ENABLE_FEATURE_CPIO_P, | ||
264 | }; | 265 | }; |
265 | 266 | ||
266 | #if ENABLE_GETOPT_LONG | 267 | #if ENABLE_GETOPT_LONG |
@@ -270,21 +271,66 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
270 | #if ENABLE_FEATURE_CPIO_O | 271 | #if ENABLE_FEATURE_CPIO_O |
271 | "create\0" No_argument "o" | 272 | "create\0" No_argument "o" |
272 | "format\0" Required_argument "H" | 273 | "format\0" Required_argument "H" |
274 | #if ENABLE_FEATURE_CPIO_P | ||
275 | "pass-through\0" No_argument "p" | ||
276 | #endif | ||
273 | #endif | 277 | #endif |
274 | ; | 278 | ; |
275 | #endif | 279 | #endif |
276 | 280 | ||
277 | /* Initialize */ | 281 | /* As of now we do not enforce this: */ |
278 | archive_handle = init_handle(); | 282 | /* -i,-t,-o,-p are mutually exclusive */ |
279 | archive_handle->src_fd = STDIN_FILENO; | 283 | /* -u,-d,-m make sense only with -i or -p */ |
280 | archive_handle->seek = seek_by_read; | 284 | /* -F makes sense only with -o */ |
281 | archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; | 285 | #if !ENABLE_FEATURE_CPIO_O |
282 | 286 | opt = getopt32(argv, "ituvF:dm", &cpio_filename); | |
283 | #if ENABLE_FEATURE_CPIO_O | 287 | #else |
284 | opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt); | 288 | opt = getopt32(argv, "ituvF:dmoH:" USE_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); |
289 | if (opt & CPIO_OPT_PASSTHROUGH) { | ||
290 | pid_t pid; | ||
291 | struct fd_pair pp; | ||
285 | 292 | ||
293 | if (argv[optind] == NULL) | ||
294 | bb_show_usage(); | ||
295 | if (opt & CPIO_OPT_CREATE_LEADING_DIR) | ||
296 | mkdir(argv[optind], 0777); | ||
297 | /* Crude existence check: | ||
298 | * close(xopen(argv[optind], O_RDONLY | O_DIRECTORY)); | ||
299 | * We can also xopen, fstat, IS_DIR, later fchdir. | ||
300 | * This would check for existence earlier and cleaner. | ||
301 | * As it stands now, if we fail xchdir later, | ||
302 | * child dies on EPIPE, unless it caught | ||
303 | * a diffrerent problem earlier. | ||
304 | * This is good enough for now. | ||
305 | */ | ||
306 | #if !BB_MMU | ||
307 | pp.rd = 3; | ||
308 | pp.wr = 4; | ||
309 | if (!re_execed) { | ||
310 | close(3); | ||
311 | close(4); | ||
312 | xpiped_pair(pp); | ||
313 | } | ||
314 | #else | ||
315 | xpiped_pair(pp); | ||
316 | #endif | ||
317 | pid = fork_or_rexec(argv); | ||
318 | if (pid == 0) { /* child */ | ||
319 | close(pp.rd); | ||
320 | xmove_fd(pp.wr, STDOUT_FILENO); | ||
321 | goto dump; | ||
322 | } | ||
323 | /* parent */ | ||
324 | xchdir(argv[optind++]); | ||
325 | close(pp.wr); | ||
326 | xmove_fd(pp.rd, STDIN_FILENO); | ||
327 | opt &= ~CPIO_OPT_PASSTHROUGH; | ||
328 | opt |= CPIO_OPT_EXTRACT; | ||
329 | goto skip; | ||
330 | } | ||
331 | /* -o */ | ||
286 | if (opt & CPIO_OPT_CREATE) { | 332 | if (opt & CPIO_OPT_CREATE) { |
287 | if (*cpio_fmt != 'n') | 333 | if (*cpio_fmt != 'n') /* we _require_ "-H newc" */ |
288 | bb_show_usage(); | 334 | bb_show_usage(); |
289 | if (opt & CPIO_OPT_FILE) { | 335 | if (opt & CPIO_OPT_FILE) { |
290 | fclose(stdout); | 336 | fclose(stdout); |
@@ -292,13 +338,18 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
292 | /* Paranoia: I don't trust libc that much */ | 338 | /* Paranoia: I don't trust libc that much */ |
293 | xdup2(fileno(stdout), STDOUT_FILENO); | 339 | xdup2(fileno(stdout), STDOUT_FILENO); |
294 | } | 340 | } |
341 | dump: | ||
295 | return cpio_o(); | 342 | return cpio_o(); |
296 | } | 343 | } |
297 | #else | 344 | skip: |
298 | opt = getopt32(argv, "ituvF:dm", &cpio_filename); | ||
299 | #endif | 345 | #endif |
300 | argv += optind; | 346 | argv += optind; |
301 | 347 | ||
348 | archive_handle = init_handle(); | ||
349 | archive_handle->src_fd = STDIN_FILENO; | ||
350 | archive_handle->seek = seek_by_read; | ||
351 | archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; | ||
352 | |||
302 | /* One of either extract or test options must be given */ | 353 | /* One of either extract or test options must be given */ |
303 | if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { | 354 | if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { |
304 | bb_show_usage(); | 355 | bb_show_usage(); |
@@ -306,9 +357,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
306 | 357 | ||
307 | if (opt & CPIO_OPT_TEST) { | 358 | if (opt & CPIO_OPT_TEST) { |
308 | /* if both extract and test options are given, ignore extract option */ | 359 | /* if both extract and test options are given, ignore extract option */ |
309 | if (opt & CPIO_OPT_EXTRACT) { | 360 | opt &= ~CPIO_OPT_EXTRACT; |
310 | opt &= ~CPIO_OPT_EXTRACT; | ||
311 | } | ||
312 | archive_handle->action_header = header_list; | 361 | archive_handle->action_header = header_list; |
313 | } | 362 | } |
314 | if (opt & CPIO_OPT_EXTRACT) { | 363 | if (opt & CPIO_OPT_EXTRACT) { |
diff --git a/findutils/find.c b/findutils/find.c index f2b89746f..df632f219 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -381,9 +381,11 @@ static int FAST_FUNC fileAction(const char *fileName, | |||
381 | { | 381 | { |
382 | int i; | 382 | int i; |
383 | #if ENABLE_FEATURE_FIND_MAXDEPTH | 383 | #if ENABLE_FEATURE_FIND_MAXDEPTH |
384 | int maxdepth = (int)(ptrdiff_t)userData; | 384 | #define minmaxdepth ((int*)userData) |
385 | 385 | ||
386 | if (depth > maxdepth) return SKIP; | 386 | if (depth < minmaxdepth[0]) return TRUE; |
387 | if (depth > minmaxdepth[1]) return SKIP; | ||
388 | #undef minmaxdepth | ||
387 | #endif | 389 | #endif |
388 | 390 | ||
389 | #if ENABLE_FEATURE_FIND_XDEV | 391 | #if ENABLE_FEATURE_FIND_XDEV |
@@ -812,19 +814,21 @@ int find_main(int argc, char **argv) | |||
812 | static const char options[] ALIGN1 = | 814 | static const char options[] ALIGN1 = |
813 | "-follow\0" | 815 | "-follow\0" |
814 | USE_FEATURE_FIND_XDEV( "-xdev\0" ) | 816 | USE_FEATURE_FIND_XDEV( "-xdev\0" ) |
815 | USE_FEATURE_FIND_MAXDEPTH("-maxdepth\0") | 817 | USE_FEATURE_FIND_MAXDEPTH("-mindepth\0""-maxdepth\0") |
816 | ; | 818 | ; |
817 | enum { | 819 | enum { |
818 | OPT_FOLLOW, | 820 | OPT_FOLLOW, |
819 | USE_FEATURE_FIND_XDEV( OPT_XDEV ,) | 821 | USE_FEATURE_FIND_XDEV( OPT_XDEV ,) |
820 | USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,) | 822 | USE_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) |
821 | }; | 823 | }; |
822 | 824 | ||
823 | char *arg; | 825 | char *arg; |
824 | char **argp; | 826 | char **argp; |
825 | int i, firstopt, status = EXIT_SUCCESS; | 827 | int i, firstopt, status = EXIT_SUCCESS; |
826 | #if ENABLE_FEATURE_FIND_MAXDEPTH | 828 | #if ENABLE_FEATURE_FIND_MAXDEPTH |
827 | int maxdepth = INT_MAX; | 829 | int minmaxdepth[2] = { 0, INT_MAX }; |
830 | #else | ||
831 | #define minmaxdepth NULL | ||
828 | #endif | 832 | #endif |
829 | 833 | ||
830 | for (firstopt = 1; firstopt < argc; firstopt++) { | 834 | for (firstopt = 1; firstopt < argc; firstopt++) { |
@@ -875,10 +879,10 @@ USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,) | |||
875 | } | 879 | } |
876 | #endif | 880 | #endif |
877 | #if ENABLE_FEATURE_FIND_MAXDEPTH | 881 | #if ENABLE_FEATURE_FIND_MAXDEPTH |
878 | if (opt == OPT_MAXDEPTH) { | 882 | if (opt == OPT_MINDEPTH || opt == OPT_MINDEPTH + 1) { |
879 | if (!argp[1]) | 883 | if (!argp[1]) |
880 | bb_show_usage(); | 884 | bb_show_usage(); |
881 | maxdepth = xatoi_u(argp[1]); | 885 | minmaxdepth[opt - OPT_MINDEPTH] = xatoi_u(argp[1]); |
882 | argp[0] = (char*)"-a"; | 886 | argp[0] = (char*)"-a"; |
883 | argp[1] = (char*)"-a"; | 887 | argp[1] = (char*)"-a"; |
884 | argp++; | 888 | argp++; |
@@ -895,9 +899,7 @@ USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,) | |||
895 | fileAction, /* file action */ | 899 | fileAction, /* file action */ |
896 | fileAction, /* dir action */ | 900 | fileAction, /* dir action */ |
897 | #if ENABLE_FEATURE_FIND_MAXDEPTH | 901 | #if ENABLE_FEATURE_FIND_MAXDEPTH |
898 | /* double cast suppresses | 902 | minmaxdepth, /* user data */ |
899 | * "cast to ptr from int of different size" */ | ||
900 | (void*)(ptrdiff_t)maxdepth,/* user data */ | ||
901 | #else | 903 | #else |
902 | NULL, /* user data */ | 904 | NULL, /* user data */ |
903 | #endif | 905 | #endif |
diff --git a/findutils/grep.c b/findutils/grep.c index 6a6ddb679..723c3511a 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -28,7 +28,9 @@ | |||
28 | USE_FEATURE_GREP_CONTEXT("A:B:C:") \ | 28 | USE_FEATURE_GREP_CONTEXT("A:B:C:") \ |
29 | USE_FEATURE_GREP_EGREP_ALIAS("E") \ | 29 | USE_FEATURE_GREP_EGREP_ALIAS("E") \ |
30 | USE_DESKTOP("w") \ | 30 | USE_DESKTOP("w") \ |
31 | USE_EXTRA_COMPAT("z") \ | ||
31 | "aI" | 32 | "aI" |
33 | |||
32 | /* ignored: -a "assume all files to be text" */ | 34 | /* ignored: -a "assume all files to be text" */ |
33 | /* ignored: -I "assume binary files have no matches" */ | 35 | /* ignored: -I "assume binary files have no matches" */ |
34 | 36 | ||
@@ -54,6 +56,7 @@ enum { | |||
54 | USE_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */ | 56 | USE_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */ |
55 | USE_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */ | 57 | USE_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */ |
56 | USE_DESKTOP( OPTBIT_w ,) /* whole word match */ | 58 | USE_DESKTOP( OPTBIT_w ,) /* whole word match */ |
59 | USE_EXTRA_COMPAT( OPTBIT_z ,) /* input is NUL terminated */ | ||
57 | OPT_l = 1 << OPTBIT_l, | 60 | OPT_l = 1 << OPTBIT_l, |
58 | OPT_n = 1 << OPTBIT_n, | 61 | OPT_n = 1 << OPTBIT_n, |
59 | OPT_q = 1 << OPTBIT_q, | 62 | OPT_q = 1 << OPTBIT_q, |
@@ -75,6 +78,7 @@ enum { | |||
75 | OPT_C = USE_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0, | 78 | OPT_C = USE_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0, |
76 | OPT_E = USE_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0, | 79 | OPT_E = USE_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0, |
77 | OPT_w = USE_DESKTOP( (1 << OPTBIT_w)) + 0, | 80 | OPT_w = USE_DESKTOP( (1 << OPTBIT_w)) + 0, |
81 | OPT_z = USE_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0, | ||
78 | }; | 82 | }; |
79 | 83 | ||
80 | #define PRINT_FILES_WITH_MATCHES (option_mask32 & OPT_l) | 84 | #define PRINT_FILES_WITH_MATCHES (option_mask32 & OPT_l) |
@@ -84,6 +88,7 @@ enum { | |||
84 | #define PRINT_MATCH_COUNTS (option_mask32 & OPT_c) | 88 | #define PRINT_MATCH_COUNTS (option_mask32 & OPT_c) |
85 | #define FGREP_FLAG (option_mask32 & OPT_F) | 89 | #define FGREP_FLAG (option_mask32 & OPT_F) |
86 | #define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L) | 90 | #define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L) |
91 | #define NUL_DELIMITED (option_mask32 & OPT_z) | ||
87 | 92 | ||
88 | struct globals { | 93 | struct globals { |
89 | int max_matches; | 94 | int max_matches; |
@@ -186,7 +191,7 @@ static void print_line(const char *line, size_t line_len, int linenum, char deco | |||
186 | puts(line); | 191 | puts(line); |
187 | #else | 192 | #else |
188 | fwrite(line, 1, line_len, stdout); | 193 | fwrite(line, 1, line_len, stdout); |
189 | putchar('\n'); | 194 | putchar(NUL_DELIMITED ? '\0' : '\n'); |
190 | #endif | 195 | #endif |
191 | } | 196 | } |
192 | } | 197 | } |
@@ -197,12 +202,13 @@ static ssize_t FAST_FUNC bb_getline(char **line_ptr, size_t *line_alloc_len, FIL | |||
197 | { | 202 | { |
198 | ssize_t res_sz; | 203 | ssize_t res_sz; |
199 | char *line; | 204 | char *line; |
205 | int delim = (NUL_DELIMITED ? '\0' : '\n'); | ||
200 | 206 | ||
201 | res_sz = getline(line_ptr, line_alloc_len, file); | 207 | res_sz = getdelim(line_ptr, line_alloc_len, delim, file); |
202 | line = *line_ptr; | 208 | line = *line_ptr; |
203 | 209 | ||
204 | if (res_sz > 0) { | 210 | if (res_sz > 0) { |
205 | if (line[res_sz - 1] == '\n') | 211 | if (line[res_sz - 1] == delim) |
206 | line[--res_sz] = '\0'; | 212 | line[--res_sz] = '\0'; |
207 | } else { | 213 | } else { |
208 | free(line); /* uclibc allocates a buffer even on EOF. WTF? */ | 214 | free(line); /* uclibc allocates a buffer even on EOF. WTF? */ |
@@ -407,8 +413,11 @@ static int grep_file(FILE *file) | |||
407 | #endif | 413 | #endif |
408 | /* Did we print all context after last requested match? */ | 414 | /* Did we print all context after last requested match? */ |
409 | if ((option_mask32 & OPT_m) | 415 | if ((option_mask32 & OPT_m) |
410 | && !print_n_lines_after && nmatches == max_matches) | 416 | && !print_n_lines_after |
417 | && nmatches == max_matches | ||
418 | ) { | ||
411 | break; | 419 | break; |
420 | } | ||
412 | } /* while (read line) */ | 421 | } /* while (read line) */ |
413 | 422 | ||
414 | /* special-case file post-processing for options where we don't print line | 423 | /* special-case file post-processing for options where we don't print line |
diff --git a/include/libbb.h b/include/libbb.h index 8ea493b18..a2042fe5c 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -797,9 +797,9 @@ int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char ** | |||
797 | * Both of the above will redirect fd 0,1,2 to /dev/null and drop ctty | 797 | * Both of the above will redirect fd 0,1,2 to /dev/null and drop ctty |
798 | * (will do setsid()). | 798 | * (will do setsid()). |
799 | * | 799 | * |
800 | * forkexit_or_rexec(argv) = bare-bones "fork + parent exits" on MMU, | 800 | * fork_or_rexec(argv) = bare-bones "fork" on MMU, |
801 | * "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid(). | 801 | * "vfork + re-exec ourself" on NOMMU. No fd redirection, no setsid(). |
802 | * Currently used for setsid only. On MMU ignores argv. | 802 | * On MMU ignores argv. |
803 | * | 803 | * |
804 | * Helper for network daemons in foreground mode: | 804 | * Helper for network daemons in foreground mode: |
805 | * | 805 | * |
@@ -813,14 +813,14 @@ enum { | |||
813 | DAEMON_ONLY_SANITIZE = 8, /* internal use */ | 813 | DAEMON_ONLY_SANITIZE = 8, /* internal use */ |
814 | }; | 814 | }; |
815 | #if BB_MMU | 815 | #if BB_MMU |
816 | void forkexit_or_rexec(void) FAST_FUNC; | 816 | pid_t fork_or_rexec(void) FAST_FUNC; |
817 | enum { re_execed = 0 }; | 817 | enum { re_execed = 0 }; |
818 | # define forkexit_or_rexec(argv) forkexit_or_rexec() | 818 | # define fork_or_rexec(argv) fork_or_rexec() |
819 | # define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags) | 819 | # define bb_daemonize_or_rexec(flags, argv) bb_daemonize_or_rexec(flags) |
820 | # define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus) | 820 | # define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus) |
821 | #else | 821 | #else |
822 | void re_exec(char **argv) NORETURN FAST_FUNC; | 822 | void re_exec(char **argv) NORETURN FAST_FUNC; |
823 | void forkexit_or_rexec(char **argv) FAST_FUNC; | 823 | pid_t fork_or_rexec(char **argv) FAST_FUNC; |
824 | extern bool re_execed; | 824 | extern bool re_execed; |
825 | int BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC; | 825 | int BUG_fork_is_unavailable_on_nommu(void) FAST_FUNC; |
826 | int BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC; | 826 | int BUG_daemon_is_unavailable_on_nommu(void) FAST_FUNC; |
diff --git a/include/usage.h b/include/usage.h index e78754315..2b5d34ea6 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -531,24 +531,29 @@ | |||
531 | "\n -l,-s Create (sym)links" \ | 531 | "\n -l,-s Create (sym)links" \ |
532 | 532 | ||
533 | #define cpio_trivial_usage \ | 533 | #define cpio_trivial_usage \ |
534 | "-[dim" USE_FEATURE_CPIO_O("o") "tuv][F cpiofile]" \ | 534 | "-[ti" USE_FEATURE_CPIO_O("o") USE_FEATURE_CPIO_P("p") "dmvu] [-F FILE]" \ |
535 | USE_FEATURE_CPIO_O( "[H newc]" ) | 535 | USE_FEATURE_CPIO_O( " [-H newc]" ) |
536 | #define cpio_full_usage "\n\n" \ | 536 | #define cpio_full_usage "\n\n" \ |
537 | "Extract or list files from a cpio archive" \ | 537 | "Extract or list files from a cpio archive" \ |
538 | USE_FEATURE_CPIO_O( ", or create a cpio archive" ) \ | 538 | USE_FEATURE_CPIO_O( ", or create a cpio archive" ) \ |
539 | "\n" \ | 539 | "\nMain operation mode:" \ |
540 | "Main operation mode:" \ | 540 | "\n -t List" \ |
541 | "\n d Make leading directories" \ | 541 | "\n -i Extract" \ |
542 | "\n i Extract" \ | ||
543 | "\n m Preserve mtime" \ | ||
544 | USE_FEATURE_CPIO_O( \ | 542 | USE_FEATURE_CPIO_O( \ |
545 | "\n o Create" \ | 543 | "\n -o Create" \ |
546 | "\n H newc Define format" \ | 544 | ) \ |
545 | USE_FEATURE_CPIO_P( \ | ||
546 | "\n -p Passthrough" \ | ||
547 | ) \ | ||
548 | "\nOptions:" \ | ||
549 | "\n -d Make leading directories" \ | ||
550 | "\n -m Preserve mtime" \ | ||
551 | "\n -v Verbose" \ | ||
552 | "\n -u Overwrite" \ | ||
553 | "\n -F Input file" \ | ||
554 | USE_FEATURE_CPIO_O( \ | ||
555 | "\n -H Define format" \ | ||
547 | ) \ | 556 | ) \ |
548 | "\n t List" \ | ||
549 | "\n v Verbose" \ | ||
550 | "\n u Unconditional overwrite" \ | ||
551 | "\n F Input from file" \ | ||
552 | 557 | ||
553 | #define crond_trivial_usage \ | 558 | #define crond_trivial_usage \ |
554 | "-fbS -l N " USE_FEATURE_CROND_D("-d N ") "-L LOGFILE -c DIR" | 559 | "-fbS -l N " USE_FEATURE_CROND_D("-d N ") "-L LOGFILE -c DIR" |
@@ -1167,6 +1172,7 @@ | |||
1167 | USE_FEATURE_FIND_MAXDEPTH( \ | 1172 | USE_FEATURE_FIND_MAXDEPTH( \ |
1168 | "\n -maxdepth N Descend at most N levels. -maxdepth 0 applies" \ | 1173 | "\n -maxdepth N Descend at most N levels. -maxdepth 0 applies" \ |
1169 | "\n tests/actions to command line arguments only") \ | 1174 | "\n tests/actions to command line arguments only") \ |
1175 | "\n -mindepth N Do not act on first N levels" \ | ||
1170 | "\n -name PATTERN File name (w/o directory name) matches PATTERN" \ | 1176 | "\n -name PATTERN File name (w/o directory name) matches PATTERN" \ |
1171 | "\n -iname PATTERN Case insensitive -name" \ | 1177 | "\n -iname PATTERN Case insensitive -name" \ |
1172 | USE_FEATURE_FIND_PATH( \ | 1178 | USE_FEATURE_FIND_PATH( \ |
@@ -1425,6 +1431,7 @@ | |||
1425 | "eF" \ | 1431 | "eF" \ |
1426 | USE_FEATURE_GREP_EGREP_ALIAS("E") \ | 1432 | USE_FEATURE_GREP_EGREP_ALIAS("E") \ |
1427 | USE_FEATURE_GREP_CONTEXT("ABC") \ | 1433 | USE_FEATURE_GREP_CONTEXT("ABC") \ |
1434 | USE_EXTRA_COMPAT("z") \ | ||
1428 | "] PATTERN [FILEs...]" | 1435 | "] PATTERN [FILEs...]" |
1429 | #define grep_full_usage "\n\n" \ | 1436 | #define grep_full_usage "\n\n" \ |
1430 | "Search for PATTERN in each FILE or standard input\n" \ | 1437 | "Search for PATTERN in each FILE or standard input\n" \ |
@@ -1453,6 +1460,8 @@ | |||
1453 | "\n -A Print NUM lines of trailing context" \ | 1460 | "\n -A Print NUM lines of trailing context" \ |
1454 | "\n -B Print NUM lines of leading context" \ | 1461 | "\n -B Print NUM lines of leading context" \ |
1455 | "\n -C Print NUM lines of output context") \ | 1462 | "\n -C Print NUM lines of output context") \ |
1463 | USE_EXTRA_COMPAT( \ | ||
1464 | "\n -z Input is NUL terminated") \ | ||
1456 | 1465 | ||
1457 | #define grep_example_usage \ | 1466 | #define grep_example_usage \ |
1458 | "$ grep root /etc/passwd\n" \ | 1467 | "$ grep root /etc/passwd\n" \ |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 50dc3affe..f64239a96 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -251,35 +251,33 @@ void FAST_FUNC re_exec(char **argv) | |||
251 | bb_perror_msg_and_die("exec %s", bb_busybox_exec_path); | 251 | bb_perror_msg_and_die("exec %s", bb_busybox_exec_path); |
252 | } | 252 | } |
253 | 253 | ||
254 | void FAST_FUNC forkexit_or_rexec(char **argv) | 254 | pid_t FAST_FUNC fork_or_rexec(char **argv) |
255 | { | 255 | { |
256 | pid_t pid; | 256 | pid_t pid; |
257 | /* Maybe we are already re-execed and come here again? */ | 257 | /* Maybe we are already re-execed and come here again? */ |
258 | if (re_execed) | 258 | if (re_execed) |
259 | return; | 259 | return 0; /* child */ |
260 | 260 | ||
261 | pid = vfork(); | 261 | pid = vfork(); |
262 | if (pid < 0) /* wtf? */ | 262 | if (pid < 0) /* wtf? */ |
263 | bb_perror_msg_and_die("vfork"); | 263 | bb_perror_msg_and_die("vfork"); |
264 | if (pid) /* parent */ | 264 | if (pid) /* parent */ |
265 | exit(EXIT_SUCCESS); | 265 | return pid; |
266 | /* child - re-exec ourself */ | 266 | /* child - re-exec ourself */ |
267 | re_exec(argv); | 267 | re_exec(argv); |
268 | } | 268 | } |
269 | #else | 269 | #else |
270 | /* Dance around (void)...*/ | 270 | /* Dance around (void)...*/ |
271 | #undef forkexit_or_rexec | 271 | #undef fork_or_rexec |
272 | void FAST_FUNC forkexit_or_rexec(void) | 272 | pid_t FAST_FUNC fork_or_rexec(void) |
273 | { | 273 | { |
274 | pid_t pid; | 274 | pid_t pid; |
275 | pid = fork(); | 275 | pid = fork(); |
276 | if (pid < 0) /* wtf? */ | 276 | if (pid < 0) /* wtf? */ |
277 | bb_perror_msg_and_die("fork"); | 277 | bb_perror_msg_and_die("fork"); |
278 | if (pid) /* parent */ | 278 | return pid; |
279 | exit(EXIT_SUCCESS); | ||
280 | /* child */ | ||
281 | } | 279 | } |
282 | #define forkexit_or_rexec(argv) forkexit_or_rexec() | 280 | #define fork_or_rexec(argv) fork_or_rexec() |
283 | #endif | 281 | #endif |
284 | 282 | ||
285 | /* Due to a #define in libbb.h on MMU systems we actually have 1 argument - | 283 | /* Due to a #define in libbb.h on MMU systems we actually have 1 argument - |
@@ -310,7 +308,8 @@ void FAST_FUNC bb_daemonize_or_rexec(int flags, char **argv) | |||
310 | fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ | 308 | fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ |
311 | 309 | ||
312 | if (!(flags & DAEMON_ONLY_SANITIZE)) { | 310 | if (!(flags & DAEMON_ONLY_SANITIZE)) { |
313 | forkexit_or_rexec(argv); | 311 | if (fork_or_rexec(argv)) |
312 | exit(EXIT_SUCCESS); /* parent */ | ||
314 | /* if daemonizing, make sure we detach from stdio & ctty */ | 313 | /* if daemonizing, make sure we detach from stdio & ctty */ |
315 | setsid(); | 314 | setsid(); |
316 | dup2(fd, 0); | 315 | dup2(fd, 0); |
diff --git a/miscutils/setsid.c b/miscutils/setsid.c index 127adf6f2..d7de1f149 100644 --- a/miscutils/setsid.c +++ b/miscutils/setsid.c | |||
@@ -26,7 +26,8 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) | |||
26 | * Otherwise our PID serves as PGID of some existing process group | 26 | * Otherwise our PID serves as PGID of some existing process group |
27 | * and cannot be used as PGID of a new process group. */ | 27 | * and cannot be used as PGID of a new process group. */ |
28 | if (getpgrp() == getpid()) | 28 | if (getpgrp() == getpid()) |
29 | forkexit_or_rexec(argv); | 29 | if (fork_or_rexec(argv)) |
30 | exit(EXIT_SUCCESS); /* parent */ | ||
30 | 31 | ||
31 | setsid(); /* no error possible */ | 32 | setsid(); /* no error possible */ |
32 | 33 | ||
diff --git a/scripts/defconfig b/scripts/defconfig index 6bf1a4a28..166989bba 100644 --- a/scripts/defconfig +++ b/scripts/defconfig | |||
@@ -112,6 +112,7 @@ CONFIG_BUNZIP2=y | |||
112 | CONFIG_BZIP2=y | 112 | CONFIG_BZIP2=y |
113 | CONFIG_CPIO=y | 113 | CONFIG_CPIO=y |
114 | CONFIG_FEATURE_CPIO_O=y | 114 | CONFIG_FEATURE_CPIO_O=y |
115 | CONFIG_FEATURE_CPIO_P=y | ||
115 | # CONFIG_DPKG is not set | 116 | # CONFIG_DPKG is not set |
116 | # CONFIG_DPKG_DEB is not set | 117 | # CONFIG_DPKG_DEB is not set |
117 | # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set | 118 | # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set |