xargs: support -a FILE

The GNU-specific option -a lets xargs read the arguments from a file
rather than from stdin.

This is particularly convenient when debugging in gdb interactively,
and it might be of more general use.

function                                             old     new   delta
xargs_main                                           788     823     +35
packed_usage                                       31683   31671     -12

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Johannes Schindelin 2017-08-25 22:42:05 +02:00 committed by Denys Vlasenko
parent f41ffff2dc
commit f8ee849ecd

View File

@ -64,6 +64,11 @@
//config: bool "Enable -P N: processes to run in parallel" //config: bool "Enable -P N: processes to run in parallel"
//config: default y //config: default y
//config: depends on XARGS //config: depends on XARGS
//config:
//config:config FEATURE_XARGS_SUPPORT_ARGS_FILE
//config: bool "Enable -a FILE: use FILE instead of stdin"
//config: default y
//config: depends on XARGS
//applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs)) //applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs))
@ -517,6 +522,9 @@ static int xargs_ask_confirmation(void)
//usage: IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( //usage: IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(
//usage: "\n -0 Input is separated by NUL characters" //usage: "\n -0 Input is separated by NUL characters"
//usage: ) //usage: )
//usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE(
//usage: "\n -a FILE Read from FILE instead of stdin"
//usage: )
//usage: "\n -t Print the command on stderr before execution" //usage: "\n -t Print the command on stderr before execution"
//usage: "\n -e[STR] STR stops input processing" //usage: "\n -e[STR] STR stops input processing"
//usage: "\n -n N Pass no more than N args to PROG" //usage: "\n -n N Pass no more than N args to PROG"
@ -565,7 +573,8 @@ enum {
IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \
IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \
IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") \ IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") \
IF_FEATURE_XARGS_SUPPORT_PARALLEL( "P:+") 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)
@ -584,6 +593,7 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
#else #else
#define read_args process_stdin #define read_args process_stdin
#endif #endif
IF_FEATURE_XARGS_SUPPORT_PARALLEL(char *opt_a = NULL;)
INIT_G(); INIT_G();
@ -592,6 +602,7 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
&max_args, &max_chars, &G.eof_str, &G.eof_str &max_args, &max_chars, &G.eof_str, &G.eof_str
IF_FEATURE_XARGS_SUPPORT_REPL_STR(, &G.repl_str, &G.repl_str) IF_FEATURE_XARGS_SUPPORT_REPL_STR(, &G.repl_str, &G.repl_str)
IF_FEATURE_XARGS_SUPPORT_PARALLEL(, &G.max_procs) IF_FEATURE_XARGS_SUPPORT_PARALLEL(, &G.max_procs)
IF_FEATURE_XARGS_SUPPORT_ARGS_FILE(, &opt_a)
); );
#if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL #if ENABLE_FEATURE_XARGS_SUPPORT_PARALLEL
@ -599,6 +610,11 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
G.max_procs = 100; /* let's not go crazy high */ G.max_procs = 100; /* let's not go crazy high */
#endif #endif
#if ENABLE_FEATURE_XARGS_SUPPORT_ARGS_FILE
if (opt_a)
xmove_fd(xopen(opt_a, O_RDONLY), 0);
#endif
/* -E ""? You may wonder why not just omit -E? /* -E ""? You may wonder why not just omit -E?
* This is used for portability: * This is used for portability:
* old xargs was using "_" as default for -E / -e */ * old xargs was using "_" as default for -E / -e */