@@ -71,27 +71,15 @@ pub fn main() anyerror!void {
7171 try testExec (allocator , "heLLo" , "hello from exe\n " );
7272
7373 // now rename the exe to not have an extension
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- }
74+ try renameExe (tmp .dir , "hello.exe" , "hello" );
8775
8876 // with extension should now fail
8977 try testExecError (error .FileNotFound , allocator , "hello.exe" );
9078 // without extension should succeed (case insensitive)
9179 try testExec (allocator , "heLLo" , "hello from exe\n " );
9280
9381 try tmp .dir .makeDir ("something" );
94- try tmp .dir . rename ( "hello" , "something/hello.exe" );
82+ try renameExe ( tmp .dir , "hello" , "something/hello.exe" );
9583
9684 const relative_path_no_ext = try std .fs .path .join (allocator , &.{ tmp_relative_path , "something/hello" });
9785 defer allocator .free (relative_path_no_ext );
@@ -118,14 +106,14 @@ pub fn main() anyerror!void {
118106 try testExecError (error .InvalidExe , allocator , "hello" );
119107
120108 // If we now rename hello.exe to have no extension, it will behave differently
121- try tmp .dir . rename ( "hello.exe" , "hello" );
109+ try renameExe ( tmp .dir , "hello.exe" , "hello" );
122110
123111 // Now, trying to execute it without an extension should treat InvalidExe as recoverable
124112 // and skip over it and find hello.bat and execute that
125113 try testExec (allocator , "hello" , "hello from bat\r \n " );
126114
127115 // If we rename the invalid exe to something else
128- try tmp .dir . rename ( "hello" , "goodbye" );
116+ try renameExe ( tmp .dir , "hello" , "goodbye" );
129117 // Then we should now get FileNotFound when trying to execute 'goodbye',
130118 // since that is what the original error will be after searching for 'goodbye'
131119 // 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 {
151139 try testExec (allocator , "hello" , "hello from bat\r \n " );
152140
153141 // If we rename something/hello.exe to something/goodbye.exe
154- try tmp .dir . rename ( "something/hello.exe" , "something/goodbye.exe" );
142+ try renameExe ( tmp .dir , "something/hello.exe" , "something/goodbye.exe" );
155143 // And try to execute goodbye, then the one in something should be found
156144 // since the one in cwd is an invalid executable
157145 try testExec (allocator , "goodbye" , "hello from exe\n " );
@@ -196,7 +184,7 @@ pub fn main() anyerror!void {
196184 var subdir_cwd = try tmp .dir .openDir (denormed_something_subdir_wtf8 , .{});
197185 defer subdir_cwd .close ();
198186
199- try tmp .dir . rename ( "something/goodbye.exe" , "hello.exe" );
187+ try renameExe ( tmp .dir , "something/goodbye.exe" , "hello.exe" );
200188 try subdir_cwd .setAsCwd ();
201189
202190 // clear the PATH again
@@ -229,3 +217,17 @@ fn testExecWithCwd(allocator: std.mem.Allocator, command: []const u8, cwd: ?[]co
229217 try std .testing .expectEqualStrings ("" , result .stderr );
230218 try std .testing .expectEqualStrings (expected_stdout , result .stdout );
231219}
220+
221+ fn renameExe (dir : std.fs.Dir , old_sub_path : []const u8 , new_sub_path : []const u8 ) ! void {
222+ var attempt : u5 = 0 ;
223+ while (true ) break dir .rename (old_sub_path , new_sub_path ) catch | err | switch (err ) {
224+ error .AccessDenied = > {
225+ if (attempt == 13 ) return error .AccessDenied ;
226+ // give the kernel a chance to finish closing the executable handle
227+ std .os .windows .kernel32 .Sleep (@as (u32 , 1 ) << attempt >> 1 );
228+ attempt += 1 ;
229+ continue ;
230+ },
231+ else = > | e | return e ,
232+ };
233+ }
0 commit comments