From wscott@ichips.intel.com  Wed Sep  2 09:06:33 1998
Received: from ganymede.or.intel.com (ganymede.or.intel.com [134.134.248.3])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id JAA13748
          for <FreeBSD-gnats-submit@freebsd.org>; Wed, 2 Sep 1998 09:06:32 -0700 (PDT)
          (envelope-from wscott@ichips.intel.com)
Received: from ichips-jf.jf.intel.com (ichips-jf.jf.intel.com [134.134.50.200])
	by ganymede.or.intel.com (8.8.6/8.8.5) with ESMTP id QAA11969
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 2 Sep 1998 16:05:21 GMT
Received: from pdxlx008.pdx.intel.com (pdxlx008.pdx.intel.com [137.102.206.194])
	by ichips-jf.jf.intel.com (8.8.8/8.8.7) with ESMTP id JAA27047
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 2 Sep 1998 09:05:20 -0700 (PDT)
Received: (from wscott@localhost)
	by pdxlx008.pdx.intel.com (8.8.7/8.8.7) id JAA07873;
	Wed, 2 Sep 1998 09:05:18 -0700 (PDT)
	(envelope-from wscott)
Message-Id: <199809021605.JAA07873@pdxlx008.pdx.intel.com>
Date: Wed, 2 Sep 1998 09:05:18 -0700 (PDT)
From: Wayne Scott <wscott@ichips.intel.com>
Reply-To: wscott@ichips.intel.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: popen fails to set close-on-exec flag and hangs on pclose
X-Send-Pr-Version: 3.2

>Number:         7810
>Category:       misc
>Synopsis:       popen fails to set close on exec flag
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep  2 09:10:00 PDT 1998
>Closed-Date:    Wed Oct 14 18:47:48 PDT 1998
>Last-Modified:  Wed Oct 14 18:49:14 PDT 1998
>Originator:     Wayne Scott
>Release:        FreeBSD 3.0-CURRENT i386
>Organization:
Intel Corp., Hillsboro, Oregon
>Environment:

3.0-current

	

>Description:

When popen() returns a file handle it does not have the close-on-exec
flag set.  In the example below, I open two output files writing
to gzip processes to compress the output.

The program will hang on the first call to pclose() because the
second gzip process inherited the open file handle for the first
gzip.  When the program closes the filehandle the first gzip process
does not exit because the second gzip process is still holding the
file open. Since gzip does not exit we wait() forever.

If BUGFIX is defined when the example program is compiled then the
close-on-exec flag is set and the second gzip does not inherit the
open filehandle for the first gzip.

Other implimentations of popen() seem to always to this by default.

	

>How-To-Repeat:

#include <stdio.h>
#include <fcntl.h>

main()
{
	FILE *file1;
	FILE *file2;

	file1 = popen("gzip > file1.gz", "w");
#ifdef BUGFIX
	fcntl(fileno(file1), F_SETFD, 1);
#endif
	file2 = popen("gzip > file2.gz", "w");
#ifdef BUGFIX
	fcntl(fileno(file2), F_SETFD, 1);
#endif

	fprintf(file1, "This is a test\n");
	fprintf(file2, "This is also a test\n");

	pclose(file1);
	pclose(file2);
}


	

>Fix:
	
	Fix this problem by adding the fcntl call to the popen() library function.
>Release-Note:
>Audit-Trail:

From: Wayne Scott <wscott@ichips.intel.com>
To: freebsd-gnats-submit@freebsd.org, wscott@ichips.intel.com
Cc:  Subject: Re: pending/7810: popen fails to set close on exec flag
Date: Wed, 02 Sep 1998 11:26:19 -0700

 I have been looking at this problem futher.
 Setting the close-on-exec flag is NOT the correct fix to this problem.
 
 POSIX states:
 /* Posix.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." */
 
 If you look at popen() in glibc you will see that they keep a linked
 list of
 file handles returned by popen() with the current pid, and then close
 ones on popen() that need to be closed.
 
 --
 Wayne Scott                     MD6 Architecture - Intel Corp.
 wscott@ichips.intel.com         Work #: (503) 613-5063
 Disclaimer:  All views expressed are my own opinions, and not
 necessarily
              those of Intel Corporation.
 
 

From: Wayne Scott <wscott@ichips.intel.com>
To: freebsd-gnats-submit@freebsd.org, wscott@ichips.intel.com
Cc:  Subject: Re: pending/7810: popen fails to set close on exec flag
Date: Wed, 02 Sep 1998 12:08:20 -0700

 Here is a patch that appears to fix the problem.
 
 -Wayne
 
 Index: popen.c
 ===================================================================
 RCS file: /home/ncvs/src/lib/libc/gen/popen.c,v
 retrieving revision 1.9
 diff -u -r1.9 popen.c
 --- popen.c 1997/04/22 09:44:06 1.9
 +++ popen.c 1998/09/02 18:47:49
 @@ -62,6 +62,7 @@
   struct pid *cur;
   FILE *iop;
   int pdes[2], pid, twoway;
 + struct pid *p;
 
   /*
    * Lite2 introduced two-way popen() pipes using socketpair().
 @@ -115,6 +116,9 @@
      (void)close(pdes[0]);
     }
     (void)close(pdes[1]);
 +  }
 +  for (p = pidlist; p; p = p->next) {
 +   close(fileno(p->fp));
    }
    execl(_PATH_BSHELL, "sh", "-c", command, NULL);
 
 --
 Wayne Scott                     MD6 Architecture - Intel Corp.
 wscott@ichips.intel.com         Work #: (503) 613-5063
 Disclaimer:  All views expressed are my own opinions, and not
 necessarily
              those of Intel Corporation.
 
 
Responsible-Changed-From-To: gnats-admin->freebsd-bugs 
Responsible-Changed-By: steve 
Responsible-Changed-When: Mon Sep 7 14:56:19 PDT 1998 
Responsible-Changed-Why:  
Misfiled PR. 
State-Changed-From-To: open->closed 
State-Changed-By: msmith 
State-Changed-When: Wed Oct 14 18:47:48 PDT 1998 
State-Changed-Why:  
The implementation fix for popen() was incorporated (with style changes). 
>Unformatted:
