Close function blocks forever when reading from piped output

Close function blocks forever when reading from piped output

am 27.11.2007 22:16:11 von 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" ;

--------
I get the following output:
got one
got end
performing close()

Re: Close function blocks forever when reading from piped output

am 27.11.2007 23:19:06 von Ben Morrow

Quoth 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.

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

Re: Close function blocks forever when reading from piped output

am 28.11.2007 02:10:38 von mark

On Nov 27, 2:19 pm, Ben Morrow wrote:
> 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.

Re: Close function blocks forever when reading from piped output

am 28.11.2007 02:58:58 von Ben Morrow

Quoth Mark :
> On Nov 27, 2:19 pm, Ben Morrow wrote:
> > 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.

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

Re: Close function blocks forever when reading from piped output

am 28.11.2007 07:50:21 von mark

On Nov 27, 5:58 pm, Ben Morrow wrote:
> Quoth Mark :
>
> > On Nov 27, 2:19 pm, Ben Morrow wrote:
> > > 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.
>
> 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

Thanks Ben. I will check it out.

Re: Close function blocks forever when reading from piped output

am 28.11.2007 19:18:15 von xhoster

Mark wrote:
> 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.

Re: Close function blocks forever when reading from piped output

am 28.11.2007 22:09:39 von mark

On Nov 28, 10:18 am, xhos...@gmail.com wrote:

> 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.

Re: Close function blocks forever when reading from piped output

am 28.11.2007 23:12:45 von xhoster

Mark wrote:
> On Nov 28, 10:18 am, xhos...@gmail.com wrote:
>
> > 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.

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.