diff options
-rw-r--r-- | findutils/find.c | 39 | ||||
-rwxr-xr-x | testsuite/find.tests | 6 |
2 files changed, 42 insertions, 3 deletions
diff --git a/findutils/find.c b/findutils/find.c index bb6ad31e5..136ca0d21 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -180,6 +180,13 @@ | |||
180 | //config: Without this option, -exec + is a synonym for -exec ; | 180 | //config: Without this option, -exec + is a synonym for -exec ; |
181 | //config: (IOW: it works correctly, but without expected speedup) | 181 | //config: (IOW: it works correctly, but without expected speedup) |
182 | //config: | 182 | //config: |
183 | //config:config FEATURE_FIND_EXEC_OK | ||
184 | //config: bool "Enable -ok: execute confirmed commands" | ||
185 | //config: default y | ||
186 | //config: depends on FEATURE_FIND_EXEC | ||
187 | //config: help | ||
188 | //config: Support the 'find -ok' option which prompts before executing. | ||
189 | //config: | ||
183 | //config:config FEATURE_FIND_USER | 190 | //config:config FEATURE_FIND_USER |
184 | //config: bool "Enable -user: username/uid matching" | 191 | //config: bool "Enable -user: username/uid matching" |
185 | //config: default y | 192 | //config: default y |
@@ -395,6 +402,9 @@ | |||
395 | //usage: IF_FEATURE_FIND_EXEC_PLUS( | 402 | //usage: IF_FEATURE_FIND_EXEC_PLUS( |
396 | //usage: "\n -exec CMD ARG + Run CMD with {} replaced by list of file names" | 403 | //usage: "\n -exec CMD ARG + Run CMD with {} replaced by list of file names" |
397 | //usage: ) | 404 | //usage: ) |
405 | //usage: IF_FEATURE_FIND_EXEC_OK( | ||
406 | //usage: "\n -ok CMD ARG ; Prompt and run CMD with {} replaced" | ||
407 | //usage: ) | ||
398 | //usage: IF_FEATURE_FIND_DELETE( | 408 | //usage: IF_FEATURE_FIND_DELETE( |
399 | //usage: "\n -delete Delete current file/directory. Turns on -depth option" | 409 | //usage: "\n -delete Delete current file/directory. Turns on -depth option" |
400 | //usage: ) | 410 | //usage: ) |
@@ -467,6 +477,9 @@ IF_FEATURE_FIND_EXEC( ACTS(exec, | |||
467 | char **exec_argv; /* -exec ARGS */ | 477 | char **exec_argv; /* -exec ARGS */ |
468 | unsigned *subst_count; | 478 | unsigned *subst_count; |
469 | int exec_argc; /* count of ARGS */ | 479 | int exec_argc; /* count of ARGS */ |
480 | IF_FEATURE_FIND_EXEC_OK( | ||
481 | int ok; /* -ok */ | ||
482 | ) | ||
470 | IF_FEATURE_FIND_EXEC_PLUS( | 483 | IF_FEATURE_FIND_EXEC_PLUS( |
471 | /* | 484 | /* |
472 | * filelist is NULL if "exec ;" | 485 | * filelist is NULL if "exec ;" |
@@ -802,10 +815,24 @@ static int do_exec(action_exec *ap, const char *fileName) | |||
802 | } | 815 | } |
803 | # endif | 816 | # endif |
804 | 817 | ||
818 | # if ENABLE_FEATURE_FIND_EXEC_OK | ||
819 | if (ap->ok) { | ||
820 | for (i = 0; argv[i]; i++) | ||
821 | fprintf(stderr, "%s ", argv[i]); | ||
822 | fprintf(stderr, "?"); | ||
823 | if (!bb_ask_y_confirmation()) { | ||
824 | rc = 1; /* "false" */ | ||
825 | goto not_ok; | ||
826 | } | ||
827 | } | ||
828 | # endif | ||
805 | rc = spawn_and_wait(argv); | 829 | rc = spawn_and_wait(argv); |
806 | if (rc < 0) | 830 | if (rc < 0) |
807 | bb_simple_perror_msg(argv[0]); | 831 | bb_simple_perror_msg(argv[0]); |
808 | 832 | ||
833 | # if ENABLE_FEATURE_FIND_EXEC_OK | ||
834 | not_ok: | ||
835 | # endif | ||
809 | i = 0; | 836 | i = 0; |
810 | while (argv[i]) | 837 | while (argv[i]) |
811 | free(argv[i++]); | 838 | free(argv[i++]); |
@@ -1120,6 +1147,7 @@ static action*** parse_params(char **argv) | |||
1120 | IF_FEATURE_FIND_DELETE( PARM_delete ,) | 1147 | IF_FEATURE_FIND_DELETE( PARM_delete ,) |
1121 | IF_FEATURE_FIND_EMPTY( PARM_empty ,) | 1148 | IF_FEATURE_FIND_EMPTY( PARM_empty ,) |
1122 | IF_FEATURE_FIND_EXEC( PARM_exec ,) | 1149 | IF_FEATURE_FIND_EXEC( PARM_exec ,) |
1150 | IF_FEATURE_FIND_EXEC_OK(PARM_ok ,) | ||
1123 | IF_FEATURE_FIND_EXECUTABLE(PARM_executable,) | 1151 | IF_FEATURE_FIND_EXECUTABLE(PARM_executable,) |
1124 | IF_FEATURE_FIND_PAREN( PARM_char_brace,) | 1152 | IF_FEATURE_FIND_PAREN( PARM_char_brace,) |
1125 | /* All options/actions starting from here require argument */ | 1153 | /* All options/actions starting from here require argument */ |
@@ -1171,6 +1199,7 @@ static action*** parse_params(char **argv) | |||
1171 | IF_FEATURE_FIND_DELETE( "-delete\0" ) | 1199 | IF_FEATURE_FIND_DELETE( "-delete\0" ) |
1172 | IF_FEATURE_FIND_EMPTY( "-empty\0" ) | 1200 | IF_FEATURE_FIND_EMPTY( "-empty\0" ) |
1173 | IF_FEATURE_FIND_EXEC( "-exec\0" ) | 1201 | IF_FEATURE_FIND_EXEC( "-exec\0" ) |
1202 | IF_FEATURE_FIND_EXEC_OK("-ok\0" ) | ||
1174 | IF_FEATURE_FIND_EXECUTABLE("-executable\0") | 1203 | IF_FEATURE_FIND_EXECUTABLE("-executable\0") |
1175 | IF_FEATURE_FIND_PAREN( "(\0" ) | 1204 | IF_FEATURE_FIND_PAREN( "(\0" ) |
1176 | /* All options/actions starting from here require argument */ | 1205 | /* All options/actions starting from here require argument */ |
@@ -1351,23 +1380,27 @@ static action*** parse_params(char **argv) | |||
1351 | } | 1380 | } |
1352 | #endif | 1381 | #endif |
1353 | #if ENABLE_FEATURE_FIND_EXEC | 1382 | #if ENABLE_FEATURE_FIND_EXEC |
1354 | else if (parm == PARM_exec) { | 1383 | else if (parm == PARM_exec IF_FEATURE_FIND_EXEC_OK(|| parm == PARM_ok)) { |
1355 | int i; | 1384 | int i; |
1356 | action_exec *ap; | 1385 | action_exec *ap; |
1357 | IF_FEATURE_FIND_EXEC_PLUS(int all_subst = 0;) | 1386 | IF_FEATURE_FIND_EXEC_PLUS(int all_subst = 0;) |
1358 | dbg("%d", __LINE__); | 1387 | dbg("%d", __LINE__); |
1359 | G.need_print = 0; | 1388 | G.need_print = 0; |
1360 | ap = ALLOC_ACTION(exec); | 1389 | ap = ALLOC_ACTION(exec); |
1390 | IF_FEATURE_FIND_EXEC_OK(ap->ok = (parm == PARM_ok);) | ||
1361 | ap->exec_argv = ++argv; /* first arg after -exec */ | 1391 | ap->exec_argv = ++argv; /* first arg after -exec */ |
1362 | /*ap->exec_argc = 0; - ALLOC_ACTION did it */ | 1392 | /*ap->exec_argc = 0; - ALLOC_ACTION did it */ |
1363 | while (1) { | 1393 | while (1) { |
1364 | if (!*argv) /* did not see ';' or '+' until end */ | 1394 | if (!*argv) /* did not see ';' or '+' until end */ |
1365 | bb_error_msg_and_die(bb_msg_requires_arg, "-exec"); | 1395 | bb_error_msg_and_die(bb_msg_requires_arg, arg); |
1366 | // find -exec echo Foo ">{}<" ";" | 1396 | // find -exec echo Foo ">{}<" ";" |
1367 | // executes "echo Foo >FILENAME<", | 1397 | // executes "echo Foo >FILENAME<", |
1368 | // find -exec echo Foo ">{}<" "+" | 1398 | // find -exec echo Foo ">{}<" "+" |
1369 | // executes "echo Foo FILENAME1 FILENAME2 FILENAME3...". | 1399 | // executes "echo Foo FILENAME1 FILENAME2 FILENAME3...". |
1370 | if ((argv[0][0] == ';' || argv[0][0] == '+') | 1400 | if ((argv[0][0] == ';' |
1401 | || (argv[0][0] == '+' IF_FEATURE_FIND_EXEC_OK(&& parm != PARM_ok)) | ||
1402 | /* -ok CMD + syntax is not accepted, only with ';' */ | ||
1403 | ) | ||
1371 | && argv[0][1] == '\0' | 1404 | && argv[0][1] == '\0' |
1372 | ) { | 1405 | ) { |
1373 | # if ENABLE_FEATURE_FIND_EXEC_PLUS | 1406 | # if ENABLE_FEATURE_FIND_EXEC_PLUS |
diff --git a/testsuite/find.tests b/testsuite/find.tests index 138236c81..d763ca6f2 100755 --- a/testsuite/find.tests +++ b/testsuite/find.tests | |||
@@ -28,6 +28,12 @@ testing "find -exec exitcode 2" \ | |||
28 | "0\n" \ | 28 | "0\n" \ |
29 | "" "" | 29 | "" "" |
30 | SKIP= | 30 | SKIP= |
31 | optional FEATURE_FIND_EXEC_OK | ||
32 | testing "find -ok" \ | ||
33 | "cd find.tempdir && find testfile -ok true {} ';' 2>&1; echo \$?" \ | ||
34 | "true testfile ?0\n" \ | ||
35 | "" "y" | ||
36 | SKIP= | ||
31 | # Surprisingly, "-exec false ;" results in exitcode 0! "-exec false +" is different!!! | 37 | # Surprisingly, "-exec false ;" results in exitcode 0! "-exec false +" is different!!! |
32 | optional FEATURE_FIND_EXEC | 38 | optional FEATURE_FIND_EXEC |
33 | testing "find -exec exitcode 3" \ | 39 | testing "find -exec exitcode 3" \ |