Selaa lähdekoodia

fix error handling; close read end of the child pipe instead of the write end twice

jason 1 vuosi sitten
vanhempi
commit
f7a73b9555
1 muutettua tiedostoa jossa 22 lisäystä ja 3 poistoa
  1. 22 3
      core/os/os2/process_linux.odin

+ 22 - 3
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[:])
+	errno = .EINTR
+	for errno == .EINTR {
+		n, errno = linux.read(child_pipe_fds[READ], child_byte[:])
+	}
 	if errno != .NONE {
-		return process, _get_platform_error(errno)
+		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)