On 04/27/2018 08:13 AM, Eric Blake wrote: >> Well, env doesn't know at that point that -S is coming later ... still >> the error message is really confusing. Any idea? > > We could include ' ' (and maybe '\t') as part of the short-option > optstring accepted in getopt_long(), as an undocumented silent no-op. > That would make '-v ' behave the same as '-v'. But I'm not sure if it > is ever possible to coax getopt_long() into parsing '-v-' as accepting a > short option named '-' (since usually, the string '--' is treated as > end-of-options). Worth a try, to see if it works?
I tested it, and it DOES seem to work: Pre-patch: $ env "$(printf -- '-0\t -0')" | grep nosuch env: invalid option -- ' ' Try 'env --help' for more information. $ Post-patch: $ ./src/env "$(printf -- '-0\t -0')" | grep nosuch $ (Admittedly, my experiment was done without the -S patch in place, but you can figure out how to incorporate it) diff --git i/src/env.c w/src/env.c index bacef9b02..db2085034 100644 --- i/src/env.c +++ w/src/env.c @@ -96,10 +96,15 @@ main (int argc, char **argv) initialize_exit_failure (EXIT_CANCELED); atexit (close_stdout); - while ((optc = getopt_long (argc, argv, "+C:iu:0", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "+C:iu:0 \t-", longopts, NULL)) != -1) { switch (optc) { + case ' ': + case '\t': + case '-': + /* Undocumented no-ops, to allow '-v -S' to behave like '-vS' */ + break; case 'i': ignore_environment = true; break; @@ -128,7 +133,7 @@ main (int argc, char **argv) } optind = 0; /* Force GNU getopt to re-initialize. */ - while ((optc = getopt_long (argc, argv, "+C:iu:0", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "+C:iu:0 \t-", longopts, NULL)) != -1) if (optc == 'u' && unsetenv (optarg)) die (EXIT_CANCELED, errno, _("cannot unset %s"), quote (optarg)); -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature