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/