@@ -965,56 +965,83 @@ pub const ChildProcess = struct {
965
965
const cmd_line_w = try unicode .utf8ToUtf16LeWithNull (self .allocator , cmd_line );
966
966
defer self .allocator .free (cmd_line_w );
967
967
968
- windowsCreateProcess (app_path_w .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo ) catch | no_path_err | {
969
- if (no_path_err != error .FileNotFound and no_path_err != error .InvalidExe ) return no_path_err ;
970
-
971
- const PATH : [:0 ]const u16 = std .os .getenvW (unicode .utf8ToUtf16LeStringLiteral ("PATH" )) orelse &[_ :0 ]u16 {};
972
- const PATHEXT : [:0 ]const u16 = std .os .getenvW (unicode .utf8ToUtf16LeStringLiteral ("PATHEXT" )) orelse &[_ :0 ]u16 {};
973
-
974
- var path_buf = std .ArrayListUnmanaged (u16 ){};
975
- defer path_buf .deinit (self .allocator );
976
-
977
- const app_name = self .argv [0 ];
978
- const app_name_trimmed_w = try unicode .utf8ToUtf16LeWithNull (self .allocator , mem .trimLeft (u8 , app_name , "\\ /" ));
979
- defer self .allocator .free (app_name_trimmed_w );
980
-
981
- var it = mem .tokenize (u16 , PATH , &[_ ]u16 {';' });
982
- retry : while (it .next ()) | search_path | {
983
- path_buf .clearRetainingCapacity ();
984
- const search_path_trimmed = mem .trimRight (u16 , search_path , &[_ ]u16 { '\\ ' , '/' });
985
- try path_buf .appendSlice (self .allocator , search_path_trimmed );
986
- try path_buf .append (self .allocator , fs .path .sep );
987
- try path_buf .appendSlice (self .allocator , app_name_trimmed_w );
988
- try path_buf .append (self .allocator , 0 );
989
- const path_no_ext = path_buf .items [0 .. path_buf .items .len - 1 :0 ];
990
-
991
- if (windowsCreateProcess (path_no_ext .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo )) | _ | {
992
- break :retry ;
993
- } else | err | switch (err ) {
994
- error .FileNotFound , error .AccessDenied , error .InvalidExe = > {},
995
- else = > return err ,
968
+ exec : {
969
+ windowsCreateProcess (app_path_w .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo ) catch | no_path_err | {
970
+ switch (no_path_err ) {
971
+ error .FileNotFound , error .InvalidExe = > {},
972
+ else = > | e | return e ,
996
973
}
997
974
998
- var ext_it = mem .tokenize (u16 , PATHEXT , &[_ ]u16 {';' });
999
- while (ext_it .next ()) | ext | {
1000
- path_buf .shrinkRetainingCapacity (path_no_ext .len );
1001
- try path_buf .appendSlice (self .allocator , ext );
975
+ const PATH : [:0 ]const u16 = std .os .getenvW (unicode .utf8ToUtf16LeStringLiteral ("PATH" )) orelse &[_ :0 ]u16 {};
976
+ const PATHEXT : [:0 ]const u16 = std .os .getenvW (unicode .utf8ToUtf16LeStringLiteral ("PATHEXT" )) orelse &[_ :0 ]u16 {};
977
+
978
+ var path_buf = std .ArrayListUnmanaged (u16 ){};
979
+ defer path_buf .deinit (self .allocator );
980
+
981
+ const app_name = self .argv [0 ];
982
+ const app_name_w = try unicode .utf8ToUtf16LeWithNull (self .allocator , app_name );
983
+ defer self .allocator .free (app_name_w );
984
+
985
+ // If we found an exe but couldn't execute it for whatever reason, then
986
+ // try again with PATHEXT's extensions appended
987
+ if (no_path_err != error .FileNotFound ) {
988
+ try path_buf .appendSlice (self .allocator , app_name_w );
989
+
990
+ var ext_it = mem .tokenize (u16 , PATHEXT , &[_ ]u16 {';' });
991
+ while (ext_it .next ()) | ext | {
992
+ path_buf .shrinkRetainingCapacity (app_name_w .len );
993
+ try path_buf .appendSlice (self .allocator , ext );
994
+ try path_buf .append (self .allocator , 0 );
995
+ const path_with_ext = path_buf .items [0 .. path_buf .items .len - 1 :0 ];
996
+
997
+ if (windowsCreateProcess (path_with_ext .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo )) | _ | {
998
+ break :exec ;
999
+ } else | err | switch (err ) {
1000
+ error .FileNotFound , error .AccessDenied , error .InvalidExe = > {},
1001
+ else = > return err ,
1002
+ }
1003
+ }
1004
+ }
1005
+
1006
+ var it = mem .tokenize (u16 , PATH , &[_ ]u16 {';' });
1007
+ while (it .next ()) | search_path | {
1008
+ path_buf .clearRetainingCapacity ();
1009
+ const search_path_trimmed = mem .trimRight (u16 , search_path , &[_ ]u16 { '\\ ' , '/' });
1010
+ try path_buf .appendSlice (self .allocator , search_path_trimmed );
1011
+ try path_buf .append (self .allocator , fs .path .sep );
1012
+ const app_name_trimmed = mem .trimLeft (u16 , app_name_w , &[_ ]u16 { '\\ ' , '/' });
1013
+ try path_buf .appendSlice (self .allocator , app_name_trimmed );
1002
1014
try path_buf .append (self .allocator , 0 );
1003
- const joined_path = path_buf .items [0 .. path_buf .items .len - 1 :0 ];
1015
+ const path_no_ext = path_buf .items [0 .. path_buf .items .len - 1 :0 ];
1004
1016
1005
- if (windowsCreateProcess (joined_path .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo )) | _ | {
1006
- break :retry ;
1017
+ if (windowsCreateProcess (path_no_ext .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo )) | _ | {
1018
+ break :exec ;
1007
1019
} else | err | switch (err ) {
1008
- error .FileNotFound = > continue ,
1009
- error .AccessDenied = > continue ,
1010
- error .InvalidExe = > continue ,
1020
+ error .FileNotFound , error .AccessDenied , error .InvalidExe = > {},
1011
1021
else = > return err ,
1012
1022
}
1023
+
1024
+ var ext_it = mem .tokenize (u16 , PATHEXT , &[_ ]u16 {';' });
1025
+ while (ext_it .next ()) | ext | {
1026
+ path_buf .shrinkRetainingCapacity (path_no_ext .len );
1027
+ try path_buf .appendSlice (self .allocator , ext );
1028
+ try path_buf .append (self .allocator , 0 );
1029
+ const joined_path = path_buf .items [0 .. path_buf .items .len - 1 :0 ];
1030
+
1031
+ if (windowsCreateProcess (joined_path .ptr , cmd_line_w .ptr , envp_ptr , cwd_w_ptr , & siStartInfo , & piProcInfo )) | _ | {
1032
+ break :exec ;
1033
+ } else | err | switch (err ) {
1034
+ error .FileNotFound = > continue ,
1035
+ error .AccessDenied = > continue ,
1036
+ error .InvalidExe = > continue ,
1037
+ else = > return err ,
1038
+ }
1039
+ }
1040
+ } else {
1041
+ return no_path_err ; // return the original error
1013
1042
}
1014
- } else {
1015
- return no_path_err ; // return the original error
1016
- }
1017
- };
1043
+ };
1044
+ }
1018
1045
1019
1046
if (g_hChildStd_IN_Wr ) | h | {
1020
1047
self .stdin = File { .handle = h };
0 commit comments