@ page 225 line 6862 section exec objection
Problem:
The so-called #!-hack is an expected feature of a modern Unix system,
and is at the core of one of the very powerful features of the
operating system: the seamless integration of various scripting
languages. There are at least three ways of implementing the #!-hack:
in the exec() functions of libc (usually only execve need to be
modified since the other functions are usually implemented in terms of
execve); in the kernel, exec server, or equivalent; or in /bin/sh.
I believe it is overdue that this expected and essential feature is
codified.
The behaviour desired of the #!-hack is the following; this follows
the behaviour of the existing systems. [[Issues that need to be
discussed and should not be included in text are marked with double
square brackets.]]
[[For the sake of simplification, this discussion assumes execve() has
been called, and that all other exec functions are implemented in
terms of execve(). This is obviously not a requirement, and needs to
be dealt with properly in the final text.]]
If the file referenced by "path" exists, the current process has
appropriate privileges, the length of the file is no less than two
characters, and the first two characters of the file is the string
"#!" then the content of the file will be parsed in the following
manner:
- The initial #! sequence and any following whitespace is skipped.
- The next sequence of no more than {PATH_MAX} non-whitespace
characters is stored as the "interpreter".
- For the remainder of the line, any additional sequences of
non-whitespace characters are individually stored as
intrp_args[0..n-1] (for n == the number of such sequences. If there
are no such sequences, n == 0.)
[[Linux requires n <= 1. This causes problems with some existing
scripts. Should we make the behaviour undefined if n > 1?]]
If the line contains single or double quotation marks ('\'' or
'\"') the behaviour is undefined.
If the "interpreter" does not contain a leading '/', the behaviour is
undefined.
If the file begins with #! but the first line contains no
non-whitespace characters, the file contains no '\n' character
whatsoever, or the file referenced by "interpreter" does not exist,
the behaviour is undefined. [[Should [ENOEXEC] be required here?]]
If either the file referenced by "path" or the file referenced by
"interpreter" has the set-user-ID or set-group-ID bit [[capability
bits?]] set, the behaviour is undefined.
[[There are two existing behaviours in use, and each has its
advantages. Some systems honour the set-ID bits on the interpreter,
others on the file, yet others on neither. Each variant has its
advantages and drawbacks. Therefore it is probably not suitable for
standardization, although one option would be to specify explicitly
that each of these three alternatives are explicitly permitted.]]
The argv array will then be modified in the following way:
argv[0] is replaced with the basename of "interpreter" (using the same
algorithm as basename().)
[[Should it be permitted for argv[0] to simply be "interpreter"?]]
argv[1] is replaced with the name of the file itself, as given by
"path", except that if "path" lacks a leading '/', the current
working directory is prepended, separated from '/' with slash
characters as needed, thus making argv[1] independent of the current
working directory. However, symlinks referenced in "path" shall not
be canonicalized.
argv[2..n+1] are replaced with intrp_args[0..n-1].
argv[n..n+m-2] are replaced with the original argv[1..m-1].
Finally, the file referenced by "interpreter" is invoked as the
process image. If this file itself begins with #!, it is
implementation-dependent if the result is to return [ENOEXEC] or the
above process is recursed; otherwise the behaviour shall be as if
execve() had been invoked directly using the above modified arguments.
[[It may be preferrable to allow the return of [ENOEXEC] if the
invocation of the interpreter would have returned [ENOENT].]]
The #! issue is also described in XCU, where it is considered
undefined. This needs to remain at least partially undefined, since
kernel- and libc-based implementations will necessarily differ from
shell-based implementations as to the behaviour of "sh script" where
script starts with a legal #!-line with an interpreter *other* than
"sh". However, it may be desirable to standardize the behaviour of
the XCU shell encountering a #!-line which references itself.
Action:
This feature, and the lack thereof in the previous standard, is
mentioned mentioned throughout the exec definition. The exec
definition should be modified in all relevant places to incorporate
the above described feature.
|