diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 98995981b..3c84f3539 100644 --- a/core/os/os2/process.odin +++ b/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. diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin index 1480e66b5..afb398c8d 100644 --- a/core/os/os2/process_linux.odin +++ b/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() diff --git a/core/os/os2/process_posix.odin b/core/os/os2/process_posix.odin index cd451781f..6070b19d6 100644 --- a/core/os/os2/process_posix.odin +++ b/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 diff --git a/core/os/os2/process_wasi.odin b/core/os/os2/process_wasi.odin index 6ebfe3788..9f4d61649 100644 --- a/core/os/os2/process_wasi.odin +++ b/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 diff --git a/core/os/os2/process_windows.odin b/core/os/os2/process_windows.odin index 536930ee1..69764dff7 100644 --- a/core/os/os2/process_windows.odin +++ b/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) }