[comp.unix.questions] Reopening stdin

chuck@trantor.harris-atd.com (Chuck Musciano) (01/08/91)

     Environment: Sun-3/60 running SunOS 4.1
     
     I have a program which at one point forks itself.  The child, in turn,
calls system() to run a command.  In the child, I would like to reopen stdin
to point to a particular file.  To do this, I call open() and dup2() before
calling system().

     Here is the strange behavior.  If the parent has at some point closed
its stdin, the command that the child invokes with system() terminates
with "stdin: bad file number".  If the parent does not close its stdin, all
works fine.  The close of stdin occurs before the child is forked.

     My question: what unusual behavior occurs when you close stdin such
that your children cannot successfully dup2() into it and fork again (via
system()).  The trivial solution is to never close stdin in the parent, but
my curiosity has been piqued by this odd behavior.  Any insight on this?

-- 

Chuck Musciano				ARPA  : chuck@trantor.harris-atd.com
Harris Corporation 			Usenet: ...!uunet!x102a!trantor!chuck
PO Box 37, MS 3A/1912			AT&T  : (407) 727-6131
Melbourne, FL 32902			FAX   : (407) 729-2537

A good newspaper is never good enough,
	but a lousy newspaper is a joy forever.		-- Garrison Keillor

maart@cs.vu.nl (Maarten Litmaath) (01/08/91)

In article <5200@trantor.harris-atd.com>,
	chuck@trantor.harris-atd.com (Chuck Musciano) writes:
)
)     Environment: Sun-3/60 running SunOS 4.1
)     
)     I have a program which at one point forks itself.  The child, in turn,
)calls system() to run a command.  In the child, I would like to reopen stdin
)to point to a particular file.  To do this, I call open() and dup2() before
)calling system().
)
)     Here is the strange behavior.  If the parent has at some point closed
)its stdin, the command that the child invokes with system() terminates
)with "stdin: bad file number".  If the parent does not close its stdin, all
)works fine.  The close of stdin occurs before the child is forked.

Does the following program fail too?

	main()
	{
		int	fd, i;

		close(0);
		fd = open("/etc/passwd", 0);
		dup2(fd, 0);
		i = system("cat");
		exit(i & 0377 ? i | 0200 : i >> 8);
	}

If so, it looks like a resurrection of the old dup2() bug: as stdin has
been closed, the open() will return file descriptor 0, so the next line
results in
		dup2(0, 0)

Old implementations of dup2(from, to) did NOT check for the case
from == to, but blindly closed `to' and duplicated `from' to `to',
so in our case stdin would get closed again...  :-(
Have you checked the return value of dup2()?
--
nlp@berlin.mt.cs.cmu.edu: "I heard that an Awk was spotted in Sherwood forest."
rmk@frog.UUCP (Rick Kelly): "It was seen running in the background."

chuck@trantor.harris-atd.com (Chuck Musciano) (01/08/91)

In article <8685@star.cs.vu.nl>, maart@cs.vu.nl (Maarten Litmaath) writes:
> Does the following program fail too?
> 
> 	main()
> 	{
> 		int	fd, i;
> 
> 		close(0);
> 		fd = open("/etc/passwd", 0);
> 		dup2(fd, 0);
> 		i = system("cat");
> 		exit(i & 0377 ? i | 0200 : i >> 8);
> 	}
> 
> If so, it looks like a resurrection of the old dup2() bug: as stdin has
> been closed, the open() will return file descriptor 0, so the next line
> results in
> 		dup2(0, 0)

     I checked dup2(), and it is returning 0, as you would expect.  In the
case of dup2(0, 0), I tried closing stdin, calling open(), and verified
that I got 0 as the descriptor.  I then skipped the dup2 call, called
system(), and it still failed!

-- 

Chuck Musciano				ARPA  : chuck@trantor.harris-atd.com
Harris Corporation 			Usenet: ...!uunet!x102a!trantor!chuck
PO Box 37, MS 3A/1912			AT&T  : (407) 727-6131
Melbourne, FL 32902			FAX   : (407) 729-2537

A good newspaper is never good enough,
	but a lousy newspaper is a joy forever.		-- Garrison Keillor

maart@cs.vu.nl (Maarten Litmaath) (01/09/91)

In article <5208@trantor.harris-atd.com>,
	chuck@trantor.harris-atd.com (Chuck Musciano) writes:
)...
)> 	main()
)> 	{
)> 		int	fd, i;
)> 
)> 		close(0);
)> 		fd = open("/etc/passwd", 0);
)> 		dup2(fd, 0);
)> 		i = system("cat");
)> 		exit(i & 0377 ? i | 0200 : i >> 8);
)> 	}
)...
)     I checked dup2(), and it is returning 0, as you would expect.  In the
)case of dup2(0, 0), I tried closing stdin, calling open(), and verified
)that I got 0 as the descriptor.  I then skipped the dup2 call, called
)system(), and it still failed!

What about this: note that in the example I forgot a close(fd) statement
after the dup2() call; now I expect that you did _not_ forget it in _your_
program, in which case you are closing stdin yourself again!

If this still doesn't explain it, could you post or email a minimal
piece of code that shows the problem?
--
nlp@berlin.mt.cs.cmu.edu: "I heard that an Awk was spotted in Sherwood forest."
rmk@frog.UUCP (Rick Kelly): "It was seen running in the background."