diff options
Diffstat (limited to 'lib/libc/gen/popen.c')
-rw-r--r-- | lib/libc/gen/popen.c | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/lib/libc/gen/popen.c b/lib/libc/gen/popen.c index 3c3bd6f..0d28046 100644 --- a/lib/libc/gen/popen.c +++ b/lib/libc/gen/popen.c @@ -35,12 +35,11 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; +static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> #include <sys/wait.h> -#include <sys/socket.h> #include <signal.h> #include <errno.h> @@ -54,36 +53,33 @@ static struct pid { struct pid *next; FILE *fp; pid_t pid; -} *pidlist; - +} *pidlist; + FILE * -popen(command, type) - const char *command, *type; +popen(program, type) + const char *program; + const char *type; { struct pid *cur; FILE *iop; - int pdes[2], pid, twoway; - - if (strchr(type, '+')) { - twoway = 1; - type = "r+"; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0) - return (NULL); - } else { - twoway = 0; - if (*type != 'r' && *type != 'w' || type[1] || - (pipe(pdes) < 0)) - return (NULL); - } + int pdes[2], pid; + + if ( (*type != 'r' && *type != 'w') || type[1]) + return (NULL); if ((cur = malloc(sizeof(struct pid))) == NULL) return (NULL); + if (pipe(pdes) < 0) { + free(cur); + return (NULL); + } + switch (pid = vfork()) { case -1: /* Error. */ (void)close(pdes[0]); (void)close(pdes[1]); - (void)free(cur); + free(cur); return (NULL); /* NOTREACHED */ case 0: /* Child. */ @@ -91,11 +87,8 @@ popen(command, type) if (pdes[1] != STDOUT_FILENO) { (void)dup2(pdes[1], STDOUT_FILENO); (void)close(pdes[1]); - pdes[1] = STDOUT_FILENO; } (void) close(pdes[0]); - if (twoway && (pdes[1] != STDIN_FILENO)) - (void)dup2(pdes[1], STDIN_FILENO); } else { if (pdes[0] != STDIN_FILENO) { (void)dup2(pdes[0], STDIN_FILENO); @@ -103,7 +96,7 @@ popen(command, type) } (void)close(pdes[1]); } - execl(_PATH_BSHELL, "sh", "-c", command, NULL); + execl(_PATH_BSHELL, "sh", "-c", program, NULL); _exit(127); /* NOTREACHED */ } @@ -137,9 +130,11 @@ pclose(iop) { register struct pid *cur, *last; int omask; - int pstat; + union wait pstat; pid_t pid; + (void)fclose(iop); + /* Find the appropriate file pointer. */ for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) if (cur->fp == iop) @@ -147,11 +142,12 @@ pclose(iop) if (cur == NULL) return (-1); - (void)fclose(iop); - + /* Get the status of the process. */ + omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); do { - pid = waitpid(cur->pid, &pstat, 0); + pid = waitpid(cur->pid, (int *) &pstat, 0); } while (pid == -1 && errno == EINTR); + (void)sigsetmask(omask); /* Remove the entry from the linked list. */ if (last == NULL) @@ -159,6 +155,6 @@ pclose(iop) else last->next = cur->next; free(cur); - - return (pid == -1 ? -1 : pstat); + + return (pid == -1 ? -1 : pstat.w_status); } |