[comp.lang.perl] Wait for an output pipe?

sps@mcnc.org (Stephen Schaefer) (09/27/90)

My perl program is writing on a pipe that I opened:

open(RMAINTNEED,"rmaintneed @ARGV|";
open(RDIST,"|rdist -f -");
while(<RMAINTNEED>) {
	...process...;
	print RDIST "rdist commands";
}

However, when it is finished writing, it does not wait for the rdist
to finish, but exits immediately, giving me my shell prompt, after
which I start seeing progress reports from rdist.  Before reading a
lot of perl source code and seemingly irrelevant pieces of the manual,
(if a simple answer is in the man page, it ought to be mentioned under
open or wait, and it's not), I'd like someone to tell me: how do I
wait for the output pipe to finish?

Let me speculate: I shouldn't have to explicitly wait, but the
``wait'' that perl does on the output process was confused by the
termination of the process from which I'm reading my input:

open(RMAINTNEED,"rmaintneed @ARGV|";
open(RDIST,"|rdist -f -");
while(<RMAINTNEED>) {
	...process...;
	print RDIST "(rdist commands)";
}

OK, I could collect the process ID from pipe open, but then how do I
wait for that process?  Wait is not documented as taking an optional
argument.  A wait without arguments at the end of the program has
behaved as a no-op.  I'm running on VAX 4.3BSD, and we do have wait3,
although the installation script mutters at our lack of wait4 (wait4
what? :-).

Thanks,
--
	Stephen P. Schaefer, Postmaster	MCNC
	sps@mcnc.org			P.O. Box 12889
	...!mcnc!sps			RTP, NC 27709

merlyn@iwarp.intel.com (Randal Schwartz) (09/28/90)

In article <SPS.90Sep27114644@pepe.mcnc.org>, sps@mcnc (Stephen Schaefer) writes:
| However, when it is finished writing, it does not wait for the rdist
| to finish, but exits immediately, giving me my shell prompt, after
| which I start seeing progress reports from rdist.  Before reading a
| lot of perl source code and seemingly irrelevant pieces of the manual,
| (if a simple answer is in the man page, it ought to be mentioned under
| open or wait, and it's not), I'd like someone to tell me: how do I
| wait for the output pipe to finish?

Just close it.

Yeah, it's not under open() or write(), but close().

print +('a'..'z','J','P',',',' ')[26,20,18,19,29,0,13,14,19,7,4,17,29,27,4,17,11,29,7,0,2,10,4,17,28]
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (09/28/90)

In article <SPS.90Sep27114644@pepe.mcnc.org> sps@mcnc.org (Stephen Schaefer) writes:
: Before reading a
: lot of perl source code and seemingly irrelevant pieces of the manual,
: (if a simple answer is in the man page, it ought to be mentioned under
: open or wait, and it's not), I'd like someone to tell me: how do I
: wait for the output pipe to finish?

Welllllll...

In the man page, under open, it says

             Explicitly closing any piped filehandle  causes  the
             parent  process to wait for the child to finish, and
             returns the status value in $?.

So you simply have to close the RDIST filehandle.

: ...OK, I could collect the process ID from pipe open, but then how do I
: wait for that process?  Wait is not documented as taking an optional
: argument.  A wait without arguments at the end of the program has
: behaved as a no-op.  I'm running on VAX 4.3BSD, and we do have wait3,
: although the installation script mutters at our lack of wait4 (wait4
: what? :-).

Version 4.0 will have waitpid(), with two arguments.  The pid to wait for,
and special flags to do things like non-blocking.  If your machine has
either wait4 or waitpid, you can use the special flags; otherwise, you
can only wait in blocking mode for a specific pid (Perl emulates this by
doing normal waits and remember all the exit statuses for later reference,
until it finds the pid you were waiting for.  If you waitpid on something
that exited earlier, it just uses the status it remembered from before.)

Larry

worley@compass.com (Dale Worley) (09/28/90)

   X-Name: Stephen Schaefer

   OK, I could collect the process ID from pipe open, but then how do I
   wait for that process?

$pid = open(RDIST,"|rdist -f -");
... write stuff to RDIST ...
close RDIST;
# Wait until process $pid is done
until (wait == $pid) {}

Dale Worley		Compass, Inc.			worley@compass.com
--
Men!  Get Deep Pockets aftershave -- rendolent of a fine, hand-tooled
Italian leather wallet filled with crisp, new $100 bills!

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (09/28/90)

In article <1990Sep27.195032.25135@uvaarpa.Virginia.EDU> worley@compass.com writes:
: 
:    X-Name: Stephen Schaefer
: 
:    OK, I could collect the process ID from pipe open, but then how do I
:    wait for that process?
: 
: $pid = open(RDIST,"|rdist -f -");
: ... write stuff to RDIST ...
: close RDIST;
: # Wait until process $pid is done
: until (wait == $pid) {}

Er, you've just written an infinite loop, since close will harvest the
pid in question, and wait will return -1 eternally.

Larry

sps@mcnc.org (Stephen Schaefer) (09/28/90)

In article <9708@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
: In the man page, under open, it says
: 
:              Explicitly closing any piped filehandle  causes  the
:              parent  process to wait for the child to finish, and
:              returns the status value in $?.
: 
: So you simply have to close the RDIST filehandle.

Thank you, and all others, for the answer.  I confused myself by
assuming that the implicit file closes on exit would behave the same
as an explicit close.  Mea culpa.  That is NOT in any way to suggest
that perl *should* behave that way: one should be able to exit
*without* waiting for the pipe's process to finish, and the current
arrangement seems to me the most elegant way to achieve that.

--
	Stephen P. Schaefer, Postmaster	MCNC
	sps@mcnc.org			P.O. Box 12889
	...!mcnc!sps			RTP, NC 27709

worley@compass.com (Dale Worley) (09/29/90)

   X-Name: Larry Wall

   In article <1990Sep27.195032.25135@uvaarpa.Virginia.EDU> worley@compass.com writes:
   : $pid = open(RDIST,"|rdist -f -");
   : ... write stuff to RDIST ...
   : close RDIST;
   : # Wait until process $pid is done
   : until (wait == $pid) {}

   Er, you've just written an infinite loop, since close will harvest the
   pid in question, and wait will return -1 eternally.

Yeah, I forgot that close waits for the process to finish.

Dale Worley		Compass, Inc.			worley@compass.com
--
"We'd better wake up and smell the goats or it will be burlap soup for all
of us!"

"Burlap soup?"

"No thanks, I had lunch on the way over."