aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-20 22:17:13 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-20 22:17:13 +0000
commit83518d18a34a3ddfcaac1739930d8469f5bc2442 (patch)
tree2af665365a69f2689288cc13bb65efbb59e7d520
parent0b28103cc774eb1ee62362cf61d52c32d44ec2cf (diff)
downloadbusybox-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_nommu1
-rw-r--r--archival/Config.in7
-rw-r--r--archival/cpio.c81
-rw-r--r--findutils/find.c22
-rw-r--r--findutils/grep.c17
-rw-r--r--include/libbb.h10
-rw-r--r--include/usage.h35
-rw-r--r--libbb/vfork_daemon_rexec.c19
-rw-r--r--miscutils/setsid.c3
-rw-r--r--scripts/defconfig1
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
110CONFIG_BZIP2=y 110CONFIG_BZIP2=y
111CONFIG_CPIO=y 111CONFIG_CPIO=y
112CONFIG_FEATURE_CPIO_O=y 112CONFIG_FEATURE_CPIO_O=y
113CONFIG_FEATURE_CPIO_P=y
113CONFIG_DPKG=y 114CONFIG_DPKG=y
114CONFIG_DPKG_DEB=y 115CONFIG_DPKG_DEB=y
115CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY=y 116CONFIG_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
113config 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
113config DPKG 120config 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"
814USE_FEATURE_FIND_XDEV( "-xdev\0" ) 816USE_FEATURE_FIND_XDEV( "-xdev\0" )
815USE_FEATURE_FIND_MAXDEPTH("-maxdepth\0") 817USE_FEATURE_FIND_MAXDEPTH("-mindepth\0""-maxdepth\0")
816 ; 818 ;
817 enum { 819 enum {
818 OPT_FOLLOW, 820 OPT_FOLLOW,
819USE_FEATURE_FIND_XDEV( OPT_XDEV ,) 821USE_FEATURE_FIND_XDEV( OPT_XDEV ,)
820USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,) 822USE_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
88struct globals { 93struct 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
254void FAST_FUNC forkexit_or_rexec(char **argv) 254pid_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
272void FAST_FUNC forkexit_or_rexec(void) 272pid_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
112CONFIG_BZIP2=y 112CONFIG_BZIP2=y
113CONFIG_CPIO=y 113CONFIG_CPIO=y
114CONFIG_FEATURE_CPIO_O=y 114CONFIG_FEATURE_CPIO_O=y
115CONFIG_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