On 8/19/20 6:05 PM, enh wrote:
>     Where's this bug? It's not in the vanilla linux as of yesterday?
> 
> https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/kernel/gen_kheaders.sh#71

Sigh. WHY is that not in scripts? Ok.

Does the attached patch look like the start of a good fix? It lets you add ~ to
the start of optstr to give every -x option the parsing behavior of "tar xvjf".

(Which I _think_ is the unix v6 semantics from 1975, which cpio seems to retain
for some reason.)

That means "cpio -pd out" should work and "cpio out -pd" should provide an error
message.

  $ ./cpio -pd out
  cpio: chdir 'out': No such file or directory
  ^C
  $ ./cpio out -pd
  cpio: Missing argument to -p (see "cpio --help")

Which looks like there's a seperate bug that the receive side ends and the send
side doesn't immediately notice, but presumably it would if we fed it some data
so it unblocked...

  $ echo xiphoid | ./cpio -pd out
  cpio: chdir 'out': No such file or directory

Yeah, that exits. Close enough, I'm probably ok with that behavior.

Rob
diff --git a/lib/args.c b/lib/args.c
index 83bceaf0..776026c3 100644
--- a/lib/args.c
+++ b/lib/args.c
@@ -76,6 +76,7 @@
 //     >9 die if > # leftover arguments (default MAX_INT)
 //     ? Allow unknown arguments (pass them through to command).
 //     & first arg has imaginary dash (ala tar/ps/ar) which sets FLAGS_NODASH
+//     ~ use UNIXv6 parsing semantics always (as & does for first argument)
 //
 //   At the end: [groups] of previously seen options
 //     - Only one in group (switch off)    [-abc] means -ab=-b, -ba=-a, -abc=-c
@@ -245,6 +246,7 @@ void parse_optflaglist(struct getoptflagstate *gof)
     else if (*options == '>') gof->maxargs=*(++options)-'0';
     else if (*options == '?') gof->noerror++;
     else if (*options == '&') gof->nodash_now = 1;
+    else if (*options == '~') gof->nodash_now = 2;
     else break;
     options++;
   }
@@ -394,7 +396,7 @@ void get_optflags(void)
 
   parse_optflaglist(&gof);
 
-  if (toys.argv[1] && toys.argv[1][0] == '-') gof.nodash_now = 0;
+  if (toys.argv[1] && toys.argv[1][0] == '-') gof.nodash_now &= 2;
 
   // Iterate through command line arguments, skipping argv[0]
   for (gof.argc=1; toys.argv[gof.argc]; gof.argc++) {
@@ -404,7 +406,7 @@ void get_optflags(void)
     // Parse this argument
     if (gof.stopearly>1) goto notflag;
 
-    if (gof.argc>1 || *gof.arg=='-') gof.nodash_now = 0;
+    if (gof.argc>1 || *gof.arg=='-') gof.nodash_now &= 2;
 
     // Various things with dashes
     if (*gof.arg == '-') {
@@ -448,7 +450,7 @@ void get_optflags(void)
 
     // Handle things that don't start with a dash.
     } else {
-      if (gof.nodash_now) toys.optflags |= FLAGS_NODASH;
+      if (gof.nodash_now&1) toys.optflags |= FLAGS_NODASH;
       else goto notflag;
     }
 
diff --git a/scripts/mkflags.c b/scripts/mkflags.c
index fff9dd4c..ad68319f 100644
--- a/scripts/mkflags.c
+++ b/scripts/mkflags.c
@@ -22,7 +22,7 @@ struct flag {
 int chrtype(char c)
 {
   // Does this populate a GLOBALS() variable?
-  if (strchr("?&^-:#|@*; %", c)) return 1;
+  if (strchr("~?&^-:#|@*; %", c)) return 1;
 
   // Is this followed by a numeric argument in optstr?
   if (strchr("=<>", c)) return 2;
_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to