From c4d296aa7c71d3dd812497c02c976124b66a0ff9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Dec 2022 10:38:08 +0100 Subject: 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 --- findutils/xargs.c | 85 +++++++++++++++++++++++++++++++++---------------------- 1 file 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 { #endif const char *eof_str; int idx; + int fd_tty; + int fd_stdin; #if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL int running_procs; int max_procs; @@ -140,6 +142,42 @@ struct globals { IF_FEATURE_XARGS_SUPPORT_QUOTES(G.process_stdin__q = '\0';) \ } while (0) +/* Correct regardless of combination of CONFIG_xxx */ +enum { + OPTBIT_VERBOSE = 0, + OPTBIT_NO_EMPTY, + OPTBIT_UPTO_NUMBER, + OPTBIT_UPTO_SIZE, + OPTBIT_EOF_STRING, + OPTBIT_EOF_STRING1, + OPTBIT_STDIN_TTY, + IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) + IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) + IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR ,) + IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR1 ,) + + OPT_VERBOSE = 1 << OPTBIT_VERBOSE , + OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , + OPT_UPTO_NUMBER = 1 << OPTBIT_UPTO_NUMBER, + OPT_UPTO_SIZE = 1 << OPTBIT_UPTO_SIZE , + OPT_EOF_STRING = 1 << OPTBIT_EOF_STRING , /* GNU: -e[] */ + OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E */ + OPT_STDIN_TTY = 1 << OPTBIT_STDIN_TTY, + OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, + OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, + OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, + OPT_REPLSTR = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR )) + 0, + OPT_REPLSTR1 = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR1 )) + 0, +}; +#define OPTION_STR "+trn:s:e::E:o" \ + IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ + IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ + IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") \ + IF_FEATURE_XARGS_SUPPORT_PARALLEL( "P:+") \ + IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( "a:") + /* * Returns 0 if xargs should continue (but may set G.xargs_exitcode to 123). @@ -151,6 +189,9 @@ static int xargs_exec(void) { int status; + if (option_mask32 & OPT_STDIN_TTY) + xdup2(G.fd_tty, STDIN_FILENO); + #if !ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL status = spawn_and_wait(G.args); #else @@ -237,6 +278,8 @@ static int xargs_exec(void) ret: if (status != 0) G.xargs_exitcode = status; + if (option_mask32 & OPT_STDIN_TTY) + xdup2(G.fd_stdin, STDIN_FILENO); return status; } @@ -542,6 +585,7 @@ static int xargs_ask_confirmation(void) //usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( //usage: "\n -a FILE Read from FILE instead of stdin" //usage: ) +//usage: "\n -o Reopen stdin as /dev/tty" //usage: "\n -r Don't run command if input is empty" //usage: "\n -t Print the command on stderr before execution" //usage: IF_FEATURE_XARGS_SUPPORT_CONFIRMATION( @@ -563,40 +607,6 @@ static int xargs_ask_confirmation(void) //usage: "$ ls | xargs gzip\n" //usage: "$ find . -name '*.c' -print | xargs rm\n" -/* Correct regardless of combination of CONFIG_xxx */ -enum { - OPTBIT_VERBOSE = 0, - OPTBIT_NO_EMPTY, - OPTBIT_UPTO_NUMBER, - OPTBIT_UPTO_SIZE, - OPTBIT_EOF_STRING, - OPTBIT_EOF_STRING1, - IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) - IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) - IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) - IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR ,) - IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR1 ,) - - OPT_VERBOSE = 1 << OPTBIT_VERBOSE , - OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , - OPT_UPTO_NUMBER = 1 << OPTBIT_UPTO_NUMBER, - OPT_UPTO_SIZE = 1 << OPTBIT_UPTO_SIZE , - OPT_EOF_STRING = 1 << OPTBIT_EOF_STRING , /* GNU: -e[] */ - OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E */ - OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, - OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, - OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, - OPT_REPLSTR = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR )) + 0, - OPT_REPLSTR1 = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR1 )) + 0, -}; -#define OPTION_STR "+trn:s:e::E:" \ - IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ - IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ - IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ - IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") \ - IF_FEATURE_XARGS_SUPPORT_PARALLEL( "P:+") \ - IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( "a:") - int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int xargs_main(int argc UNUSED_PARAM, char **argv) { @@ -726,6 +736,13 @@ int xargs_main(int argc UNUSED_PARAM, char **argv) store_param(argv[i]); } + if (opt & OPT_STDIN_TTY) { + G.fd_tty = xopen(CURRENT_TTY, O_RDONLY); + close_on_exec_on(G.fd_tty); + G.fd_stdin = dup(STDIN_FILENO); + close_on_exec_on(G.fd_stdin); + } + initial_idx = G.idx; while (1) { char *rem; -- cgit v1.2.3