Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libc/gen/popen.c,v rcsdiff: /ftp/cvs/cvsroot/src/lib/libc/gen/popen.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.8 retrieving revision 1.15 diff -u -p -r1.8 -r1.15 --- src/lib/libc/gen/popen.c 1994/05/07 03:03:13 1.8 +++ src/lib/libc/gen/popen.c 1997/09/16 00:35:47 1.15 @@ -1,3 +1,5 @@ +/* $NetBSD: popen.c,v 1.15 1997/09/16 00:35:47 thorpej Exp $ */ + /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. @@ -34,10 +36,16 @@ * SUCH DAMAGE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) +#if 0 static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: popen.c,v 1.15 1997/09/16 00:35:47 thorpej Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ +#include "namespace.h" #include #include @@ -49,6 +57,11 @@ static char sccsid[] = "@(#)popen.c 8.1 #include #include +#ifdef __weak_alias +__weak_alias(popen,_popen); +__weak_alias(pclose,_pclose); +#endif + static struct pid { struct pid *next; FILE *fp; @@ -60,18 +73,23 @@ popen(program, type) const char *program; const char *type; { - struct pid *cur; + struct pid *cur, *old; FILE *iop; int pdes[2], pid; +#ifdef __GNUC__ + (void) &cur; +#endif - if (*type != 'r' && *type != 'w' || type[1]) + if ((*type != 'r' && *type != 'w') || type[1]) { + errno = EINVAL; return (NULL); + } if ((cur = malloc(sizeof(struct pid))) == NULL) return (NULL); if (pipe(pdes) < 0) { - (void)free(cur); + free(cur); return (NULL); } @@ -79,7 +97,7 @@ popen(program, type) case -1: /* Error. */ (void)close(pdes[0]); (void)close(pdes[1]); - (void)free(cur); + free(cur); return (NULL); /* NOTREACHED */ case 0: /* Child. */ @@ -96,6 +114,13 @@ popen(program, type) } (void)close(pdes[1]); } + + /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams + from previous popen() calls that remain open in the + parent process are closed in the new child process. */ + for (old = pidlist; old; old = old->next) + close(fileno(old->fp)); + execl(_PATH_BSHELL, "sh", "-c", program, NULL); _exit(127); /* NOTREACHED */ @@ -129,8 +154,7 @@ pclose(iop) FILE *iop; { register struct pid *cur, *last; - int omask; - union wait pstat; + int pstat; pid_t pid; (void)fclose(iop); @@ -142,12 +166,9 @@ pclose(iop) if (cur == NULL) return (-1); - /* Get the status of the process. */ - omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); do { - pid = waitpid(cur->pid, (int *) &pstat, 0); + pid = waitpid(cur->pid, &pstat, 0); } while (pid == -1 && errno == EINTR); - (void)sigsetmask(omask); /* Remove the entry from the linked list. */ if (last == NULL) @@ -156,5 +177,5 @@ pclose(iop) last->next = cur->next; free(cur); - return (pid == -1 ? -1 : pstat.w_status); + return (pid == -1 ? -1 : pstat); }