Way back on Oct 02, 2004, David G. Lawrence wrote: >Garance wrote: > > In fact, it seems to be the '--' which is causing the rest of the >> line to be ignored, not the '#'. >> >> The PR is correct in that this feature is documented by perl books, >> but the right way to support the feature is to change /bin/sh and >> not the command interpreter. The PR includes a followup reply from >> Ahmon Dancy <dancy_at_dancysoft.com> with some additional proof that >> the change to the command interpreter was the wrong way to fix this. >> >> Since this perl feature is documented in many places (including the >> famous "Camel" book from O'Reilly), we can not just drop the support >> in the command interpreter. But if we first fix /bin/sh then I >> believe we can drop it. > > Err, your terminology is a bit off (/bin/sh is the "command >interpreter"); what we're talking about is the behavior of the >execve() system call in the kernel, specifically the imgact_shell >image activation module. When the system sees that a file needs to >be interpreted by something (e.g. sh, perl, python, or some other >language interpreter) it parses the interpreter line specified at >the top of the file (#!/bin/sh) and sets up to invoke that with >the original file as the argument. > > ...but I see what you're saying and I agree with the thought. >The interpreter should decide if the # is a comment, not the kernel. Since the above message, the execve() system call was fixed, but we never changed the behavior of /bin/sh to match. I recently noticed that some of my scripts broke due to this combination, and today one of my friends also mentioned that some of their scripts were broken after they upgraded to the latest 5.3-stable. I remember someone saying that they were going to fix /bin/sh, but I don't remember who, and it looks like I didn't save that email. So I wrote up the following update, and hope to commit it sometime soon. It seems to work fine, but I want to test it a bit after doing some buildworlds on three different platforms. Index: options.c =================================================================== RCS file: /home/ncvs/src/bin/sh/options.c,v retrieving revision 1.21 diff -u -r1.21 options.c --- options.c 6 Apr 2004 20:06:51 -0000 1.21 +++ options.c 1 Feb 2005 01:53:52 -0000 _at__at_ -67,6 +67,7 _at__at_ char *optptr; /* used by nextopt */ char *minusc; /* argument to -c option */ +STATIC int found_eoo; /* found '-' or '--' in the option list */ STATIC void options(int); _at__at_ -82,6 +83,7 _at__at_ void procargs(int argc, char **argv) { + char *ap; int i; argptr = argv; _at__at_ -91,6 +93,23 _at__at_ optlist[i].val = 2; privileged = (getuid() != geteuid() || getgid() != getegid()); options(1); + /* + * If an end-of-options marker ('-' or '--') is followed by an arg + * of '#', then skip over all args after the marker. Some scripting + * languages (e.g.: perl) document that /bin/sh will implement this + * behavior, and they recommend that users take advantage of it to + * solve certain issues that can come up when writing a perl script. + * Yes, this feature is in /bin/sh to help users write perl scripts. + */ + if (found_eoo) { + ap = *argptr; + if (ap != NULL && ap[0] == '#' && ap[1] == '\0') { + while (*argptr != NULL) + argptr++; + /* We need to keep the final argument */ + argptr--; + } + } if (*argptr == NULL && minusc == NULL) sflag = 1; if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) _at__at_ -142,6 +161,7 _at__at_ int val; int c; + found_eoo = 0; if (cmdline) minusc = NULL; while ((p = *argptr) != NULL) { _at__at_ -149,6 +169,7 _at__at_ if ((c = *p++) == '-') { val = 1; if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { + found_eoo = 1; if (!cmdline) { /* "-" means turn off -x and -v */ if (p[0] == '\0') -- Garance Alistair Drosehn = gad_at_gilead.netel.rpi.edu Senior Systems Programmer or gad_at_freebsd.org Rensselaer Polytechnic Institute or drosih_at_rpi.eduReceived on Tue Feb 01 2005 - 03:09:23 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:27 UTC