-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ChildProcess.spawnWindows
: PATH
search fixes + optimizations
#13983
ChildProcess.spawnWindows
: PATH
search fixes + optimizations
#13983
Conversation
…mand For example, if the command is specified as `something.exe`, the retry will now try: ``` C:\some\path\something.exe C:\some\path\something.exe.COM C:\some\path\something.exe.EXE C:\some\path\something.exe.BAT ... etc ... ``` whereas before it would only try the versions with an added extension from `PATHEXT`, which would cause the retry to fail on things that it should find.
…n during FileNotFound recovery Avoid a lot of unnecessary utf8 -> utf16 conversion and use a single ArrayList buffer for all the joined paths instead of a separate allocation for each join
ChildProcess.spawnWindows
: Fix PATH
search when the ext is in the command + optimizationsChildProcess.spawnWindows
: PATH
search fixes + optimizations
Out of curiosity, I wrote a simple benchmark that just calls
Benchmark code: const std = @import("std");
pub fn main() !void {
const allocator = std.heap.c_allocator;
var i: usize = 0;
const iterations = 100;
while (i < iterations) : (i += 1) {
var result = try std.ChildProcess.exec(.{
.allocator = allocator,
.argv = &[_][]const u8{"whoami"},
});
defer allocator.free(result.stdout);
defer allocator.free(result.stderr);
if (result.term != .Exited or result.term.Exited != 0) {
return error.CommandFailed;
}
}
} |
Looking good so far, but this is still missing ci tests (eg. standalone tests in #13639). For the search extensions: Are there use cases, where this is strictly necessary or is this behavior specified somewhere? Which programs are relying on these behavior? More a general question: Can absolute paths still lead to an evaluation of |
Will try to include tests if possible, but might do that in a follow up PR if that's acceptable.
I think you're right to question this, as we currently use Other values in So, I think the best thing to do is to parse As for documentation about how/when to use (for what it's worth, ReactOS doesn't seem to use the
|
…ldProcess.spawnWindows
…T values appended This matches `cmd.exe` behavior. For example, if there is only a file named `mycommand` in the cwd but it is a Linux executable, then running the command `mycommand` will result in: 'mycommand' is not recognized as an internal or external command, operable program or batch file. However, if there is *both* a `mycommand` (that is a Linux executable) and a `mycommand.exe` that is a valid Windows exe, then running the command `mycommand` will successfully run `mycommand.exe`.
ac15404
to
9e8ac2b
Compare
This is good to go unless added tests are required before merging. I'll have a follow up PR with added tests and another that focuses solely on performance improvements. |
Thanks @squeek502! |
Fixes a regression caused by ziglang#13983 From the added comment: We still search the path if the cwd is absolute because of the "cwd set in ChildProcess is in effect when choosing the executable path to match posix semantics" behavior--we don't want to skip searching the PATH just because we were trying to set the cwd of the child process.
Fixes a regression caused by ziglang#13983 From the added comment: We still search the path if the cwd is absolute because of the "cwd set in ChildProcess is in effect when choosing the executable path to match posix semantics" behavior--we don't want to skip searching the PATH just because we were trying to set the cwd of the child process.
Fixes a regression caused by #13983 From the added comment: We still search the path if the cwd is absolute because of the "cwd set in ChildProcess is in effect when choosing the executable path to match posix semantics" behavior--we don't want to skip searching the PATH just because we were trying to set the cwd of the child process.
Note: This is probably best reviewed commit-by-commit, as they could each be a separate PR if I weren't making all the changes at one time.
If the command is specified as
something.exe
, the retry will now try:whereas before it would only try the versions with an added extension from
PATHEXT
, which would cause the retry to fail on things that it should find.Also, I reworked some stuff to drastically reduce the amount of allocations that occur in the
FileNotFound
recovery block when looking throughPATH
.Finally,
CreateProcessW
can now returnerror.InvalidExe
when appropriate, andspawnWindows
has been made to handle it. When the initialwindowsCreateProcess
inspawnWindows
fails witherror.InvalidExe
, it will now retry with the values fromPATHEXT
appended before searching thePATH
.This matches
cmd.exe
behavior. For example, if there is only a file namedmycommand
in the cwd but it is a Linux executable, then running the commandmycommand
will result in:'mycommand' is not recognized as an internal or external command, operable program or batch file.
However, if there is both a
mycommand
(that is a Linux executable) and amycommand.exe
that is a valid Windows exe, then running the commandmycommand
will successfully runmycommand.exe
.Example that demonstrates the path search problem and shows the extent of the reduced allocations:
Before:
After:
However, this is comparing the command not being found with it being found. For completeness, here's an apples-to-apples comparison for the number of allocations when the command is not found:
Note also that the number/size of the allocations saved depends on the number of items within
PATH
andPATHEXT
.