LibCore: Pass correct number of arguments to the Process on Windows

Incorrect behavior of CreateProcess:
CreateProcess("a.exe", "b c", ...) ->
    a.exe::main::argv == ["b", "c"] (wrong)
CreateProcess(0, "a.exe b c", ...) ->
    a.exe::main::argv == ["a.exe", "b", "c"] (right)

https://learn.microsoft.com/en-us/cpp/cpp/main-function-command-line-args
"If you use both the first and second arguments (lpApplicationName and
lpCommandLine), argv[0] may not be the executable name."

This means first argument of CreateProcess should never be used.
-----------------------------------------------------------------------

Searching for executable in path is suppressed now by prepending "./"

Additional bonus of the new code: .exe extension does not need to be
specified.
This commit is contained in:
stasoid 2024-12-23 18:25:45 +05:00 committed by Andrew Kaster
commit 1173b14c43
Notes: github-actions[bot] 2025-02-06 22:16:22 +00:00

View file

@ -42,12 +42,11 @@ ErrorOr<Process> Process::spawn(ProcessSpawnOptions const& options)
// file actions are not supported
VERIFY(options.file_actions.is_empty());
char const* program_path = 0;
StringBuilder builder;
if (options.search_for_executable_in_path)
builder.appendff("\"{}\" ", options.executable);
if (!options.search_for_executable_in_path && !options.executable.find_any_of("\\/:"sv).has_value())
builder.appendff("\"./{}\" ", options.executable);
else
program_path = options.executable.characters();
builder.appendff("\"{}\" ", options.executable);
builder.join(' ', options.arguments);
builder.append('\0');
@ -59,7 +58,7 @@ ErrorOr<Process> Process::spawn(ProcessSpawnOptions const& options)
PROCESS_INFORMATION process_info = {};
BOOL result = CreateProcess(
program_path,
NULL,
(char*)command_line.data(),
NULL, // process security attributes
NULL, // primary thread security attributes