@@ -142,7 +142,7 @@ pub const ChildProcess = struct {
142142 if (! windows .TerminateProcess (self .handle , exit_code )) {
143143 const err = windows .GetLastError ();
144144 return switch (err ) {
145- else = > error . Unexpected ,
145+ else = > os . unexpectedErrorWindows ( err ) ,
146146 };
147147 }
148148 self .waitUnwrappedWindows ();
@@ -164,7 +164,7 @@ pub const ChildProcess = struct {
164164 posix .EINVAL = > unreachable ,
165165 posix .EPERM = > error .PermissionDenied ,
166166 posix .ESRCH = > error .ProcessNotFound ,
167- else = > error . Unexpected ,
167+ else = > os . unexpectedErrorPosix ( err ) ,
168168 };
169169 }
170170 self .waitUnwrapped ();
@@ -357,7 +357,7 @@ pub const ChildProcess = struct {
357357 restore_SIGCHLD ();
358358 return switch (pid_err ) {
359359 posix .EAGAIN , posix .ENOMEM , posix .ENOSYS = > error .SystemResources ,
360- else = > error . Unexpected ,
360+ else = > os . unexpectedErrorPosix ( pid_err ) ,
361361 };
362362 }
363363 if (pid_result == 0 ) {
@@ -556,9 +556,6 @@ pub const ChildProcess = struct {
556556 };
557557 var piProcInfo : windows.PROCESS_INFORMATION = undefined ;
558558
559- const app_name = % return cstr .addNullByte (self .allocator , self .argv [0 ]);
560- defer self .allocator .free (app_name );
561-
562559 const cwd_slice = if (self .cwd ) | cwd | {
563560 % return cstr .addNullByte (self .allocator , cwd )
564561 } else {
@@ -575,17 +572,42 @@ pub const ChildProcess = struct {
575572 defer if (maybe_envp_buf ) | envp_buf | self .allocator .free (envp_buf );
576573 const envp_ptr = if (maybe_envp_buf ) | envp_buf | envp_buf .ptr else null ;
577574
578- if (windows .CreateProcessA (app_name .ptr , cmd_line .ptr , null , null , windows .TRUE , 0 ,
579- @ptrCast (? & c_void , envp_ptr ),
580- cwd_ptr , & siStartInfo , & piProcInfo ) == windows .FALSE )
575+ // the cwd set in ChildProcess is in effect when choosing the executable path
576+ // to match posix semantics
577+ const app_name = if (self .cwd ) | cwd | {
578+ const resolved = % return os .path .resolve (self .allocator , cwd , self .argv [0 ]);
579+ defer self .allocator .free (resolved );
580+ % return cstr .addNullByte (self .allocator , resolved )
581+ } else {
582+ % return cstr .addNullByte (self .allocator , self .argv [0 ])
583+ };
584+ defer self .allocator .free (app_name );
585+
586+ windowsCreateProcess (app_name .ptr , cmd_line .ptr , envp_ptr , cwd_ptr ,
587+ & siStartInfo , & piProcInfo ) %% | no_path_err |
581588 {
582- const err = windows .GetLastError ();
583- return switch (err ) {
584- windows .ERROR .FILE_NOT_FOUND = > error .FileNotFound ,
585- windows .ERROR .INVALID_PARAMETER = > unreachable ,
586- else = > error .Unexpected ,
587- };
588- }
589+ if (no_path_err != error .FileNotFound )
590+ return no_path_err ;
591+
592+ const PATH = % return os .getEnvVarOwned (self .allocator , "PATH" );
593+ defer self .allocator .free (PATH );
594+
595+ var it = mem .split (PATH , ";" );
596+ while (it .next ()) | search_path | {
597+ const joined_path = % return os .path .join (self .allocator , search_path , app_name );
598+ defer self .allocator .free (joined_path );
599+
600+ if (windowsCreateProcess (joined_path .ptr , cmd_line .ptr , envp_ptr , cwd_ptr ,
601+ & siStartInfo , & piProcInfo )) | _ |
602+ {
603+ break ;
604+ } else | err | if (err == error .FileNotFound ) {
605+ continue ;
606+ } else {
607+ return err ;
608+ }
609+ }
610+ };
589611
590612 if (stdin_ptr ) | outstream | {
591613 * outstream = io.OutStream {
@@ -633,6 +655,24 @@ pub const ChildProcess = struct {
633655 }
634656};
635657
658+ fn windowsCreateProcess (app_name : & u8 , cmd_line : & u8 , envp_ptr : ? & u8 , cwd_ptr : ? & u8 ,
659+ lpStartupInfo : & windows.STARTUPINFOA , lpProcessInformation : & windows.PROCESS_INFORMATION ) - > % void
660+ {
661+ if (windows .CreateProcessA (app_name , cmd_line , null , null , windows .TRUE , 0 ,
662+ @ptrCast (? & c_void , envp_ptr ), cwd_ptr , lpStartupInfo , lpProcessInformation ) == 0 )
663+ {
664+ const err = windows .GetLastError ();
665+ return switch (err ) {
666+ windows .ERROR .FILE_NOT_FOUND , windows .ERROR .PATH_NOT_FOUND = > error .FileNotFound ,
667+ windows .ERROR .INVALID_PARAMETER = > unreachable ,
668+ else = > os .unexpectedErrorWindows (err ),
669+ };
670+ }
671+ }
672+
673+
674+
675+
636676/// Caller must dealloc.
637677/// Guarantees a null byte at result[result.len].
638678fn windowsCreateCommandLine (allocator : & Allocator , argv : []const []const u8 ) - > % []u8 {
@@ -684,7 +724,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR
684724 if (windows .CreatePipe (rd , wr , sattr , 0 ) == 0 ) {
685725 const err = windows .GetLastError ();
686726 return switch (err ) {
687- else = > error . Unexpected ,
727+ else = > os . unexpectedErrorWindows ( err ) ,
688728 };
689729 }
690730}
@@ -693,7 +733,7 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
693733 if (windows .SetHandleInformation (h , mask , flags ) == 0 ) {
694734 const err = windows .GetLastError ();
695735 return switch (err ) {
696- else = > error . Unexpected ,
736+ else = > os . unexpectedErrorWindows ( err ) ,
697737 };
698738 }
699739}
@@ -724,7 +764,7 @@ fn makePipe() -> %[2]i32 {
724764 if (err > 0 ) {
725765 return switch (err ) {
726766 posix .EMFILE , posix .ENFILE = > error .SystemResources ,
727- else = > error . Unexpected ,
767+ else = > os . unexpectedErrorPosix ( err ) ,
728768 }
729769 }
730770 return fds ;
0 commit comments