summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2005-02-16 05:17:58 +0000
committergad <gad@FreeBSD.org>2005-02-16 05:17:58 +0000
commit41238cc6d19537d94771e20dbde35067d8d8f618 (patch)
treee25740a73c8e9fed7cfa1bffc83c07393f859e15 /bin
parent050a349d745c648534dc5d4bf551d4c1dd56c670 (diff)
downloadFreeBSD-src-41238cc6d19537d94771e20dbde35067d8d8f618.zip
FreeBSD-src-41238cc6d19537d94771e20dbde35067d8d8f618.tar.gz
Change /bin/sh so *it* implements the processing needed for scripts to
work as expected when they have a "shebang line" of: #!/bin/sh -- # -*- perl -*- -p This specific line is recommended in some perl documentation, and I think I've seen similar lines in documentation for ruby and python. Those write-ups expect `sh' to ignore everything after the '--' if the first thing after the '--' is a '#'. See chapter 19, "The Command-Line Interface" in 3rd edition of "Programming Perl", for some discussion of why perl recommends using this line in some circumstances. The above line does work on solaris, irix and aix (as three data points), and it used to work on FreeBSD by means of a similar patch to execve(). However, that change to execve() effected *all* shells (which caused other problems), and that processing was recently removed. PR: 16393 (the original request to fix the same issue) Reviewed by: freebsd-current (looking at a slightly different patch) MFC after: 1 week
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/options.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/bin/sh/options.c b/bin/sh/options.c
index df30c19..bc60a96 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -148,17 +148,11 @@ options(int cmdline)
argptr++;
if ((c = *p++) == '-') {
val = 1;
- if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
- if (!cmdline) {
- /* "-" means turn off -x and -v */
- if (p[0] == '\0')
- xflag = vflag = 0;
- /* "--" means reset params */
- else if (*argptr == NULL)
- setparam(argptr);
- }
- break; /* "-" or "--" terminates options */
- }
+ /* A "-" or "--" terminates options */
+ if (p[0] == '\0')
+ goto end_options1;
+ if (p[0] == '-' && p[1] == '\0')
+ goto end_options2;
} else if (c == '+') {
val = 0;
} else {
@@ -191,6 +185,44 @@ options(int cmdline)
}
}
}
+ return;
+
+ /* When processing `set', a single "-" means turn off -x and -v */
+end_options1:
+ if (!cmdline) {
+ xflag = vflag = 0;
+ return;
+ }
+
+ /*
+ * When processing `set', a "--" means the remaining arguments
+ * replace the positional parameters in the active shell. If
+ * there are no remaining options, then all the positional
+ * parameters are cleared (equivalent to doing ``shift $#'').
+ */
+end_options2:
+ if (!cmdline) {
+ if (*argptr == NULL)
+ setparam(argptr);
+ return;
+ }
+
+ /*
+ * At this point we are processing options given to 'sh' on a command
+ * line. If an end-of-options marker ("-" or "--") is followed by an
+ * arg of "#", then skip over all remaining arguments. 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.
+ */
+ p = *argptr;
+ if (p != NULL && p[0] == '#' && p[1] == '\0') {
+ while (*argptr != NULL)
+ argptr++;
+ /* We need to keep the final argument */
+ argptr--;
+ }
}
STATIC void
OpenPOWER on IntegriCloud