You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Tina Müller <ap...@s05.tinita.de> on 2008/09/04 19:45:08 UTC
mod_perl 2 and IPC::Open3
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
Posted by Tina Müller <ap...@s05.tinita.de>.
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/
Re: mod_perl 2 and IPC::Open3
Posted by Torsten Foertsch <to...@gmx.net>.
On Thu 04 Sep 2008, Tina Müller wrote:
> $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 .= $_;
> }
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.
To illustrate that try this:
perl -e 'pipe my ($r, $w) or die "pipe: $!\n"; print $w "x"x64000;
warn "printed\n"; close $w;'
Here a pipe is created and written to but never read from. This example
succeeds on my linux box. If 64000 is raised to 69000 the "print $w"
succeeds and I see the output of warn(). But the process never ends. It
is blocked in the close() operation. If the buffer length is raised a
bit further to 70000 I don't even see the warning. The process is
blocked in the print() operation. The pipe buffer size depends upon the
operating system. So your numbers may vary.
I'd recommend to rewrite that piece based on either perl's select(),
IO::Select or some kind of event library like Lib::Event, EV, Event or
even POE. In all cases you have to use non-blocking IO for reading and
writing combined with sysread/syswrite.
Further, I'd suggest a bit of error handling. All those operations
open3, print, close may fail. Only open3 reports the failure via an
exception.
Also, you may want to watch out for SIGPIPE.
Torsten
--
Need professional mod_perl support?
Just hire me: torsten.foertsch@gmx.net