X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fruntime%2Frun-program.c;h=57df79a5969e1eb0e84a14c99f37cfd518cc6693;hb=ba39d165a0bb6fabba6d6feb9b6fb88ae4d544ff;hp=ef9c51cb0f57d2e77d434b6790bcffd25c700602;hpb=26ac616b6783b8841ccda8b4f1caa7d898d91b86;p=sbcl.git diff --git a/src/runtime/run-program.c b/src/runtime/run-program.c index ef9c51c..57df79a 100644 --- a/src/runtime/run-program.c +++ b/src/runtime/run-program.c @@ -100,12 +100,13 @@ set_pty(char *pty_name) extern char **environ; int spawn(char *program, char *argv[], int sin, int sout, int serr, - int search, char *envp[], char *pty_name, int wait) + int search, char *envp[], char *pty_name, int wait, char *pwd) { pid_t pid; int fd; int channel[2]; sigset_t sset; + int failure_code = 2; channel[0] = -1; channel[1] = -1; @@ -140,10 +141,14 @@ int spawn(char *program, char *argv[], int sin, int sout, int serr, } close(channel[0]); if (child_errno) { - waitpid(pid, NULL, 0); - /* Our convention to tell Lisp that it was the exec that - * failed, not the fork. */ - pid = -2; + int status; + waitpid(pid, &status, 0); + /* Our convention to tell Lisp that it was the exec or + chdir that failed, not the fork. */ + /* FIXME: there are other values waitpid(2) can return. */ + if (WIFEXITED(status)) { + pid = -WEXITSTATUS(status); + } errno = child_errno; } } @@ -193,16 +198,20 @@ int spawn(char *program, char *argv[], int sin, int sout, int serr, if (fd != channel[1]) close(fd); #endif - if (envp) { - environ = envp; + if (pwd && chdir(pwd) < 0) { + failure_code = 3; + } else { + if (envp) { + environ = envp; + } + /* Exec the program. */ + if (search) + execvp(program, argv); + else + execv(program, argv); } - /* Exec the program. */ - if (search) - execvp(program, argv); - else - execv(program, argv); - /* When exec fails and channel is available, send the errno value. */ + /* When exec or chdir fails and channel is available, send the errno value. */ if (-1 != channel[1]) { int our_errno = errno; int bytes = sizeof(int); @@ -223,7 +232,7 @@ int spawn(char *program, char *argv[], int sin, int sout, int serr, } close(channel[1]); } - _exit(1); + _exit(failure_code); } #else /* !LISP_FEATURE_WIN32 */ @@ -254,7 +263,8 @@ HANDLE spawn ( int search, char *envp, char *ptyname, - int wait + int wait, + char *pwd ) { int stdout_backup, stdin_backup, stderr_backup, wait_mode; @@ -291,6 +301,13 @@ HANDLE spawn ( wait_mode = P_WAIT; } + /* Change working directory if supplied. */ + if (pwd) { + if (chdir(pwd) < 0) { + goto error_exit; + } + } + /* Spawn process given on the command line*/ if (search) hProcess = (HANDLE) spawnvp ( wait_mode, program, (char* const* )argv );