diff options
Diffstat (limited to 'src/libthread/exec-unix.c')
-rw-r--r-- | src/libthread/exec-unix.c | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c deleted file mode 100644 index e5848eaa..00000000 --- a/src/libthread/exec-unix.c +++ /dev/null @@ -1,147 +0,0 @@ -#include <u.h> -#include <fcntl.h> -#include <unistd.h> -#include "threadimpl.h" - -static void efork(int[3], int[2], char*, char**); -int -_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs) -{ - int pfd[2]; - int n, pid; - char exitstr[ERRMAX]; - - _threaddebug(DBGEXEC, "threadexec %s", prog); - - /* - * We want threadexec to behave like exec; if exec succeeds, - * never return, and if it fails, return with errstr set. - * Unfortunately, the exec happens in another proc since - * we have to wait for the exec'ed process to finish. - * To provide the semantics, we open a pipe with the - * write end close-on-exec and hand it to the proc that - * is doing the exec. If the exec succeeds, the pipe will - * close so that our read below fails. If the exec fails, - * then the proc doing the exec sends the errstr down the - * pipe to us. - */ - if(pipe(pfd) < 0) - goto Bad; - if(fcntl(pfd[0], F_SETFD, 1) < 0) - goto Bad; - if(fcntl(pfd[1], F_SETFD, 1) < 0) - goto Bad; - - switch(pid = fork()){ - case -1: - close(pfd[0]); - close(pfd[1]); - goto Bad; - case 0: - efork(fd, pfd, prog, args); - _threaddebug(DBGSCHED, "exit after efork"); - _exit(0); - default: - if(freeargs) - free(args); - break; - } - - close(pfd[1]); - if((n = read(pfd[0], exitstr, ERRMAX-1)) > 0){ /* exec failed */ - exitstr[n] = '\0'; - errstr(exitstr, ERRMAX); - close(pfd[0]); - goto Bad; - } - close(pfd[0]); - close(fd[0]); - if(fd[1] != fd[0]) - close(fd[1]); - if(fd[2] != fd[1] && fd[2] != fd[0]) - close(fd[2]); - if(pidc) - sendul(pidc, pid); - - _threaddebug(DBGEXEC, "threadexec schedexecwait"); - return pid; - -Bad: - _threaddebug(DBGEXEC, "threadexec bad %r"); - if(pidc) - sendul(pidc, ~0); - return -1; -} - -void -threadexec(Channel *pidc, int fd[3], char *prog, char *args[]) -{ - if(_kthreadexec(pidc, fd, prog, args, 0) >= 0) - threadexits(nil); -} - -int -threadspawn(int fd[3], char *prog, char *args[]) -{ - return _kthreadexec(nil, fd, prog, args, 0); -} - -/* - * The &f+1 trick doesn't work on SunOS, so we might - * as well bite the bullet and do this correctly. - */ -void -threadexecl(Channel *pidc, int fd[3], char *f, ...) -{ - char **args, *s; - int n; - va_list arg; - - va_start(arg, f); - for(n=0; va_arg(arg, char*) != 0; n++) - ; - n++; - va_end(arg); - - args = malloc(n*sizeof(args[0])); - if(args == nil){ - if(pidc) - sendul(pidc, ~0); - return; - } - - va_start(arg, f); - for(n=0; (s=va_arg(arg, char*)) != 0; n++) - args[n] = s; - args[n] = 0; - va_end(arg); - - if(_kthreadexec(pidc, fd, f, args, 1) >= 0) - threadexits(nil); -} - -static void -efork(int stdfd[3], int fd[2], char *prog, char **args) -{ - char buf[ERRMAX]; - int i; - - _threaddebug(DBGEXEC, "_schedexec %s -- calling execv", prog); - dup(stdfd[0], 0); - dup(stdfd[1], 1); - dup(stdfd[2], 2); - for(i=3; i<40; i++) - if(i != fd[1]) - close(i); - rfork(RFNOTEG); - execvp(prog, args); - _threaddebug(DBGEXEC, "_schedexec failed: %r"); - rerrstr(buf, sizeof buf); - if(buf[0]=='\0') - strcpy(buf, "exec failed"); - write(fd[1], buf, strlen(buf)); - close(fd[1]); - _threaddebug(DBGSCHED, "_exits in exec-unix"); - _exits(buf); -} - |