Unix grump: if you 'exec' a script whose interpreter can't be found, you get ENOENT, which is exactly the same error code as if the script file itself wasn't there.
-
Unix grump: if you 'exec' a script whose interpreter can't be found, you get ENOENT, which is exactly the same error code as if the script file itself wasn't there.
So if I prepend a directory to PATH containing a script I want to use instead of /usr/bin/foo, and the script has this problem, execvp() won't even notice – it just execs each $dir/foo until one doesn't give ENOENT – and my replacement will be _silently_ ignored, instead of telling me about the error. Arrgh!
-
@simontatham Yeah, that's not a well-considered part of the specification.
-
@riley I keep thinking that I wish kernel error codes were more like an algebraic type, with each errno value carrying a different set of associated data items.
ENOENT should explain which component of the pathname didn't exist, e.g. open("foo/bar/baz") might give ENOENT("foo/bar"). If rename(2) fails it should say whether the source file or destination dir didn't exist; for a script exec, it should distinguish nonexistence of the script from the interpreter.
And similarly for other errnos.
-
@simontatham I mostly run into it outside kernel, but I'd really like an error system to be able to encode multiple levels of an error at once, such as both "Could not load the source code" and "Attempting to open file xxx.c failed with
ELOOP
.