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>
This commit is contained in:
Denys Vlasenko 2022-12-22 10:38:08 +01:00
parent 02ca565646
commit c4d296aa7c

View File

@ -111,6 +111,8 @@ struct globals {
#endif #endif
const char *eof_str; const char *eof_str;
int idx; int idx;
int fd_tty;
int fd_stdin;
#if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL #if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL
int running_procs; int running_procs;
int max_procs; int max_procs;
@ -140,6 +142,42 @@ struct globals {
IF_FEATURE_XARGS_SUPPORT_QUOTES(G.process_stdin__q = '\0';) \ IF_FEATURE_XARGS_SUPPORT_QUOTES(G.process_stdin__q = '\0';) \
} while (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[<param>] */
OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E<param> */
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). * 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; int status;
if (option_mask32 & OPT_STDIN_TTY)
xdup2(G.fd_tty, STDIN_FILENO);
#if !ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL #if !ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL
status = spawn_and_wait(G.args); status = spawn_and_wait(G.args);
#else #else
@ -237,6 +278,8 @@ static int xargs_exec(void)
ret: ret:
if (status != 0) if (status != 0)
G.xargs_exitcode = status; G.xargs_exitcode = status;
if (option_mask32 & OPT_STDIN_TTY)
xdup2(G.fd_stdin, STDIN_FILENO);
return status; return status;
} }
@ -542,6 +585,7 @@ static int xargs_ask_confirmation(void)
//usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( //usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE(
//usage: "\n -a FILE Read from FILE instead of stdin" //usage: "\n -a FILE Read from FILE instead of stdin"
//usage: ) //usage: )
//usage: "\n -o Reopen stdin as /dev/tty"
//usage: "\n -r Don't run command if input is empty" //usage: "\n -r Don't run command if input is empty"
//usage: "\n -t Print the command on stderr before execution" //usage: "\n -t Print the command on stderr before execution"
//usage: IF_FEATURE_XARGS_SUPPORT_CONFIRMATION( //usage: IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(
@ -563,40 +607,6 @@ static int xargs_ask_confirmation(void)
//usage: "$ ls | xargs gzip\n" //usage: "$ ls | xargs gzip\n"
//usage: "$ find . -name '*.c' -print | xargs rm\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[<param>] */
OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E<param> */
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, char **argv) MAIN_EXTERNALLY_VISIBLE;
int xargs_main(int argc UNUSED_PARAM, char **argv) 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]); 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; initial_idx = G.idx;
while (1) { while (1) {
char *rem; char *rem;