From 3251df6068abddc55917aa1b5c9cc93aa4ecd193 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Mon, 12 Aug 2024 08:12:30 +0200 Subject: [PATCH] ExecAndWait --- src/basic/filesystem.h | 2 ++ src/basic/win32.cpp | 11 ++++++++++- src/text_editor/buffer.cpp | 5 +++++ src/text_editor/process.cpp | 29 +++++++++++++++++++++++++---- src/text_editor/text_editor.h | 1 + src/text_editor/todo.txt | 1 - 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/basic/filesystem.h b/src/basic/filesystem.h index 5aa6249..96aa11c 100644 --- a/src/basic/filesystem.h +++ b/src/basic/filesystem.h @@ -42,6 +42,7 @@ struct StdoutPollInfo { struct Process { bool is_valid; String error_message; + bool exited; int exit_code; char platform[6 * 8]; @@ -52,5 +53,6 @@ struct Process { Process CreateCommandLineProcess(String command_line, String working_dir); bool WaitForExit(Process *process); bool PollExitCode(Process *process); +void CloseProcess(Process *process); void KillProcess(Process *process); StdoutPollInfo PollStdout(Process *process, char *buffer, int64_t buffer_size); \ No newline at end of file diff --git a/src/basic/win32.cpp b/src/basic/win32.cpp index ac5d1cd..0b931ae 100644 --- a/src/basic/win32.cpp +++ b/src/basic/win32.cpp @@ -396,6 +396,7 @@ Process CreateCommandLineProcess(String command_line, String working_dir) { bool PollExitCode(Process *process) { Assert(process->is_valid); Win32Process *p = (Win32Process *)process->platform; + if (process->exited) return process->exited; if (WaitForSingleObject(p->handle, 0) != WAIT_OBJECT_0) { return false; @@ -407,11 +408,15 @@ bool PollExitCode(Process *process) { exit_code = -1; } + process->exited = true; process->exit_code = (int)exit_code; - Win32CloseProcess(process); return true; } +void CloseProcess(Process *process) { + Win32CloseProcess(process); +} + void KillProcess(Process *process) { Assert(process->is_valid); Win32Process *p = (Win32Process *)process->platform; @@ -437,6 +442,10 @@ StdoutPollInfo PollStdout(Process *process, char *buffer, int64_t buffer_size) { return result; } + if (!buffer) { + return {0, bytes_avail}; + } + if (bytes_avail == 0) { return result; } diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index aa42530..c9dfd10 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -114,6 +114,11 @@ void IKnowWhatImDoing_Append(Buffer *buffer, String16 string) { IKnowWhatImDoing_ReplaceText(buffer, GetEndAsRange(*buffer), string); } +void IKnowWhatImDoing_Append(Buffer *buffer, String string) { + Scratch scratch; + IKnowWhatImDoing_Append(buffer, ToString16(scratch, string)); +} + void IKnowWhatImDoing_Appendf(Buffer *buffer, const char *fmt, ...) { Scratch scratch; STRING_FORMAT(scratch, fmt, string); diff --git a/src/text_editor/process.cpp b/src/text_editor/process.cpp index d0f458b..cb568d8 100644 --- a/src/text_editor/process.cpp +++ b/src/text_editor/process.cpp @@ -20,6 +20,7 @@ void UpdateProcesses() { bool exited = PollExitCode(&it); if (exited) { + CloseProcess(&it); remove_item = true; String s = Format(scratch, "exited with code: %d", it.exit_code); Command_Append(view_id, s, it.scroll_to_end); @@ -32,10 +33,9 @@ void Exec(ViewID view, bool scroll_to_end, String cmd, String working_dir) { if (process.error_message.len) Command_Append(view, process.error_message, process.scroll_to_end); process.view_id = view.id; process.scroll_to_end = scroll_to_end; - if (process.is_valid) { - Assert(process.error_message.len == 0); - Add(&ActiveProcesses, process); - } + if (!process.is_valid) return; + Assert(process.error_message.len == 0); + Add(&ActiveProcesses, process); } void Exec(ViewID view, bool scroll_to_end, String16 cmd16, String working_dir) { @@ -44,6 +44,27 @@ void Exec(ViewID view, bool scroll_to_end, String16 cmd16, String working_dir) { Exec(view, scroll_to_end, cmd, working_dir); } +Buffer *ExecAndWait(Allocator allocator, String cmd, String working_dir) { + Process process = CreateCommandLineProcess(cmd, working_dir); + if (process.error_message.len) ReportWarningf("%.*s", FmtString(process.error_message)); + if (!process.is_valid) return {}; + + Scratch scratch; + Buffer *temp_buffer = CreateTempBuffer(allocator, 4096 * 2); + char *buffer = AllocArray(scratch, char, 4096); + for (;;) { + bool exited = PollExitCode(&process); + StdoutPollInfo i0 = PollStdout(&process, buffer, 4096); + IKnowWhatImDoing_Append(temp_buffer, String{buffer, i0.size_read}); + if (exited && i0.size_available == 0) { + CloseProcess(&process); + break; + } + } + + return temp_buffer; +} + void KillProcess(ViewID view) { IterRemove(ActiveProcesses) { IterRemovePrepare(ActiveProcesses); diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 871ad6b..1b98b40 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -128,6 +128,7 @@ void Command_SelectRangeOneCursor(View *view, Range range); void Command_Append(ViewID view_id, String16 string, bool scroll_to_end_if_cursor_on_last_line); void Command_Append(ViewID view_id, String string, bool scroll_to_end_if_cursor_on_last_line); +void ReportConsolef(const char *fmt, ...); void ReportErrorf(const char *fmt, ...); void ReportWarningf(const char *fmt, ...); diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index 1bab0f9..2a9af4c 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -10,7 +10,6 @@ - Change mouse keybindings again (left+ctrl could be load - left+ctrl could be add new cursor), exec could be middle mouse - Store editor metadata in user accessible buffers? (read only) - Find matches using grep, change things in that buffer then apply those changes to all items -- assert buffer name unique when createing and changing name - apply clang format - apply clang format on save