Bug 16502 – spawnProcess does not throw on exec errors
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2016-09-17T00:36:00Z
Last change time
2017-06-25T10:22:53Z
Assigned to
nobody
Creator
freeslave93
Comments
Comment #0 by freeslave93 — 2016-09-17T00:36:52Z
I chose Linux as OS for this issue, but it's legitimate for all Posix.
spawnProcess does not implement proper reporting of errors from exec.
This leads to the situations when execve fails, but spawnProcess does not throw.
spawnProcess has some checks before fork, but these are not enough.
E.g. create empty file and mark it as executable
touch notreallyexecutable
chmod +x notreallyexecutable
Then write D program:
import std.process;
void main(string[] args)
{
spawnProcess(args[1]);
}
Compile and run:
dmd test.d
./test ./notreallyexecutable
It will not throw.
Error reporting can be implemented via pipe. Open pipe on parent side with CLOEXEC. It will be inherited in fork. In case of exec errors write some code to the pipe, e.g. errno code. On success pipe will be closed automatically.
On parent side read from pipe. In case of errors there will be errno code, otherwise nothing.
Comment #1 by b2.temp — 2016-09-17T13:43:16Z
Why should it ?
You can check the exit status, read stderr if your process is piped and throw if you like. As example can you give any language whose the process methods, as implemented in their standard libraries, throw ?
Comment #2 by freeslave93 — 2016-09-17T14:56:55Z
(In reply to b2.temp from comment #1)
> Why should it ?
>
> You can check the exit status, read stderr if your process is piped and
> throw if you like. As example can you give any language whose the process
> methods, as implemented in their standard libraries, throw ?
The example is right in the std.process: spawnProcess throws if file is not executable or working directory does not exist.
Reading stderr and exit status is different from handling the situation where process could not start at all.
Comment #3 by greeenify — 2016-12-27T12:07:57Z
So when I execute the program it prints:
> spawnProcess(): Failed to execute program: Exec format error
from here:
https://github.com/dlang/phobos/blob/3f8298e8531b36dd12420af7ce868e5b2f156f27/std/process.d#L504
If I understand you correctly you want to catch this C API error?
This seems me a very valid enhancement request.
> Error reporting can be implemented via pipe.
Hmm do you know how much overhead this would cost?
(introducing something that increases the cost vs. C API always needs a very good justification)
Comment #4 by freeslave93 — 2016-12-27T18:03:14Z
(In reply to greenify from comment #3)
> So when I execute the program it prints:
>
> > spawnProcess(): Failed to execute program: Exec format error
>
> from here:
>
> https://github.com/dlang/phobos/blob/
> 3f8298e8531b36dd12420af7ce868e5b2f156f27/std/process.d#L504
>
> If I understand you correctly you want to catch this C API error?
> This seems me a very valid enhancement request.
>
> > Error reporting can be implemented via pipe.
>
> Hmm do you know how much overhead this would cost?
> (introducing something that increases the cost vs. C API always needs a very
> good justification)
It prints error, but does not throw exception. Also it obviously will print nothing if stderr was redirected to /dev/null.
I'm not sure about overhead. I just saw similar method in Qt QProcess code.
But what I'm sure about is that this error should be propagated to user right way (which for D is throwing the exception).