Просмотр исходного кода

Merge pull request #5127 from laytan/fix-process-windows-handles-handling

Fix process windows handles handling
Laytan 4 месяцев назад
Родитель
Сommit
7c1a9f1e7a

+ 1 - 12
core/os/os2/process.odin

@@ -264,7 +264,7 @@ specific process, even after it has died.
 **Note(linux)**: The `handle` will be referring to pidfd.
 */
 Process :: struct {
-	pid: int,
+	pid:    int,
 	handle: uintptr,
 }
 
@@ -290,21 +290,10 @@ process_open :: proc(pid: int, flags := Process_Open_Flags {}) -> (Process, Erro
 	return _process_open(pid, flags)
 }
 
-
-/*
-OS-specific process attributes.
-*/
-Process_Attributes :: struct {
-	sys_attr: _Sys_Process_Attributes,
-}
-
 /*
 	The description of how a process should be created.
 */
 Process_Desc :: struct {
-	// OS-specific attributes.
-	sys_attr: Process_Attributes,
-
 	// The working directory of the process. If the string has length 0, the
 	// working directory is assumed to be the current working directory of the
 	// current process.

+ 0 - 3
core/os/os2/process_linux.odin

@@ -390,9 +390,6 @@ _process_open :: proc(pid: int, _: Process_Open_Flags) -> (process: Process, err
 	return
 }
 
-@(private="package")
-_Sys_Process_Attributes :: struct {}
-
 @(private="package")
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	TEMP_ALLOCATOR_GUARD()

+ 0 - 2
core/os/os2/process_posix.odin

@@ -46,8 +46,6 @@ _current_process_info :: proc(selection: Process_Info_Fields, allocator: runtime
 	return _process_info_by_pid(_get_pid(), selection, allocator)
 }
 
-_Sys_Process_Attributes :: struct {}
-
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	if len(desc.command) == 0 {
 		err = .Invalid_Path

+ 0 - 2
core/os/os2/process_wasi.odin

@@ -44,8 +44,6 @@ _current_process_info :: proc(selection: Process_Info_Fields, allocator: runtime
 	return
 }
 
-_Sys_Process_Attributes :: struct {}
-
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	err = .Unsupported
 	return

+ 38 - 9
core/os/os2/process_windows.odin

@@ -417,9 +417,6 @@ _process_open :: proc(pid: int, flags: Process_Open_Flags) -> (process: Process,
 	return
 }
 
-@(private="package")
-_Sys_Process_Attributes :: struct {}
-
 @(private="package")
 _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	TEMP_ALLOCATOR_GUARD()
@@ -431,17 +428,49 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
 	}
 	environment_block   := _build_environment_block(environment, temp_allocator())
 	environment_block_w := win32_utf8_to_utf16(environment_block, temp_allocator()) or_return
-	stderr_handle       := win32.GetStdHandle(win32.STD_ERROR_HANDLE)
-	stdout_handle       := win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)
-	stdin_handle        := win32.GetStdHandle(win32.STD_INPUT_HANDLE)
 
-	if desc.stdout != nil {
+	stderr_handle: win32.HANDLE	
+	stdout_handle: win32.HANDLE	
+	stdin_handle:  win32.HANDLE	
+
+	null_handle: win32.HANDLE
+	if desc.stdout == nil || desc.stderr == nil || desc.stdin == nil {
+		null_handle = win32.CreateFileW(
+			win32.L("NUL"),
+			win32.GENERIC_READ|win32.GENERIC_WRITE,
+			win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE,
+			&win32.SECURITY_ATTRIBUTES{
+				nLength        = size_of(win32.SECURITY_ATTRIBUTES),
+				bInheritHandle = true,
+			},
+			win32.OPEN_EXISTING,
+			win32.FILE_ATTRIBUTE_NORMAL,
+			nil,
+		)
+		// Opening NUL should always succeed.
+		assert(null_handle != nil)
+	}
+	// NOTE(laytan): I believe it is fine to close this handle right after CreateProcess,
+	// and we don't have to hold onto this until the process exits.
+	defer if null_handle != nil {
+		win32.CloseHandle(null_handle)
+	}
+
+	if desc.stdout == nil {
+		stdout_handle = null_handle
+	} else {
 		stdout_handle = win32.HANDLE((^File_Impl)(desc.stdout.impl).fd)
 	}
-	if desc.stderr != nil {
+
+	if desc.stderr == nil {
+		stderr_handle = null_handle
+	} else {
 		stderr_handle = win32.HANDLE((^File_Impl)(desc.stderr.impl).fd)
 	}
-	if desc.stdin != nil {
+
+	if desc.stdin == nil {
+		stdin_handle = null_handle
+	} else {
 		stdin_handle = win32.HANDLE((^File_Impl)(desc.stdin.impl).fd)
 	}