View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002002 | 1003.1(2024)/Issue8 | System Interfaces | public | 2026-10-28 18:50 | 2026-11-10 06:05 |
| Reporter | stephane | Assigned To | |||
| Priority | normal | Severity | Objection | Type | Enhancement Request |
| Status | New | Resolution | Open | ||
| Name | Stephane Chazelas | ||||
| Organization | |||||
| User Reference | |||||
| Section | https://pubs.opengroup.org/onlinepubs/9799919799/functions/execl.html | ||||
| Page Number | https://pubs.opengroup.org/onlinepubs/9799919799/functions/execl.html | ||||
| Line Number | https://pubs.opengroup.org/onlinepubs/9799919799/functions/execl.html | ||||
| Interp Status | |||||
| Final Accepted Text | |||||
| Summary | 0002002: execlp() / execvp() and commands starting with - or + | ||||
| Description | Similar to 0001440, related to 0001600 https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/execl.html has: """ In the cases where the other members of the exec family of functions would fail and set errno to [ENOEXEC], the execlp() and execvp() functions shall execute a command interpreter and the environment of the executed command shall be as if the process invoked the sh utility using execl() as follows: execl(<shell path>, <name>, file, <args>, (char *)0); where <shell path> is an unspecified pathname for the sh utility, <name> is an unspecified string, file is the process image file, and where <args> is zero or more parameters corresponding to any initial non-null arguments passed after arg0 for execlp() or to any initial non-null members of argv starting at argv[1] for execvp(). """ "file is the process image file" should probably be "file is the pathname to the process image file", but also, if that pathname starts with - or +, such as when invoked as execlp("-dir-/cmd",...) or execlp("+x",...) and +x was found in the current directory because $PATH contains an empty component, then that path will be taken as an option by sh instead of the path to the file being executed. There's a similar problem in the resolution of 0001600 where #! /path/to/sh
${0##*/} "$@"Should be: #! /path/to/sh --
"${0##*/}" "$@"(leaving that ${0##*/} unquoted to request split+glob also doesn't make sense here) | ||||
| Desired Action | For execlp/execvp, change to: """ execl(<shell path>, <name>, "--", file, <args>, (char *)0); where <shell path> is an unspecified pathname for the sh utility, <name> is an unspecified string, file is the pathname of the process image file, and where <args> is zero or more parameters corresponding to any initial non-null arguments passed after arg0 for execlp() or to any initial non-null members of argv starting at argv[1] for execvp(). """ Apparently Solaris/Illumos prefix the path with ./ if it starts with - (not +) instead (https://github.com/illumos/illumos-gate/blob/7bbcc14f12e8a235cc9668f76da6d2c9ecf14cd4/usr/src/lib/libc/port/gen/execvp.c#L156-L158). We may want to also allow that even if that means that changes the value of `$0` in the shell script. For the builtins (0001600 resolution): #! /path/to/sh --
"${0##*/}" "$@"Using a single dash as in: #! /path/to/sh -
"${0##*/}" "$@"May be more canonical as that's what was done for the Bourne shell. | ||||
| Tags | issue9 | ||||
| related to | 0001600 | Closed | 1003.1(2016/18)/Issue7+TC2 | Problems with the suggested single-line shell script: $0 "$@" |
|
|
Interpretation response ------------------------ The standard clearly states the behavior of execvp and execlp , and conforming implementations must conform to this. Rationale: ------------- The behavior specified by the standard contains dangers that users may not realize, and there is no appropriate warning. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- Page 867, after line 29504 add a following new sentence:
Page 874, after line 29802, add a new paragraph:
|
|
|
Thanks, that's a step in the right direction in my opinion as at least it raises awareness to the potential issue, but some issues remain: It doesn't address my: > "file is the process image file" should probably be "file is the pathname to the process image file" And that "if the file argument" in the proposed change makes me realise the problem in the original text is that in execl(<shell path>, <name>, file, <args>, (char *)0); That "file" incorrectly refers to the "file" argument passed in: execlp(const char *file, const char *arg0, ... /*, (char *)0 */); It should rather be: execl(<shell path>, <name>, <resolved_pathname>, <args>, (char *)0); Where <resolved_pathname> is the pathname to file resolved as per above (with behaviour undefined if that pathname (not file) starts with - or +). For example: % PATH=~/bin:/bin ltrace -e execvp env zzz blah
env->execvp("zzz", ["zzz", "blah"] <no return ...>
--- Called exec() ---
+++ exited (status 0) +++
% PATH=~/bin:/bin strace -qqe execve env zzz blah
execve("/bin/env", ["env", "zzz", "blah"], 0x7fffc2ccc440 /* 55 vars */) = 0
execve("/home/chazelas/bin/zzz", ["zzz", "blah"], 0x7ffc48cf3368 /* 55 vars */) = -1 ENOEXEC (Exec format error)
execve("/bin/sh", ["/bin/sh", "/home/chazelas/bin/zzz", "blah"], 0x7ffc48cf3368 /* 55 vars */) = 0It's the pathname resolved from a $PATH lookup (/home/chazelas/bin/zzz) that was passed as argument to /bin/sh, not zzz (the "file" argument to execvp()). And: $ PATH=+dir+:/bin strace -qqe execve env zzz blah
execve("/bin/env", ["env", "zzz", "blah"], 0x7fffe38a6820 /* 55 vars */) = 0
execve("+dir+/zzz", ["zzz", "blah"], 0x7ffda17ab848 /* 55 vars */) = -1 ENOEXEC (Exec format error)
execve("/bin/sh", ["/bin/sh", "+dir+/zzz", "blah"], 0x7ffda17ab848 /* 55 vars */) = 0
/bin/sh: 0: Illegal option -d(as that execvp() implementation fails to pass the -- option delimiter). Note that I'm aware of Solaris/Illumos prepending "./" to that pathname when it starts with - (not + in Illumos at least which would be an overlook) as already noted, I don't know if there are any that add the "--" delimiter (or "-" which is more idiomatic for sh as was supported by the Bourne shell). |
|
|
The proposed resolution also doesn't address the missing -- / - in#! /path/to/sh --
"${0##*/}" "$@" |
|
|
Also, it is not about "and the file found does not have appropriate execute permission". If the file does not have appropriate permission, execlp() / execvp() must fail with the appropriate error code (EACESS / EPERM...). "sh" is only invoked for files that have appropriate execute permission and for which execve() returns ENOEXEC (an executable format not recognised by the system). |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-10-28 18:50 | stephane | New Issue | |
| 2026-11-02 16:30 | msbrown | Relationship added | related to 0001600 |
| 2026-11-09 17:28 | msbrown | Tag Attached: issue9 | |
| 2026-11-09 17:29 | nick | Note Added: 0007552 | |
| 2026-11-09 17:30 | nick | Note Edited: 0007552 | |
| 2026-11-10 05:46 | stephane | Note Added: 0007557 | |
| 2026-11-10 05:49 | stephane | Note Added: 0007558 | |
| 2026-11-10 06:05 | stephane | Note Added: 0007559 |