Implement -p, -t, and -r.

Add some missing tests.

Move -L and -x back to TODO since they're not implemented and I haven't
yet even understood what they're supposed to do.
---
 tests/xargs.test   | 11 ++++++++++
 toys/posix/xargs.c | 50 ++++++++++++++++++++++++++++++----------------
 2 files changed, 44 insertions(+), 17 deletions(-)
From 8cb64c227d253cf264b9a06b110a8e716e5dedcf Mon Sep 17 00:00:00 2001
From: Elliott Hughes <[email protected]>
Date: Fri, 18 Jan 2019 16:54:13 -0800
Subject: [PATCH] xargs: make --help match reality.

Implement -p, -t, and -r.

Add some missing tests.

Move -L and -x back to TODO since they're not implemented and I haven't
yet even understood what they're supposed to do.
---
 tests/xargs.test   | 11 ++++++++++
 toys/posix/xargs.c | 50 ++++++++++++++++++++++++++++++----------------
 2 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/tests/xargs.test b/tests/xargs.test
index 407817cc..dce93ed3 100644
--- a/tests/xargs.test
+++ b/tests/xargs.test
@@ -27,6 +27,17 @@ rm one two three
 testing "-0 -n1" "printf 'a\0b\0c\0d\0e\0f' | xargs -0 -n1 echo _" "_ a\n_ b\n_ c\n_ d\n_ e\n_ f\n" "" ""
 testing "-0 -n2" "printf 'a\0b\0c\0d\0e\0f' | xargs -0 -n2 echo _" "_ a b\n_ c d\n_ e f\n" "" ""
 
+testing "-t" "xargs -t 2>stderr ; cat stderr ; rm stderr" "one two\necho one two \n" "" "one\ntwo\n"
+
+testing "-E END" "xargs -E END" "a b\n" "" "a\nb\nEND\nc\nd\n"
+
+testing "-r" "xargs -r echo x" "" "" ""
+
+# TODO: what exactly is -x supposed to do? why does coreutils output "one"?
+#testing "-x" "xargs -x -s 9 || echo expected" "one\nexpected\n" "" "one\ntwo\nthree"
+
+# TODO: test for -L? what exactly is the difference between -n and -L?
+
 #testing "-n exact match"
 #testing "-s exact match"
 #testing "-s 0"
diff --git a/toys/posix/xargs.c b/toys/posix/xargs.c
index d25a2e3f..e23d14c4 100644
--- a/toys/posix/xargs.c
+++ b/toys/posix/xargs.c
@@ -5,28 +5,28 @@
  * See http://opengroup.org/onlinepubs/9699919799/utilities/xargs.html
  *
  * TODO: Rich's whitespace objection, env size isn't fixed anymore.
+ * TODO: -x	Exit if can't fit everything in one command
+ * TODO: -L	Max number of lines of input per command
 
-USE_XARGS(NEWTOY(xargs, "^I:E:L#ptxrn#<1s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_XARGS(NEWTOY(xargs, "^I:E:ptrn#<1s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config XARGS
   bool "xargs"
   default y
   help
-    usage: xargs [-ptxr0] [-s NUM] [-n NUM] [-L NUM] [-E STR] COMMAND...
+    usage: xargs [-0prt] [-s NUM] [-n NUM] [-E STR] COMMAND...
 
     Run command line one or more times, appending arguments from stdin.
 
     If command exits with 255, don't launch another even if arguments remain.
 
-    -s	Size in bytes per command line
-    -n	Max number of arguments per command
     -0	Each argument is NULL terminated, no whitespace or quote processing
-    #-p	Prompt for y/n from tty before running each command
-    #-t	Trace, print command line to stderr
-    #-x	Exit if can't fit everything in one command
-    #-r	Don't run command with empty input
-    #-L	Max number of lines of input per command
-    -E	stop at line matching string
+    -E	Stop at line matching string
+    -n	Max number of arguments per command
+    -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 compatability"
@@ -41,7 +41,7 @@ config XARGS_PEDANTIC
 #include "toys.h"
 
 GLOBALS(
-  long s, n, L;
+  long s, n;
   char *E, *I;
 
   long entries, bytes;
@@ -134,6 +134,8 @@ void xargs_main(void)
 
   // Loop through exec chunks.
   while (data || !done) {
+    int doit = 1;
+
     TT.entries = 0;
     TT.bytes = bytes;
 
@@ -163,6 +165,8 @@ void xargs_main(void)
       break;
     }
 
+    if (TT.entries == 0 && FLAG(r)) continue;
+
     // Accumulate cally thing
 
     if (data && !TT.entries) error_exit("argument too long");
@@ -176,13 +180,25 @@ void xargs_main(void)
     for (dtemp = dlist; dtemp; dtemp = dtemp->next)
       handle_entries(dtemp->data, out+entries);
 
-    if (!(pid = XVFORK())) {
-      xclose(0);
-      open("/dev/null", O_RDONLY);
-      xexec(out);
+    if (FLAG(p) || FLAG(t)) {
+      int i;
+
+      for (i = 0; out[i]; ++i) fprintf(stderr, "%s ", out[i]);
+      if (FLAG(p)) {
+        fprintf(stderr, "?");
+	doit = yesno(0);
+      } else fprintf(stderr, "\n");
+    }
+
+    if (doit) {
+      if (!(pid = XVFORK())) {
+        xclose(0);
+        open("/dev/null", O_RDONLY);
+        xexec(out);
+      }
+      waitpid(pid, &status, 0);
+      status = WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127;
     }
-    waitpid(pid, &status, 0);
-    status = WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127;
 
     // Abritrary number of execs, can't just leak memory each time...
     while (dlist) {
-- 
2.20.1.321.g9e740568ce-goog

_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to