| author | |
| committer | |
| log | 958faa7031c7b50a544e151fea4d486e1c4926c1 |
| tree | eeb3f0238b95ec4c6fd1647798ae877b4701873c |
| parent | ea694bfdb762a4dd18654c73aaaaf1b917d99cc3 |
2 files changed, 19 insertions(+), 11 deletions(-)
src/link.zig+6-3| ... | ... | @@ -616,19 +616,22 @@ pub const File = struct { |
| 616 | 616 | &coff.mf |
| 617 | 617 | else |
| 618 | 618 | unreachable; |
| 619 | mf.file = for (0..10) |_| break base.emit.root_dir.handle.openFile(base.emit.sub_path, .{ | |
| 619 | var attempt: u5 = 0; | |
| 620 | mf.file = while (true) break base.emit.root_dir.handle.openFile(base.emit.sub_path, .{ | |
| 620 | 621 | .mode = .read_write, |
| 621 | 622 | }) catch |err| switch (err) { |
| 622 | 623 | error.AccessDenied => switch (builtin.os.tag) { |
| 623 | 624 | .windows => { |
| 625 | if (attempt == 13) return error.AccessDenied; | |
| 624 | 626 | // give the kernel a chance to finish closing the executable handle |
| 625 | std.os.windows.kernel32.Sleep(10); | |
| 627 | std.os.windows.kernel32.Sleep(@as(u32, 1) << attempt >> 1); | |
| 628 | attempt += 1; | |
| 626 | 629 | continue; |
| 627 | 630 | }, |
| 628 | 631 | else => return error.AccessDenied, |
| 629 | 632 | }, |
| 630 | 633 | else => |e| return e, |
| 631 | } else return error.AccessDenied; | |
| 634 | }; | |
| 632 | 635 | base.file = mf.file; |
| 633 | 636 | try mf.ensureTotalCapacity(@intCast(mf.nodes.items[0].location().resolve(mf)[1])); |
| 634 | 637 | }, |
test/standalone/windows_spawn/main.zig+13-8| ... | ... | @@ -71,14 +71,19 @@ 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 | for (0..10) |_| 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(10); | |
| 78 | continue; | |
| 79 | }, | |
| 80 | else => |e| return e, | |
| 81 | } else return error.AccessDenied; | |
| 74 | { | |
| 75 | var attempt: u5 = 0; | |
| 76 | while (true) break tmp.dir.rename("hello.exe", "hello") catch |err| switch (err) { | |
| 77 | error.AccessDenied => { | |
| 78 | if (attempt == 13) return error.AccessDenied; | |
| 79 | // give the kernel a chance to finish closing the executable handle | |
| 80 | std.os.windows.kernel32.Sleep(@as(u32, 1) << attempt >> 1); | |
| 81 | attempt += 1; | |
| 82 | continue; | |
| 83 | }, | |
| 84 | else => |e| return e, | |
| 85 | }; | |
| 86 | } | |
| 82 | 87 | |
| 83 | 88 | // with extension should now fail |
| 84 | 89 | try testExecError(error.FileNotFound, allocator, "hello.exe"); |