Subject: lib/2575: task will hang when calling pclose
To: None <gnats-bugs@NetBSD.ORG>
From: Clifford Wright <cliff@wport.com>
List: netbsd-bugs
Date: 06/26/1996 21:24:49
>Number: 2575
>Category: lib
>Synopsis: task will hang when calling pclose
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: lib-bug-people (Library Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jun 27 00:50:02 1996
>Last-Modified:
>Originator: Clifford Wright
>Organization:
>Release: 1.1
>Environment:
All
System: NetBSD vixen 1.1 NetBSD 1.1 (VIXEN) #28: Tue Jun 25 01:40:06 PDT 1996 cliff@vixen:/usr/src/sys/arch/i386/compile/VIXEN i386
>Description:
When running the WWW browser Grail from CNRI and doing multiple jpeg
image loads the browser would hang. Investigation showed this occured
after multiple popen's had been called and a pclose was issued on the
first popen stream.
>How-To-Repeat:
>Fix:
The popen library routine should have closed all file descriptors except
the input or output stream after the fork. Otherwise the reference
count on the stream file descriptor will be incremented when other
popen calls are made, and a complete close can not occur on the first
stream file descriptor when pclose is called until the later streams all
close. Since pclose does a wait forever on a complete close of the
fisrt stream, the close on the later streams never occurs, and thus
the task hangs.
The diff against base NetBSD 1.1 follows.
*** popen.c.orig Fri Oct 13 17:47:41 1995
--- popen.c Wed Jun 26 21:22:16 1996
***************
*** 68,74 ****
{
struct pid *cur;
FILE *iop;
! int pdes[2], pid;
if (*type != 'r' && *type != 'w' || type[1]) {
errno = EINVAL;
--- 68,74 ----
{
struct pid *cur;
FILE *iop;
! int pdes[2], pid, fd;
if (*type != 'r' && *type != 'w' || type[1]) {
errno = EINVAL;
***************
*** 94,108 ****
if (*type == 'r') {
if (pdes[1] != STDOUT_FILENO) {
(void)dup2(pdes[1], STDOUT_FILENO);
- (void)close(pdes[1]);
}
! (void) close(pdes[0]);
} else {
if (pdes[0] != STDIN_FILENO) {
(void)dup2(pdes[0], STDIN_FILENO);
- (void)close(pdes[0]);
}
! (void)close(pdes[1]);
}
execl(_PATH_BSHELL, "sh", "-c", program, NULL);
_exit(127);
--- 94,112 ----
if (*type == 'r') {
if (pdes[1] != STDOUT_FILENO) {
(void)dup2(pdes[1], STDOUT_FILENO);
}
! for(fd = 0; fd < NOFILE; fd++) {
! if(fd != STDOUT_FILENO)
! (void)close(fd);
! }
} else {
if (pdes[0] != STDIN_FILENO) {
(void)dup2(pdes[0], STDIN_FILENO);
}
! for(fd = 0; fd < NOFILE; fd++) {
! if(fd != STDIN_FILENO)
! (void)close(fd);
! }
}
execl(_PATH_BSHELL, "sh", "-c", program, NULL);
_exit(127);
>Audit-Trail:
>Unformatted: