blueflashlight has asked for the wisdom of the Perl Monks concerning the following question:

hi, monks ... looking for some wisdom here; my little brain can't figure out what I'm doing wrong.

basically, I am trying to use the open2 function from the IPC::Open2 module to: (a) send the contents of an array to the STDIN of "enscript", and (b) read the resulting STDOUT postscript code into an array.

Here is the code I'm using (lots of unrelated stuff snipped) ...

$|++; # put the args to enscript in an array ... my @enscript_args = ( "--no-header ", "--escapes ", "--font=AvantGarde-Book24 ", "--no-job-header ", "--quiet ", "--output=- " ); # here is where gnu enscript is on this system ... my $enscript = "/usr/bin/enscript"; # wrap the opening of enscript in an eval block, # so we can catch problems and die gracefully ... eval { open2 (*FROMENSCRIPT, *TOENSCRIPT, "$enscript @enscript_args"); }; if ( defined ($@) && $@ =~ /^open2/) { warn "$me: open2 failed: $!\n$@\n"; die }; print TOENSCRIPT (@burstpage); my @burstpage_ps = <FROMENSCRIPT>; close(TOENSCRIPT); close(FROMENSCRIPT);


the problem is that when I run this, an enscript process is spawned, but just hangs until I control-c the perl script. The "eval" statement provides me with no errors.

I assume that I'm running into a deadlock (I did rtfm, and my cookbook), and so I've seen the warnings that go with using open2; am I doing something stupid, or is there a better way of doing this? (I *really* don't want to use a temp file.)

Any help/advice would be greatly appreciated (even a "terse" solution from merlyn :-)

thanks!

Replies are listed 'Best First'.
Re: need help with open2, please!
by stephen (Priest) on May 02, 2001 at 08:49 UTC
    You need to close the TOENSCRIPT handle to tell the process that you've finished writing to it. Move close(TOENSCRIPT) above the line where you read the output, like so:
    print TOENSCRIPT (@burstpage); close(TOENSCRIPT); my @burstpage_ps = <FROMENSCRIPT>; close(FROMENSCRIPT);

    stephen


    Update 1: Added code example.
      This sounds like a problem I'm having with both the Lingua::ISpell and Text::ISpell modules. Every script I write with them just hangs when an attempt is made to read from the spawned process's output pipe. Both modules use an open2 call from an _init() function prior to calling spellcheck(). Here's what they look like:
      sub _init { ... $Lingua::Ispell::pid = open2( *Reader, *Writer, $Lingua::Ispell::path, '-a', '-S', @options, ); ... } sub spellcheck { _init() or return(); # caller should really catch the exception fro +m a failed open2. my $line = shift; local $/ = "\n"; local $\ = ''; chomp $line; $line =~ s/\r//g; # kill the hate $line =~ /\n/ and croak "newlines not allowed in arguments to Lingua +::Ispell::spellcheck!"; print Writer "^$line\n"; my @commentary; local $_; while ( <Reader> ) { chomp; last unless $_ gt ''; push @commentary, $_; }
      From a debugger, I see that it hangs at the line:
      while ( <Reader> ) {
      By the by, I'm trying to write a litte script to check fields in a database for spelling errors and write out a log of misspelled words. Any ideas on what I'm doing wrong? ( I can't even run the example code for these modules without hanging. Oh, I'm on a Windows machine and cannot use a real operating system.)
        It sounds like you are Suffering from Buffering. Though not exactly. Anyways you are expecting output while it is expecting input, and nobody is going to be happy.

        What happens if you try to close Writer before reading? Once it finds out that there will be no more input, you should get your output and be happy...

      thank you!!! that solved all my problems; life is good. -s-