mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-18 17:08:21 +00:00
More clean up for process_windows.odin
This commit is contained in:
@@ -57,19 +57,23 @@ _get_ppid :: proc() -> int {
|
||||
}
|
||||
|
||||
@(private="package")
|
||||
_process_list :: proc(allocator: runtime.Allocator) -> ([]int, Error) {
|
||||
pid_list := make([dynamic]int, allocator)
|
||||
_process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error) {
|
||||
snap := win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPPROCESS, 0)
|
||||
if snap == win32.INVALID_HANDLE_VALUE {
|
||||
return pid_list[:], _get_platform_error()
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
entry := win32.PROCESSENTRY32W { dwSize = size_of(win32.PROCESSENTRY32W) }
|
||||
|
||||
list_d := make([dynamic]int, allocator) or_return
|
||||
|
||||
entry := win32.PROCESSENTRY32W{dwSize = size_of(win32.PROCESSENTRY32W)}
|
||||
status := win32.Process32FirstW(snap, &entry)
|
||||
for status {
|
||||
append(&pid_list, int(entry.th32ProcessID))
|
||||
append(&list_d, int(entry.th32ProcessID))
|
||||
status = win32.Process32NextW(snap, &entry)
|
||||
}
|
||||
return pid_list[:], nil
|
||||
list = list_d[:]
|
||||
return
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
@@ -160,7 +164,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
|
||||
|
||||
if .Command_Line in selection || .Command_Args in selection {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator())
|
||||
cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator()) or_return
|
||||
_ = read_memory_as_slice(ph, process_params.CommandLine.Buffer, cmdline_w) or_return
|
||||
|
||||
if .Command_Line in selection {
|
||||
@@ -177,7 +181,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
|
||||
if .Environment in selection {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
env_len := process_params.EnvironmentSize / 2
|
||||
envs_w := make([]u16, env_len, temp_allocator())
|
||||
envs_w := make([]u16, env_len, temp_allocator()) or_return
|
||||
_ = read_memory_as_slice(ph, process_params.Environment, envs_w) or_return
|
||||
|
||||
envs := _parse_environment_block(raw_data(envs_w), allocator) or_return
|
||||
@@ -187,7 +191,7 @@ _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator
|
||||
}
|
||||
if .Working_Dir in selection {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator())
|
||||
cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator()) or_return
|
||||
_ = read_memory_as_slice(ph, process_params.CurrentDirectoryPath.Buffer, cwd_w) or_return
|
||||
|
||||
cwd := win32.utf16_to_utf8(cwd_w, allocator) or_return
|
||||
@@ -262,7 +266,7 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
|
||||
|
||||
if .Command_Line in selection || .Command_Args in selection {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator())
|
||||
cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator()) or_return
|
||||
_ = read_memory_as_slice(ph, process_params.CommandLine.Buffer, cmdline_w) or_return
|
||||
|
||||
if .Command_Line in selection {
|
||||
@@ -281,7 +285,7 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
|
||||
if .Environment in selection {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
env_len := process_params.EnvironmentSize / 2
|
||||
envs_w := make([]u16, env_len, temp_allocator())
|
||||
envs_w := make([]u16, env_len, temp_allocator()) or_return
|
||||
_ = read_memory_as_slice(ph, process_params.Environment, envs_w) or_return
|
||||
|
||||
envs := _parse_environment_block(raw_data(envs_w), allocator) or_return
|
||||
@@ -291,7 +295,7 @@ _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields
|
||||
|
||||
if .Working_Dir in selection {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator())
|
||||
cwd_w := make([]u16, process_params.CurrentDirectoryPath.Length, temp_allocator()) or_return
|
||||
_ = read_memory_as_slice(ph, process_params.CurrentDirectoryPath.Buffer, cwd_w) or_return
|
||||
|
||||
cwd := win32.utf16_to_utf8(cwd_w, allocator) or_return
|
||||
@@ -399,9 +403,9 @@ _process_open :: proc(pid: int, flags: Process_Open_Flags) -> (process: Process,
|
||||
_Sys_Process_Attributes :: struct {}
|
||||
|
||||
@(private="package")
|
||||
_process_start :: proc(desc: Process_Desc) -> (Process, Error) {
|
||||
_process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
command_line := _build_command_line(desc.command, temp_allocator())
|
||||
command_line := _build_command_line(desc.command, temp_allocator())
|
||||
command_line_w := win32.utf8_to_wstring(command_line, temp_allocator())
|
||||
environment := desc.env
|
||||
if desc.env == nil {
|
||||
@@ -412,6 +416,7 @@ _process_start :: proc(desc: Process_Desc) -> (Process, Error) {
|
||||
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 {
|
||||
stdout_handle = win32.HANDLE((^File_Impl)(desc.stdout.impl).fd)
|
||||
}
|
||||
@@ -421,12 +426,10 @@ _process_start :: proc(desc: Process_Desc) -> (Process, Error) {
|
||||
if desc.stdin != nil {
|
||||
stdin_handle = win32.HANDLE((^File_Impl)(desc.stderr.impl).fd)
|
||||
}
|
||||
working_dir_w := win32.wstring(nil)
|
||||
if len(desc.working_dir) > 0 {
|
||||
working_dir_w = win32.utf8_to_wstring(desc.working_dir, temp_allocator())
|
||||
}
|
||||
|
||||
working_dir_w := win32.utf8_to_wstring(desc.working_dir, temp_allocator()) if len(desc.working_dir) > 0 else nil
|
||||
process_info: win32.PROCESS_INFORMATION
|
||||
process_ok := win32.CreateProcessW(
|
||||
ok := win32.CreateProcessW(
|
||||
nil,
|
||||
command_line_w,
|
||||
nil,
|
||||
@@ -435,30 +438,29 @@ _process_start :: proc(desc: Process_Desc) -> (Process, Error) {
|
||||
win32.CREATE_UNICODE_ENVIRONMENT|win32.NORMAL_PRIORITY_CLASS,
|
||||
raw_data(environment_block_w),
|
||||
working_dir_w,
|
||||
&win32.STARTUPINFOW {
|
||||
&win32.STARTUPINFOW{
|
||||
cb = size_of(win32.STARTUPINFOW),
|
||||
hStdError = stderr_handle,
|
||||
hStdError = stderr_handle,
|
||||
hStdOutput = stdout_handle,
|
||||
hStdInput = stdin_handle,
|
||||
hStdInput = stdin_handle,
|
||||
dwFlags = win32.STARTF_USESTDHANDLES,
|
||||
},
|
||||
&process_info,
|
||||
)
|
||||
if !process_ok {
|
||||
return {}, _get_platform_error()
|
||||
if !ok {
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
return Process {
|
||||
pid = int(process_info.dwProcessId),
|
||||
handle = uintptr(process_info.hProcess),
|
||||
}, nil
|
||||
process = {pid = int(process_info.dwProcessId), handle = uintptr(process_info.hProcess)}
|
||||
return
|
||||
}
|
||||
|
||||
@(private="package")
|
||||
_process_wait :: proc(process: Process, timeout: time.Duration) -> (process_state: Process_State, err: Error) {
|
||||
handle := win32.HANDLE(process.handle)
|
||||
timeout_ms := u32(timeout / time.Millisecond) if timeout > 0 else win32.INFINITE
|
||||
wait_result := win32.WaitForSingleObject(handle, timeout_ms)
|
||||
switch wait_result {
|
||||
timeout_ms := u32(timeout / time.Millisecond) if timeout >= 0 else win32.INFINITE
|
||||
|
||||
switch win32.WaitForSingleObject(handle, timeout_ms) {
|
||||
case win32.WAIT_OBJECT_0:
|
||||
exit_code: u32
|
||||
if !win32.GetExitCodeProcess(handle, &exit_code) {
|
||||
@@ -516,26 +518,24 @@ _filetime_to_duration :: proc(filetime: win32.FILETIME) -> time.Duration {
|
||||
return time.Duration(ticks * 100)
|
||||
}
|
||||
|
||||
_process_entry_by_pid :: proc(pid: int) -> (win32.PROCESSENTRY32W, Error) {
|
||||
_process_entry_by_pid :: proc(pid: int) -> (entry: win32.PROCESSENTRY32W, err: Error) {
|
||||
snap := win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPPROCESS, 0)
|
||||
if snap == win32.INVALID_HANDLE_VALUE {
|
||||
return {}, _get_platform_error()
|
||||
err = _get_platform_error()
|
||||
return
|
||||
}
|
||||
defer win32.CloseHandle(snap)
|
||||
entry := win32.PROCESSENTRY32W { dwSize = size_of(win32.PROCESSENTRY32W) }
|
||||
|
||||
entry = win32.PROCESSENTRY32W{dwSize = size_of(win32.PROCESSENTRY32W)}
|
||||
status := win32.Process32FirstW(snap, &entry)
|
||||
found := false
|
||||
for status {
|
||||
if u32(pid) == entry.th32ProcessID {
|
||||
found = true
|
||||
break
|
||||
return
|
||||
}
|
||||
status = win32.Process32NextW(snap, &entry)
|
||||
}
|
||||
if !found {
|
||||
return {}, General_Error.Not_Exist
|
||||
}
|
||||
return entry, nil
|
||||
err = General_Error.Not_Exist
|
||||
return
|
||||
}
|
||||
|
||||
// Note(flysand): Not sure which way it's better to get the executable path:
|
||||
@@ -580,7 +580,7 @@ _get_process_user :: proc(process_handle: win32.HANDLE, allocator: runtime.Alloc
|
||||
}
|
||||
err = nil
|
||||
}
|
||||
token_user := (^win32.TOKEN_USER)(raw_data(make([]u8, token_user_size, temp_allocator())))
|
||||
token_user := (^win32.TOKEN_USER)(raw_data(make([]u8, token_user_size, temp_allocator()) or_return))
|
||||
if !win32.GetTokenInformation(token_handle, .TokenUser, token_user, token_user_size, &token_user_size) {
|
||||
err = _get_platform_error()
|
||||
return
|
||||
@@ -701,22 +701,17 @@ _parse_environment_block :: proc(block: [^]u16, allocator: runtime.Allocator) ->
|
||||
|
||||
_build_environment_block :: proc(environment: []string, allocator: runtime.Allocator) -> string {
|
||||
builder := strings.builder_make(allocator)
|
||||
#reverse for kv, cur_idx in environment {
|
||||
loop: #reverse for kv, cur_idx in environment {
|
||||
eq_idx := strings.index_byte(kv, '=')
|
||||
assert(eq_idx >= 0, "Malformed environment string. Expected '=' to separate keys and values")
|
||||
key := kv[:eq_idx]
|
||||
already_handled := false
|
||||
for old_kv in environment[cur_idx+1:] {
|
||||
old_key := old_kv[:strings.index_byte(old_kv, '=')]
|
||||
if key == old_key {
|
||||
already_handled = true
|
||||
break
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
if already_handled {
|
||||
continue
|
||||
}
|
||||
strings.write_bytes(&builder, transmute([]byte) kv)
|
||||
strings.write_string(&builder, kv)
|
||||
strings.write_byte(&builder, 0)
|
||||
}
|
||||
// Note(flysand): In addition to the NUL-terminator for each string, the
|
||||
|
||||
Reference in New Issue
Block a user