Close function blocks forever when reading from piped output

M

Mark

I am reading piped output from a command that produces a lot of
output. I would like to terminate reading the data before the end of
the output is reached.

The following sample program illustrates the issue. The program will
get stuck on the close(). Any help in dealing with this situation
will be appreciated.

I am having this issue on Windows XP.

use strict ;
use warnings ;

$| = 1 ;

# The following one line perl program produces the lines, "one",
"end", "two",
# continuously, forever.
# Note: You may need to change the quote characters for your command
shell.
my $GenTxtCmd = 'perl -le "while () {foreach (qw(one end two))
{print};}" ' ;

open my $FH, '-|', "$GenTxtCmd" or die "open failed: $!" ;

while (<$FH>) {
print "got $_" ;
last if /end/ ;
}

print "performing close()\n" ;
my $result = close($FH) ;
print "completed close(), result=$result\n" ;
 
B

Ben Morrow

Quoth Mark said:
I am reading piped output from a command that produces a lot of
output. I would like to terminate reading the data before the end of
the output is reached.

The following sample program illustrates the issue. The program will
get stuck on the close(). Any help in dealing with this situation
will be appreciated.

I am having this issue on Windows XP.

This is probably your problem :). Try killing the process before closing
the pipe: open '-|' returns a pid, and kill TERM => $pid should do
something reasonable on Win32.

Otherwise try IPC::Run, or do it all by hand with Win32::process.

Ben
 
M

Mark

This is probably your problem :). Try killing the process before closing
the pipe: open '-|' returns a pid, and kill TERM => $pid should do
something reasonable on Win32.

Otherwise try IPC::Run, or do it all by hand with Win32::process.

I tried killing the process from within my while(<$FH>) loop and that
did allowed the program to complete. However, I was looking for a
more elegant solution.
 
B

Ben Morrow

Quoth Mark said:
I tried killing the process from within my while(<$FH>) loop and that
did allowed the program to complete. However, I was looking for a
more elegant solution.

IPC::Run, as I said. It has a lot of options, but it makes the sort of
thing you are trying to do very simple.

Ben
 
X

xhoster

Mark said:
I am reading piped output from a command that produces a lot of
output. I would like to terminate reading the data before the end of
the output is reached.

The following sample program illustrates the issue. The program will
get stuck on the close(). Any help in dealing with this situation
will be appreciated.


If you use a piped open, Perl automagically bundles the wait (or whatever
the Windows equiv is) in with the close, which might be the problem. If you
roll your own using pipe and fork (or Windows equiv), then it should be
possible to unbundle the close and the wait.

But why close, rather than just going about your business with an open but
no longer used file handle? If you want the return value of the close,
then anything you do to force the close to happen means that the return
value you get will now be driven by the forcing method rather than the
natural operation of the child, and so probably isn't worth having.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
M

Mark

But why close, rather than just going about your business with an open but
no longer used file handle? If you want the return value of the close,
then anything you do to force the close to happen means that the return
value you get will now be driven by the forcing method rather than the
natural operation of the child, and so probably isn't worth having.

I tried removing the close() as you suggested but then the perl
program hungs at the end of the program, presumably, while doing an
implicit close.
 
X

xhoster

Mark said:
I tried removing the close() as you suggested but then the perl
program hungs at the end of the program, presumably, while doing an
implicit close.

So I assume you find that undesirable? :)

The same thing happens if a lexically held find handle goes of scope,
so this implicit close could get you in that case to.

And if I capture the pid and then kill it before the close, the close
doesn't hang but doing this seems to leave some kind of CPU-draining
zombies behind.

Ugg. I'm glad I don't need to program in Perl for Windows very much.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top