mod_perl 2 and IPC::Open3

mod_perl 2 and IPC::Open3

am 04.09.2008 19:45:08 von apache

Hi,

I'm using source-highlight in a mod_perl application. This program takes
code in STDIN and prints the html-highlighted code to STDOUT.
My code works fine from the commandline and in
Apache/1.3.37 (Unix) mod_perl/1.30
(perl 5.8.8)

On another machine it also works from the commandline, but not in
Apache/2.2.3 (Debian) mod_perl/2.0.2 Perl/v5.8.8

There is no error, I just cannot get anything from the read handle, it
seems to be empty.
Also an "or die $!" after the open3 is not executed.

I searched for similar problems, I found a posting where they said it would
help to untie STDIN before the open3, but this didn't help.

I also don't get any lines back from the error handle.

Does anybody have an idea what it could be? Maybe I should update to a
more recent mod_perl?

The version of IPC::Open3 is 1.02

Thanks,
tina

Here's the code:
# --------------------------
use strict;
use warnings;
use IPC::Open3;
use Data::Dumper;
use POSIX;

my $content = <<'EOM';
if ($foo) {
bar() # bar
}
EOM
my $highlighted = '';
my $success = 0;
my $pid;
eval {
my($wtr, $rdr, $err);
$pid = open3($wtr, $rdr, $err,
'/usr/bin/source-highlight', '-s', 'perl', '-css', '--no-doc');
print $wtr $content;
close $wtr;
warn __PACKAGE__.':'.__LINE__.": before read loop\n";
while (<$rdr>) {
# this is not executed
warn __PACKAGE__.':'.__LINE__.": line $_\n";
$highlighted .= $_;
}
# code after the loop is executed
};
if ($@) {
warn __PACKAGE__.':'.__LINE__.": ERROR happened: $@ ($$)\n";
$highlighted = "error";
POSIX::_exit(1);
die "oops ($$)";
}
else {
my $exit = waitpid $pid, 0;
$success = 1 if $exit;
}
# --------------------------


--
http://darkdance.net/
http://perlpunks.de/
http://www.trashcave.de/

Re: mod_perl 2 and IPC::Open3

am 05.09.2008 09:23:57 von torsten.foertsch

On Thu 04 Sep 2008, Tina Müller wrote:
> =A0 =A0 =A0$pid =3D open3($wtr, $rdr, $err,
> =A0 =A0 =A0 =A0 =A0'/usr/bin/source-highlight', '-s', 'perl', '-css',
> '--no-doc');
> print $wtr $content;=20
> =A0 =A0 =A0close $wtr;
> =A0 =A0 =A0warn __PACKAGE__.':'.__LINE__.": before read loop\n";
> =A0 =A0 =A0while (<$rdr>) {
> =A0 =A0 =A0 =A0 =A0# this is not executed
> =A0 =A0 =A0 =A0 =A0warn __PACKAGE__.':'.__LINE__.": line $_\n";
> =A0 =A0 =A0 =A0 =A0$highlighted .=3D $_;
> =A0 =A0 =A0}

Don't know if it relates to the problem but this code is quite fragile.=20
It depends upon whether $content completely fits into the operating=20
systems pipe buffer. In your program the print $wtr or the close $wtr=20
statements may infinitely block if $content is too large.

To illustrate that try this:

perl -e 'pipe my ($r, $w) or die "pipe: $!\n"; print $w "x"x64000;=20
warn "printed\n"; close $w;'

Here a pipe is created and written to but never read from. This example=20
succeeds on my linux box. If 64000 is raised to 69000 the "print $w"=20
succeeds and I see the output of warn(). But the process never ends. It=20
is blocked in the close() operation. If the buffer length is raised a=20
bit further to 70000 I don't even see the warning. The process is=20
blocked in the print() operation. The pipe buffer size depends upon the=20
operating system. So your numbers may vary.

I'd recommend to rewrite that piece based on either perl's select(),=20
IO::Select or some kind of event library like Lib::Event, EV, Event or=20
even POE. In all cases you have to use non-blocking IO for reading and=20
writing combined with sysread/syswrite.

=46urther, I'd suggest a bit of error handling. All those operations=20
open3, print, close may fail. Only open3 reports the failure via an=20
exception.

Also, you may want to watch out for SIGPIPE.

Torsten

=2D-
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net

Re: mod_perl 2 and IPC::Open3

am 06.09.2008 20:17:39 von apache

On Fri, 5 Sep 2008, Torsten Foertsch wrote:

> Don't know if it relates to the problem but this code is quite fragile.
> It depends upon whether $content completely fits into the operating
> systems pipe buffer. In your program the print $wtr or the close $wtr
> statements may infinitely block if $content is too large.

thanks for pointing that out, I didn't know that.
To keep it simple, I decided to write the code into a temporary file
and give it as an argument to source-highlight, so that I can call it
with a simple one-directional pipe-open.

Still, it would be interesting to know why the code did not work in MP
2.02.

regards,
tina

--
http://darkdance.net/
http://perlpunks.de/
http://www.trashcave.de/