Skip to content

Commit 7b8beb0

Browse files
committed
handle exec errors on linux
1 parent 3d7ff32 commit 7b8beb0

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

runtime/process-posix.c

+22-2
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,10 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
497497
if(has_pipes[i])
498498
if(pipe(pipes[i])) return -1;
499499

500+
//Create error pipe
501+
int errpipe[2];
502+
if(pipe(errpipe) < 0) goto return_error;
503+
500504
// Fork child process
501505
stz_long pid = (stz_long)vfork();
502506
if(pid < 0) return -1;
@@ -507,6 +511,15 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
507511
//Block SIGCHLD until setup is finished.
508512
sigset_t old_signal_mask = block_sigchild();
509513

514+
// Check for exec success
515+
close(errpipe[1]);
516+
int exec_r = 0;
517+
read(errpipe[0], &exec_r, sizeof(int)); // block until read or close
518+
if(exec_r) {
519+
errno = exec_r;
520+
goto return_error;
521+
}
522+
510523
//Cleanup any unneeded process metadata.
511524
remove_dead_child_processes();
512525

@@ -558,6 +571,11 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
558571

559572
// Child: setup pipes, exec
560573
else {
574+
575+
// Error pipe setup
576+
close(errpipe[0]); // close read end of error pipe
577+
if(fcntl(errpipe[1], F_SETFD, FD_CLOEXEC) == -1) exit(-1); // set close-on-exec
578+
561579
//Connect process input pipe if necessary.
562580
if(has_pipes[PROCESS_IN]){
563581
if(close(pipes[PROCESS_IN][1]) < 0) exit(-1);
@@ -590,12 +608,14 @@ stz_int launch_process(stz_byte* file, stz_byte** argvs, stz_int input,
590608

591609
//Launch child process.
592610
//If an environment is supplied then call execvpe, otherwise call execvp.
611+
int exec_r;
593612
if(env_vars == NULL)
594-
execvp(C_CSTR(file), (char**)argvs);
613+
exec_r = execvp(C_CSTR(file), (char**)argvs);
595614
else
596-
execvpe(C_CSTR(file), (char**)argvs, (char**)env_vars);
615+
exec_r = execvpe(C_CSTR(file), (char**)argvs, (char**)env_vars);
597616

598617
//Exit to indicate that execvp did not work.
618+
write(errpipe[1], &exec_r, sizeof(int));
599619
exit(-1);
600620
}
601621
}

0 commit comments

Comments
 (0)