diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin index 6ce4ece5d..41b46b235 100644 --- a/core/os/os2/process_linux.odin +++ b/core/os/os2/process_linux.odin @@ -61,6 +61,9 @@ _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error) return {}, .Invalid_Dir case .ENOENT: return {}, .Not_Exist + case .NONE: + case: + return {}, _get_platform_error(errno) } defer linux.close(dir_fd) @@ -482,16 +485,31 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) { } linux.close(child_pipe_fds[WRITE]) - defer linux.close(child_pipe_fds[WRITE]) + defer linux.close(child_pipe_fds[READ]) + + process.pid = int(pid) n: int child_byte: [1]u8 - n, errno = linux.read(child_pipe_fds[READ], child_byte[:]) - if errno != .NONE { - return process, _get_platform_error(errno) + errno = .EINTR + for errno == .EINTR { + n, errno = linux.read(child_pipe_fds[READ], child_byte[:]) } + if errno != .NONE { + child_state, _ := process_wait(process, 0) + if child_state.exited { + process.pid = 0 // If the child exited, we reaped it. + return process, _get_platform_error(errno) + } + // else.. something weird happened, but there IS a running process. + // Do not return the read error so the user knows to wait on it. + } + child_errno := linux.Errno(child_byte[0]) if child_errno != .NONE { + // We can assume it trapped here. + _reap_terminated(process) + process.pid = 0 return process, _get_platform_error(child_errno) } @@ -559,6 +577,7 @@ _reap_terminated :: proc(process: Process) -> (state: Process_State, err: Error) switch linux.Sig_Child_Code(info.code) { case .NONE, .CONTINUED, .STOPPED: + unreachable() case .EXITED: state.exited = true state.exit_code = int(info.status)