diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2022-12-22 10:38:08 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2022-12-22 10:38:08 +0100 |
commit | c4d296aa7c71d3dd812497c02c976124b66a0ff9 (patch) | |
tree | f923bc14db2b88b2b85a3f0dae05ad71af1cf140 | |
parent | 02ca56564628de474f7a59dbdf3a1a8711b5bee7 (diff) | |
download | busybox-w32-c4d296aa7c71d3dd812497c02c976124b66a0ff9.tar.gz busybox-w32-c4d296aa7c71d3dd812497c02c976124b66a0ff9.tar.bz2 busybox-w32-c4d296aa7c71d3dd812497c02c976124b66a0ff9.zip |
xargs: implement -o, closes 15146
function old new delta
.rodata 105225 105259 +34
d6_listen_socket 150 180 +30
packed_usage 34512 34532 +20
d6_read_interface 595 581 -14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 84/-14) Total: 70 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | findutils/xargs.c | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c index 90ff05986..067ef41c5 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -111,6 +111,8 @@ struct globals { | |||
111 | #endif | 111 | #endif |
112 | const char *eof_str; | 112 | const char *eof_str; |
113 | int idx; | 113 | int idx; |
114 | int fd_tty; | ||
115 | int fd_stdin; | ||
114 | #if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL | 116 | #if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL |
115 | int running_procs; | 117 | int running_procs; |
116 | int max_procs; | 118 | int max_procs; |
@@ -140,6 +142,42 @@ struct globals { | |||
140 | IF_FEATURE_XARGS_SUPPORT_QUOTES(G.process_stdin__q = '\0';) \ | 142 | IF_FEATURE_XARGS_SUPPORT_QUOTES(G.process_stdin__q = '\0';) \ |
141 | } while (0) | 143 | } while (0) |
142 | 144 | ||
145 | /* Correct regardless of combination of CONFIG_xxx */ | ||
146 | enum { | ||
147 | OPTBIT_VERBOSE = 0, | ||
148 | OPTBIT_NO_EMPTY, | ||
149 | OPTBIT_UPTO_NUMBER, | ||
150 | OPTBIT_UPTO_SIZE, | ||
151 | OPTBIT_EOF_STRING, | ||
152 | OPTBIT_EOF_STRING1, | ||
153 | OPTBIT_STDIN_TTY, | ||
154 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) | ||
155 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) | ||
156 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) | ||
157 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR ,) | ||
158 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR1 ,) | ||
159 | |||
160 | OPT_VERBOSE = 1 << OPTBIT_VERBOSE , | ||
161 | OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , | ||
162 | OPT_UPTO_NUMBER = 1 << OPTBIT_UPTO_NUMBER, | ||
163 | OPT_UPTO_SIZE = 1 << OPTBIT_UPTO_SIZE , | ||
164 | OPT_EOF_STRING = 1 << OPTBIT_EOF_STRING , /* GNU: -e[<param>] */ | ||
165 | OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E<param> */ | ||
166 | OPT_STDIN_TTY = 1 << OPTBIT_STDIN_TTY, | ||
167 | OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, | ||
168 | OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, | ||
169 | OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, | ||
170 | OPT_REPLSTR = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR )) + 0, | ||
171 | OPT_REPLSTR1 = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR1 )) + 0, | ||
172 | }; | ||
173 | #define OPTION_STR "+trn:s:e::E:o" \ | ||
174 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ | ||
175 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ | ||
176 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ | ||
177 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") \ | ||
178 | IF_FEATURE_XARGS_SUPPORT_PARALLEL( "P:+") \ | ||
179 | IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( "a:") | ||
180 | |||
143 | 181 | ||
144 | /* | 182 | /* |
145 | * Returns 0 if xargs should continue (but may set G.xargs_exitcode to 123). | 183 | * Returns 0 if xargs should continue (but may set G.xargs_exitcode to 123). |
@@ -151,6 +189,9 @@ static int xargs_exec(void) | |||
151 | { | 189 | { |
152 | int status; | 190 | int status; |
153 | 191 | ||
192 | if (option_mask32 & OPT_STDIN_TTY) | ||
193 | xdup2(G.fd_tty, STDIN_FILENO); | ||
194 | |||
154 | #if !ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL | 195 | #if !ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL |
155 | status = spawn_and_wait(G.args); | 196 | status = spawn_and_wait(G.args); |
156 | #else | 197 | #else |
@@ -237,6 +278,8 @@ static int xargs_exec(void) | |||
237 | ret: | 278 | ret: |
238 | if (status != 0) | 279 | if (status != 0) |
239 | G.xargs_exitcode = status; | 280 | G.xargs_exitcode = status; |
281 | if (option_mask32 & OPT_STDIN_TTY) | ||
282 | xdup2(G.fd_stdin, STDIN_FILENO); | ||
240 | return status; | 283 | return status; |
241 | } | 284 | } |
242 | 285 | ||
@@ -542,6 +585,7 @@ static int xargs_ask_confirmation(void) | |||
542 | //usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( | 585 | //usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( |
543 | //usage: "\n -a FILE Read from FILE instead of stdin" | 586 | //usage: "\n -a FILE Read from FILE instead of stdin" |
544 | //usage: ) | 587 | //usage: ) |
588 | //usage: "\n -o Reopen stdin as /dev/tty" | ||
545 | //usage: "\n -r Don't run command if input is empty" | 589 | //usage: "\n -r Don't run command if input is empty" |
546 | //usage: "\n -t Print the command on stderr before execution" | 590 | //usage: "\n -t Print the command on stderr before execution" |
547 | //usage: IF_FEATURE_XARGS_SUPPORT_CONFIRMATION( | 591 | //usage: IF_FEATURE_XARGS_SUPPORT_CONFIRMATION( |
@@ -563,40 +607,6 @@ static int xargs_ask_confirmation(void) | |||
563 | //usage: "$ ls | xargs gzip\n" | 607 | //usage: "$ ls | xargs gzip\n" |
564 | //usage: "$ find . -name '*.c' -print | xargs rm\n" | 608 | //usage: "$ find . -name '*.c' -print | xargs rm\n" |
565 | 609 | ||
566 | /* Correct regardless of combination of CONFIG_xxx */ | ||
567 | enum { | ||
568 | OPTBIT_VERBOSE = 0, | ||
569 | OPTBIT_NO_EMPTY, | ||
570 | OPTBIT_UPTO_NUMBER, | ||
571 | OPTBIT_UPTO_SIZE, | ||
572 | OPTBIT_EOF_STRING, | ||
573 | OPTBIT_EOF_STRING1, | ||
574 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) | ||
575 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) | ||
576 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) | ||
577 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR ,) | ||
578 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR1 ,) | ||
579 | |||
580 | OPT_VERBOSE = 1 << OPTBIT_VERBOSE , | ||
581 | OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , | ||
582 | OPT_UPTO_NUMBER = 1 << OPTBIT_UPTO_NUMBER, | ||
583 | OPT_UPTO_SIZE = 1 << OPTBIT_UPTO_SIZE , | ||
584 | OPT_EOF_STRING = 1 << OPTBIT_EOF_STRING , /* GNU: -e[<param>] */ | ||
585 | OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E<param> */ | ||
586 | OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, | ||
587 | OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, | ||
588 | OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, | ||
589 | OPT_REPLSTR = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR )) + 0, | ||
590 | OPT_REPLSTR1 = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR1 )) + 0, | ||
591 | }; | ||
592 | #define OPTION_STR "+trn:s:e::E:" \ | ||
593 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ | ||
594 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ | ||
595 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ | ||
596 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") \ | ||
597 | IF_FEATURE_XARGS_SUPPORT_PARALLEL( "P:+") \ | ||
598 | IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( "a:") | ||
599 | |||
600 | int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 610 | int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
601 | int xargs_main(int argc UNUSED_PARAM, char **argv) | 611 | int xargs_main(int argc UNUSED_PARAM, char **argv) |
602 | { | 612 | { |
@@ -726,6 +736,13 @@ int xargs_main(int argc UNUSED_PARAM, char **argv) | |||
726 | store_param(argv[i]); | 736 | store_param(argv[i]); |
727 | } | 737 | } |
728 | 738 | ||
739 | if (opt & OPT_STDIN_TTY) { | ||
740 | G.fd_tty = xopen(CURRENT_TTY, O_RDONLY); | ||
741 | close_on_exec_on(G.fd_tty); | ||
742 | G.fd_stdin = dup(STDIN_FILENO); | ||
743 | close_on_exec_on(G.fd_stdin); | ||
744 | } | ||
745 | |||
729 | initial_idx = G.idx; | 746 | initial_idx = G.idx; |
730 | while (1) { | 747 | while (1) { |
731 | char *rem; | 748 | char *rem; |