For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > November 2007 > Close function blocks forever when reading from piped output









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Close function blocks forever when reading from piped output
Mark

2007-11-27, 7:10 pm

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()

Ben Morrow

2007-11-27, 7:10 pm


Quoth Mark <google@markginsburg.com>:
> 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

Mark

2007-11-27, 10:08 pm

On Nov 27, 2:19 pm, Ben Morrow <b...@morrow.me.uk> 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.

Ben Morrow

2007-11-27, 10:08 pm


Quoth Mark <google@markginsburg.com>:
> On Nov 27, 2:19 pm, Ben Morrow <b...@morrow.me.uk> wrote:
>
> 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

Mark

2007-11-28, 4:16 am

On Nov 27, 5:58 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth Mark <goo...@markginsburg.com>:
>
>
>
>
> 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.
xhoster@gmail.com

2007-11-28, 7:07 pm

Mark <google@markginsburg.com> 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.
Mark

2007-11-28, 7:07 pm

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.
xhoster@gmail.com

2007-11-28, 7:07 pm

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







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com