diff options
author | Elliott Hughes <enh@google.com> | 2019-08-17 20:13:38 -0700 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-08-26 21:54:44 -0500 |
commit | 0ec6b113985f4470e021f84b216c1b98e1e194ad (patch) | |
tree | c286b8d3792648fd5eef78a65f4be8206b1f0079 | |
parent | c26870dab3462c6176936384b090df6b9ba46dee (diff) | |
download | toybox-0ec6b113985f4470e021f84b216c1b98e1e194ad.tar.gz |
xargs: add --max-args synonym, -o option, and fix -p.
The Linux kernel uses the --max-args synonym for -n.
Barbarians who use vi need xargs' -o to be able to do something like:
find -name xargs.c | xargs vi # Sad vi.
find -name xargs.c | xargs -o vi # Happy vi.
The -p option needs fixing to read from /dev/tty because stdin is
otherwise occupied in xargs. I think xargs is the only place that needs
this, so it didn't seem sensible to make all callers to yesno() be
specific about which they wanted, hence the new function.
Also remove the documentation for the build-time XARGS_PEDANTIC option
which isn't actually implemented.
Also add a TODO for -P (which is used by at least one script in the
Linux kernel).
-rw-r--r-- | lib/lib.c | 7 | ||||
-rw-r--r-- | lib/lib.h | 1 | ||||
-rw-r--r-- | toys/posix/xargs.c | 20 |
3 files changed, 16 insertions, 12 deletions
@@ -819,11 +819,16 @@ void base64_init(char *p) int yesno(int def) { + return fyesno(stdin, def); +} + +int fyesno(FILE *in, int def) +{ char buf; fprintf(stderr, " (%c/%c):", def ? 'Y' : 'y', def ? 'n' : 'N'); fflush(stderr); - while (fread(&buf, 1, 1, stdin)) { + while (fread(&buf, 1, 1, in)) { int new; // The letter changes the value, the newline (or space) returns it. @@ -250,6 +250,7 @@ void replace_tempfile(int fdin, int fdout, char **tempname); void crc_init(unsigned int *crc_table, int little_endian); void base64_init(char *p); int yesno(int def); +int fyesno(FILE *fp, int def); int qstrcmp(const void *a, const void *b); void create_uuid(char *uuid); char *show_uuid(char *uuid); diff --git a/toys/posix/xargs.c b/toys/posix/xargs.c index a8a7e339..f0d2efe0 100644 --- a/toys/posix/xargs.c +++ b/toys/posix/xargs.c @@ -8,8 +8,9 @@ * TODO: -I Insert mode * TODO: -L Max number of lines of input per command * TODO: -x Exit if can't fit everything in one command + * TODO: -P NUM Run up to NUM processes at once -USE_XARGS(NEWTOY(xargs, "^E:ptrn#<1s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN)) +USE_XARGS(NEWTOY(xargs, "^E:optrn#<1(max-args)s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN)) config XARGS bool "xargs" @@ -24,18 +25,11 @@ config XARGS -0 Each argument is NULL terminated, no whitespace or quote processing -E Stop at line matching string -n Max number of arguments per command + -o Open tty for COMMAND's stdin (default /dev/null) -p Prompt for y/n from tty before running each command -r Don't run command with empty input -s Size in bytes per command line -t Trace, print command line to stderr - -config XARGS_PEDANTIC - bool "TODO xargs pedantic posix compatibility" - default n - depends on XARGS - help - This version supports insane posix whitespace handling rendered obsolete - by -0 mode. */ #define FOR_xargs @@ -47,6 +41,7 @@ GLOBALS( long entries, bytes; char delim; + FILE *tty; ) // If out==NULL count TT.bytes and TT.entries, stopping at max. @@ -188,14 +183,16 @@ void xargs_main(void) for (i = 0; out[i]; ++i) fprintf(stderr, "%s ", out[i]); if (FLAG(p)) { fprintf(stderr, "?"); - doit = yesno(0); + if (!TT.tty) TT.tty = xfopen("/dev/tty", "re"); + doit = fyesno(TT.tty, 0); } else fprintf(stderr, "\n"); } if (doit) { if (!(pid = XVFORK())) { xclose(0); - open("/dev/null", O_RDONLY); + if (open(FLAG(o) ? "/dev/tty" : "/dev/null", O_RDONLY) != 0) + perror_exit("child stdin open"); xexec(out); } waitpid(pid, &status, 0); @@ -212,4 +209,5 @@ void xargs_main(void) } free(out); } + if (TT.tty) fclose(TT.tty); } |