Open ea85c2d2-6c1b-404f-925b-b563a6edde5b opened 10 years ago
Hello,
According to [1],
"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>, arg0, file, arg1, ..., (char *)0);"
This is not the case with os.execvp which keeps looking in PATH for other executables. To reproduce:
Instead of running the #!-less shell script, /usr/bin/curl is executed. With GNU libc's execvp(), the shell script is executed. According to my interpretation of POSIX, the shell script should be executed.
[1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
Cheers,
-- Stéphane
What platform is this on? Looking quickly through posix.execve (which is what I think gets called), it looks like it just calls C's execve().
Also, what's your use case for this? I realize it might be a standard behavior, but it seems like a bad idea to me. (Not that that's a reason not to be standards compliant: I'm mostly just curious why you'd want this.)
What platform is this on?
I'm on Linux (Debian testing).
Looking quickly through posix.execve (which is what I think gets called), it looks like it just calls C's execve().
Yes, but I'm talking about os.execvp, here. With the search in PATH.
Also, what's your use case for this?
I discovered that by accident while investigating another bug...
I realize it might be a standard behavior, but it seems like a bad idea to me.
What is the bad idea? Keep looking in subsequent directories in PATH when you find a candidate for which execve() fails? Sorry, but I beg to differ, and POSIX is on my side.
What is the bad idea? Keep looking in subsequent directories in PATH when you find a candidate for which execve() fails? Sorry, but I beg to differ, and POSIX is on my side.
Sorry, I meant "Stop looking in subsequent [..]".
os.execvp calls os._execvpe which calls posix.execv which calls execv. At least that's how I think it works.
os.execvp calls os._execvpe which calls posix.execv which calls execv. At least that's how I think it works.
I am not contesting that. This bug is about the "search the command in PATH" part. More precisely, the fact that os.execvp continues the search after execv fails.
I know that. This is mostly just a note to myself so I can remember what I've looked at the next time I have a few moments to look at the bug. Or, anyone else who wants to track it down.
Here's a real-world case where this can cause unexpected results: A shell script has a typo in the shebang ("#/!bin/bash") but the execute bit set. It still runs via the C library's execvp() and also via bash (which uses execve() but reimplements the behavior) but not with Python's os.execvp().
Would there be interest in a patch that fixes this?
Someone on Stack Overflow just had a problem where their shell script would work in shell but get OSError: [Errno 8] Exec format error
when calling it with subprocess.call
. I'd say rather fix this (on POSIX platforms).
Why does Python do path resolving on its own anyway? Shouldn't it delegate these all to appropriate execv* variants.
While at it, another POSIX semantic that execvp doesn't support is the behaviour when PATH
is not set, e.g. on Linux, the search path is set to '.', followed by confstr(_CS_PATH). It is debatable whether this is desired (having current directory first in search path doesn't exactly sound right, which is also acknowledged by Linux man pages:
NOTES On some other systems, the default path (used when the environment does not contain the variable PATH) has the current working direc‐ tory listed after /bin and /usr/bin, as an anti-Trojan-horse mea‐ sure. Linux uses here the traditional "current directory first" default path.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields: ```python assignee = None closed_at = None created_at =
labels = ['type-bug', 'library']
title = 'POSIX semantics of PATH search in execvpe is not respected'
updated_at =
user = 'https://bugs.python.org/glondu'
```
bugs.python.org fields:
```python
activity =
actor = 'ztane'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation =
creator = 'glondu'
dependencies = []
files = []
hgrepos = []
issue_num = 19948
keywords = []
message_count = 10.0
messages = ['205819', '205850', '205899', '205900', '205908', '205909', '205910', '279943', '281335', '281338']
nosy_count = 5.0
nosy_names = ['eric.smith', 'r.david.murray', 'ztane', 'glondu', 'Alex Samuel']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue19948'
versions = ['Python 2.7']
```