mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
windows: workaround kernel race condition in more places
This commit is contained in:
parent
595cd8935a
commit
cc3c4d1069
@ -71,19 +71,7 @@ pub fn main() anyerror!void {
|
||||
try testExec(allocator, "heLLo", "hello from exe\n");
|
||||
|
||||
// now rename the exe to not have an extension
|
||||
{
|
||||
var attempt: u5 = 0;
|
||||
while (true) break tmp.dir.rename("hello.exe", "hello") catch |err| switch (err) {
|
||||
error.AccessDenied => {
|
||||
if (attempt == 13) return error.AccessDenied;
|
||||
// give the kernel a chance to finish closing the executable handle
|
||||
std.os.windows.kernel32.Sleep(@as(u32, 1) << attempt >> 1);
|
||||
attempt += 1;
|
||||
continue;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
try renameExe(tmp.dir, "hello.exe", "hello");
|
||||
|
||||
// with extension should now fail
|
||||
try testExecError(error.FileNotFound, allocator, "hello.exe");
|
||||
@ -91,7 +79,7 @@ pub fn main() anyerror!void {
|
||||
try testExec(allocator, "heLLo", "hello from exe\n");
|
||||
|
||||
try tmp.dir.makeDir("something");
|
||||
try tmp.dir.rename("hello", "something/hello.exe");
|
||||
try renameExe(tmp.dir, "hello", "something/hello.exe");
|
||||
|
||||
const relative_path_no_ext = try std.fs.path.join(allocator, &.{ tmp_relative_path, "something/hello" });
|
||||
defer allocator.free(relative_path_no_ext);
|
||||
@ -118,14 +106,14 @@ pub fn main() anyerror!void {
|
||||
try testExecError(error.InvalidExe, allocator, "hello");
|
||||
|
||||
// If we now rename hello.exe to have no extension, it will behave differently
|
||||
try tmp.dir.rename("hello.exe", "hello");
|
||||
try renameExe(tmp.dir, "hello.exe", "hello");
|
||||
|
||||
// Now, trying to execute it without an extension should treat InvalidExe as recoverable
|
||||
// and skip over it and find hello.bat and execute that
|
||||
try testExec(allocator, "hello", "hello from bat\r\n");
|
||||
|
||||
// If we rename the invalid exe to something else
|
||||
try tmp.dir.rename("hello", "goodbye");
|
||||
try renameExe(tmp.dir, "hello", "goodbye");
|
||||
// Then we should now get FileNotFound when trying to execute 'goodbye',
|
||||
// since that is what the original error will be after searching for 'goodbye'
|
||||
// in the cwd. It will try to execute 'goodbye' from the PATH but the InvalidExe error
|
||||
@ -151,7 +139,7 @@ pub fn main() anyerror!void {
|
||||
try testExec(allocator, "hello", "hello from bat\r\n");
|
||||
|
||||
// If we rename something/hello.exe to something/goodbye.exe
|
||||
try tmp.dir.rename("something/hello.exe", "something/goodbye.exe");
|
||||
try renameExe(tmp.dir, "something/hello.exe", "something/goodbye.exe");
|
||||
// And try to execute goodbye, then the one in something should be found
|
||||
// since the one in cwd is an invalid executable
|
||||
try testExec(allocator, "goodbye", "hello from exe\n");
|
||||
@ -196,7 +184,7 @@ pub fn main() anyerror!void {
|
||||
var subdir_cwd = try tmp.dir.openDir(denormed_something_subdir_wtf8, .{});
|
||||
defer subdir_cwd.close();
|
||||
|
||||
try tmp.dir.rename("something/goodbye.exe", "hello.exe");
|
||||
try renameExe(tmp.dir, "something/goodbye.exe", "hello.exe");
|
||||
try subdir_cwd.setAsCwd();
|
||||
|
||||
// clear the PATH again
|
||||
@ -229,3 +217,17 @@ fn testExecWithCwd(allocator: std.mem.Allocator, command: []const u8, cwd: ?[]co
|
||||
try std.testing.expectEqualStrings("", result.stderr);
|
||||
try std.testing.expectEqualStrings(expected_stdout, result.stdout);
|
||||
}
|
||||
|
||||
fn renameExe(dir: std.fs.Dir, old_sub_path: []const u8, new_sub_path: []const u8) !void {
|
||||
var attempt: u5 = 0;
|
||||
while (true) break dir.rename(old_sub_path, new_sub_path) catch |err| switch (err) {
|
||||
error.AccessDenied => {
|
||||
if (attempt == 13) return error.AccessDenied;
|
||||
// give the kernel a chance to finish closing the executable handle
|
||||
std.os.windows.kernel32.Sleep(@as(u32, 1) << attempt >> 1);
|
||||
attempt += 1;
|
||||
continue;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user