X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Frun-program.c;h=6b7575c6c7536af7959d3ffbf34441e0e1c6d503;hb=53f576d7d796e37a9c51c3c3296341458f046c44;hp=feb8d8d0d4cac74423d106887b06c141f584f57a;hpb=c03ebb54770cfa613d4b706a80e5be231786a5d0;p=sbcl.git diff --git a/src/runtime/run-program.c b/src/runtime/run-program.c index feb8d8d..6b7575c 100644 --- a/src/runtime/run-program.c +++ b/src/runtime/run-program.c @@ -54,8 +54,9 @@ int set_noecho(int fd) return 1; } -int spawn(char *program, char *argv[], char *envp[], char *pty_name, - int stdin, int stdout, int stderr) +extern char **environ; +int spawn(char *program, char *argv[], int stdin, int stdout, int stderr, + int search, char *envp[], char *pty_name, int wait) { int pid = fork(); int fd; @@ -67,6 +68,8 @@ int spawn(char *program, char *argv[], char *envp[], char *pty_name, /* Put us in our own process group. */ #if defined(hpux) setsid(); +#elif defined(LISP_FEATURE_DARWIN) + setpgid(0, getpid()); #elif defined(SVR4) || defined(__linux__) || defined(__osf__) setpgrp(); #else @@ -110,16 +113,14 @@ int spawn(char *program, char *argv[], char *envp[], char *pty_name, close(fd); #endif + environ = envp; /* Exec the program. */ - execve(program, argv, envp); + if (search) + execvp(program, argv); + else + execv(program, argv); - /* It didn't work, so try /bin/sh. */ - argv[0] = program; - argv[-1] = "sh"; - execve("/bin/sh", argv-1, envp); - - /* The exec didn't work, flame out. */ - exit(1); + exit (1); } #else /* !LISP_FEATURE_WIN32 */ @@ -147,33 +148,38 @@ HANDLE spawn ( int in, int out, int err, + int search, + char *envp, + char *ptyname, int wait ) { - int fdOut, fdIn, fdErr, fdInPipe[2], fdOutPipe[2], fdErrPipe[2], wait_mode; + int stdout_backup, stdin_backup, stderr_backup, wait_mode; HANDLE hProcess; - - /* Make pipes to be passed to the spawned process as in/out/err */ - if ( _pipe ( fdOutPipe, 512, O_TEXT | O_NOINHERIT ) == -1 ) return (HANDLE)-1; - if ( _pipe ( fdInPipe, 512, O_TEXT | O_NOINHERIT ) == -1 ) return (HANDLE)-1; - if ( _pipe ( fdErrPipe, 512, O_TEXT | O_NOINHERIT ) == -1 ) return (HANDLE)-1; - - /* Duplicate and save original in/out/err handles */ - fdOut = _dup ( out ); - fdIn = _dup ( in ); - fdErr = _dup ( err ); - - /* Duplicate write end of new pipes to current out/err handles, - * read to in */ - if ( _dup2 ( fdOutPipe[WRITE_HANDLE], out ) != 0 ) return (HANDLE)-1; - if ( _dup2 ( fdInPipe[READ_HANDLE], in ) != 0 ) return (HANDLE)-1; - if ( _dup2 ( fdErrPipe[WRITE_HANDLE], err ) != 0 ) return (HANDLE)-1; - - - /* Close the duplicated handles to the new pipes */ - close ( fdOutPipe[WRITE_HANDLE] ); - close ( fdInPipe[READ_HANDLE] ); - close ( fdErrPipe[WRITE_HANDLE] ); + HANDLE hReturn; + + /* Duplicate and save the original stdin/out/err handles. */ + stdout_backup = _dup ( _fileno ( stdout ) ); + stdin_backup = _dup ( _fileno ( stdin ) ); + stderr_backup = _dup ( _fileno ( stderr ) ); + + /* If we are not using stdin/out/err + * then duplicate the new pipes to current stdin/out/err handles. + * + * Default std fds are used if in, out or err parameters + * are -1. */ + + hReturn = (HANDLE)-1; + hProcess = (HANDLE)-1; + if ( ( out >= 0 ) && ( out != _fileno ( stdout ) ) ) { + if ( _dup2 ( out, _fileno ( stdout ) ) != 0 ) goto error_exit; + } + if ( ( in >= 0 ) && ( in != _fileno ( stdin ) ) ) { + if ( _dup2 ( in, _fileno ( stdin ) ) != 0 ) goto error_exit_out; + } + if ( ( err >= 0 ) && ( err != _fileno ( stderr ) ) ) { + if ( _dup2 ( err, _fileno ( stderr ) ) != 0 ) goto error_exit_in; + } /* Set the wait mode. */ if ( 0 == wait ) { @@ -181,22 +187,31 @@ HANDLE spawn ( } else { wait_mode = P_WAIT; } - + /* Spawn process given on the command line*/ - hProcess = (HANDLE) spawnvp ( wait_mode, program, argv ); - + if (search) + hProcess = (HANDLE) spawnvp ( wait_mode, program, argv ); + else + hProcess = (HANDLE) spawnv ( wait_mode, program, argv ); + /* Now that the process is launched, replace the original - * in/out/err handles */ - if ( _dup2 ( fdOut, out ) != 0 ) return (HANDLE)-1; - if ( _dup2 ( fdIn, in ) != 0 ) return (HANDLE)-1; - if ( _dup2 ( fdErr, err ) != 0 ) return (HANDLE)-1; + * in/out/err handles and close the backups. */ + + if ( _dup2 ( stderr_backup, _fileno ( stderr ) ) != 0 ) goto error_exit; + error_exit_in: + if ( _dup2 ( stdin_backup, _fileno ( stdin ) ) != 0 ) goto error_exit; + error_exit_out: + if ( _dup2 ( stdout_backup, _fileno ( stdout ) ) != 0 ) goto error_exit; + + hReturn = hProcess; + + error_exit: + close ( stdout_backup ); + close ( stdin_backup ); + close ( stderr_backup ); - /* Close duplicates */ - close(fdOut); - close(fdIn); - close(fdErr); + return hReturn; - return ( hProcess ); }