diff options
author | David Leonard <d+busybox@adaptive-enterprises.com> | 2023-01-29 12:07:08 +1000 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-03-28 18:08:02 +0200 |
commit | d8a33603801476dd870ea66c36cf7c64d852d674 (patch) | |
tree | 9f4f45ee78d973bc10015b8e452e23ea88bcea1c | |
parent | 2d4a3d9e6c1493a9520b907e07a41aca90cdfd94 (diff) | |
download | busybox-w32-d8a33603801476dd870ea66c36cf7c64d852d674.tar.gz busybox-w32-d8a33603801476dd870ea66c36cf7c64d852d674.tar.bz2 busybox-w32-d8a33603801476dd870ea66c36cf7c64d852d674.zip |
find: implement -ok
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
-ok utility_name [argument ...] ;
The -ok primary shall be equivalent to -exec, except that the use
of a <plus-sign> to punctuate the end of the primary expression
need not be supported, and find shall request affirmation of the
invocation of utility_name using the current file as an argument
by writing to standard error as described in the STDERR section. If
the response on standard input is affirmative, the utility shall be
invoked. Otherwise, the command shall not be invoked and the value
of the -ok operand shall be false.
function old new delta
do_exec 438 517 +79
parse_params 1833 1845 +12
static.params 288 292 +4
.rodata 100771 100775 +4
packed_usage 34543 34541 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/1 up/down: 99/-2) Total: 97 bytes
Signed-off-by: David Leonard <d+busybox@adaptive-enterprises.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-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" \ |