mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Fix for the error codepath in ChildProcess
This commit is contained in:
parent
c257f892fd
commit
9d9b0720f5
@ -282,17 +282,36 @@ pub const ChildProcess = struct {
|
||||
fn cleanupAfterWait(self: *ChildProcess, status: u32) !Term {
|
||||
defer destroyPipe(self.err_pipe);
|
||||
|
||||
// Write maxInt(ErrInt) to the write end of the err_pipe. This is after
|
||||
// waitpid, so this write is guaranteed to be after the child
|
||||
// pid potentially wrote an error. This way we can do a blocking
|
||||
// read on the error pipe and either get maxInt(ErrInt) (no error) or
|
||||
// an error code.
|
||||
try writeIntFd(self.err_pipe[1], maxInt(ErrInt));
|
||||
const err_int = try readIntFd(self.err_pipe[0]);
|
||||
// Here we potentially return the fork child's error
|
||||
// from the parent pid.
|
||||
if (err_int != maxInt(ErrInt)) {
|
||||
return @errSetCast(SpawnError, @intToError(err_int));
|
||||
if (builtin.os == .linux) {
|
||||
var fd = [1]std.os.pollfd{std.os.pollfd{
|
||||
.fd = self.err_pipe[0],
|
||||
.events = std.os.POLLIN,
|
||||
.revents = undefined,
|
||||
}};
|
||||
|
||||
// Check if the eventfd buffer stores a non-zero value by polling
|
||||
// it, that's the error code returned by the child process.
|
||||
_ = std.os.poll(&fd, 0) catch unreachable;
|
||||
|
||||
// According to eventfd(2) the descriptro is readable if the counter
|
||||
// has a value greater than 0
|
||||
if ((fd[0].revents & std.os.POLLIN) != 0) {
|
||||
const err_int = try readIntFd(self.err_pipe[0]);
|
||||
return @errSetCast(SpawnError, @intToError(err_int));
|
||||
}
|
||||
} else {
|
||||
// Write maxInt(ErrInt) to the write end of the err_pipe. This is after
|
||||
// waitpid, so this write is guaranteed to be after the child
|
||||
// pid potentially wrote an error. This way we can do a blocking
|
||||
// read on the error pipe and either get maxInt(ErrInt) (no error) or
|
||||
// an error code.
|
||||
try writeIntFd(self.err_pipe[1], maxInt(ErrInt));
|
||||
const err_int = try readIntFd(self.err_pipe[0]);
|
||||
// Here we potentially return the fork child's error from the parent
|
||||
// pid.
|
||||
if (err_int != maxInt(ErrInt)) {
|
||||
return @errSetCast(SpawnError, @intToError(err_int));
|
||||
}
|
||||
}
|
||||
|
||||
return statusToTerm(status);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user