From ce158f26b9136b3fc831c6325ad911e3bf403a4b Mon Sep 17 00:00:00 2001 From: pommicket Date: Mon, 9 Jan 2023 14:02:02 -0500 Subject: switch from CreateProcessA to CreateProcessW --- main.c | 3 +-- os-win.c | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 7ee9bfc..8e95cdc 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,6 @@ /* @TODO: -- switch to CreateProcessW -- why are all requests failing? +- why are all requests failing on windows? - are we freeing process if process_run(_ex) fails? - test time_last_modified (windows) - some way of opening + closing all C files in directory for clangd diff --git a/os-win.c b/os-win.c index e641c8c..8dd8ce8 100644 --- a/os-win.c +++ b/os-win.c @@ -190,7 +190,21 @@ static void get_last_error_str(char *out, size_t out_sz) { Process *process_run_ex(const char *command, const ProcessSettings *settings) { // thanks to https://devblogs.microsoft.com/oldnewthing/20131209-00/?p=2433 for the job code Process *process = calloc(1, sizeof *process); - char *command_line = str_dup(command); + WCHAR *command_line = calloc(strlen(command) + 1, sizeof *command_line); + if (MultiByteToWideChar(CP_UTF8, 0, command, -1, command_line, (int)strlen(command) + 1) == 0) { + strbuf_printf(process->error, "Bad UTF-8 in command."); + return process; + } + WCHAR wdbuf[4100]; + const WCHAR *working_directory = NULL; + if (settings->working_directory) { + if (MultiByteToWideChar(CP_UTF8, 0, settings->working_directory, -1, wdbuf, (int)arr_count(wdbuf)) == 0) { + strbuf_printf(process->error, "Bad UTF-8 in working directory."); + return process; + } + working_directory = wdbuf; + } + // we need to create a "job" for this, because when you kill a process on windows, // all its children just keep going. so cmd.exe would die, but not the actual build process. @@ -211,15 +225,15 @@ Process *process_run_ex(const char *command, const ProcessSettings *settings) { created_pipes &= CreatePipe(&pipe_stderr_read, &pipe_stderr_write, &security_attrs, 0) != 0; if (created_pipes) { - STARTUPINFOA startup = {sizeof(STARTUPINFOA)}; + STARTUPINFOW startup = {sizeof(STARTUPINFOW)}; startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; startup.hStdOutput = pipe_stdout_write; startup.hStdError = settings->separate_stderr ? pipe_stderr_write : pipe_stdout_write; startup.hStdInput = pipe_stdin_read; startup.wShowWindow = SW_HIDE; PROCESS_INFORMATION *process_info = &process->process_info; - if (CreateProcessA(NULL, command_line, NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, - NULL, settings->working_directory, &startup, process_info)) { + if (CreateProcessW(NULL, command_line, NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, + NULL, working_directory, &startup, process_info)) { // create a suspended process, add it to the job, then resume (unsuspend) the process if (AssignProcessToJobObject(job, process_info->hProcess)) { if (ResumeThread(process_info->hThread) != (DWORD)-1) { -- cgit v1.2.3