File tree Expand file tree Collapse file tree 3 files changed +22
-3
lines changed
test/standalone/windows_spawn Expand file tree Collapse file tree 3 files changed +22
-3
lines changed Original file line number Diff line number Diff line change @@ -1912,6 +1912,7 @@ pub const CreateProcessError = error{
1912
1912
NameTooLong ,
1913
1913
InvalidExe ,
1914
1914
SystemResources ,
1915
+ FileBusy ,
1915
1916
Unexpected ,
1916
1917
};
1917
1918
@@ -1982,6 +1983,7 @@ pub fn CreateProcessW(
1982
1983
.INVALID_PARAMETER = > unreachable ,
1983
1984
.INVALID_NAME = > return error .InvalidName ,
1984
1985
.FILENAME_EXCED_RANGE = > return error .NameTooLong ,
1986
+ .SHARING_VIOLATION = > return error .FileBusy ,
1985
1987
// These are all the system errors that are mapped to ENOEXEC by
1986
1988
// the undocumented _dosmaperr (old CRT) or __acrt_errno_map_os_error
1987
1989
// (newer CRT) functions. Their code can be found in crt/src/dosmap.c (old SDK)
Original file line number Diff line number Diff line change @@ -616,9 +616,19 @@ pub const File = struct {
616
616
& coff .mf
617
617
else
618
618
unreachable ;
619
- mf .file = try base .emit .root_dir .handle .openFile (base .emit .sub_path , .{
619
+ mf .file = for (0 .. 2) | _ | break base .emit .root_dir .handle .openFile (base .emit .sub_path , .{
620
620
.mode = .read_write ,
621
- });
621
+ }) catch | err | switch (err ) {
622
+ error .AccessDenied = > switch (builtin .os .tag ) {
623
+ .windows = > {
624
+ // give the kernel a chance to finish closing the executable handle
625
+ std .os .windows .kernel32 .Sleep (0 );
626
+ continue ;
627
+ },
628
+ else = > return error .AccessDenied ,
629
+ },
630
+ else = > | e | return e ,
631
+ } else return error .AccessDenied ;
622
632
base .file = mf .file ;
623
633
try mf .ensureTotalCapacity (@intCast (mf .nodes .items [0 ].location ().resolve (mf )[1 ]));
624
634
},
Original file line number Diff line number Diff line change @@ -71,7 +71,14 @@ pub fn main() anyerror!void {
71
71
try testExec (allocator , "heLLo" , "hello from exe\n " );
72
72
73
73
// now rename the exe to not have an extension
74
- try tmp .dir .rename ("hello.exe" , "hello" );
74
+ for (0.. 2) | _ | break tmp .dir .rename ("hello.exe" , "hello" ) catch | err | switch (err ) {
75
+ error .AccessDenied = > {
76
+ // give the kernel a chance to finish closing the executable handle
77
+ std .os .windows .kernel32 .Sleep (0 );
78
+ continue ;
79
+ },
80
+ else = > | e | return e ,
81
+ } else return error .AccessDenied ;
75
82
76
83
// with extension should now fail
77
84
try testExecError (error .FileNotFound , allocator , "hello.exe" );
You can’t perform that action at this time.
0 commit comments