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

We have been struggling for a week on an issue involving open3 in several modules that are run out of mod_perl. A rough version of the code is shown below, but it is important to note that it WORKS, at least for some people.

Each developer runs their own sandbox under RedHat Linux, comprising the code and apache. For some folks, these modules work fine. For others, the sysread always returns 0 bytes, with no warnings or errors. The difference is in who starts apache/mod_perl.

We became desperate enough wrap the called utility in strace, and the one clue we've found is a difference in fstat64 calls. The users whose modules work see:

fstat64(1, . . . st_mode=S_IFIFO . . .) = 0;
For users whose calls fail:
fstat64(1, . . . st_mode=S_IFSOCK . . .) = 0;

We've compared profiles, environment variables, and version numbers and see no differences.

In addition, users whose modules don't work from inside mod_perl can run standalone scripts like this with no problems.

Has anyone encountered anything like this? Thanks in advance.

use IPC::Open3; use Symbol qw /gensym /; use IO::File; use IO::Select; my $pid; my ($in,$out,$err) = map gensym, 1..3; eval { $pid = open3($in,$out,$err,"/usr/bin/<utility>",("/home/me/infile")) +; }; die "Bad error" if ($@); my $sel = IO::Select->new(); $sel->add($out); $sel->add($err); while (my @ready = $sel->can_read(5)) { for my $handle (@ready) { my $buf; if ($handle == $out) { my $bytes = sysread($handle,$buf,1024); if ($bytes == 0) { $sel->remove($handle); next; } $results .= $buf; } } } if (length($results) > 0) { waitpid($pid); } else { kill(9,$pid); }

Replies are listed 'Best First'.
Re: Yet another Open3 issue . . . or is it?
by ikegami (Patriarch) on Jul 15, 2010 at 18:17 UTC

    the sysread always returns 0 bytes, with no warnings or errors.

    But you're not checking for errors.

    my $bytes = sysread($handle,$buf,1024); if ($bytes == 0) {
    should be
    my $bytes = sysread($handle,$buf,1024); die "sysread: $!" if !defined($bytes); if ($bytes == 0) {

    You imply you have warnings turned on, in which case this won't help since you'd get "Use of uninitialized value in numeric eq (==)" on error.

      Thanks for your reply, ikegami.

      The code I posted is really an "overview" of what appears in several modules, and in fact we are checking for errors as you described:

      if (not defined $bytes) { warn . . . $sel->remove($handle); next; }
      At this point I'd love to get an error or warning, but unfortunately it simply returns 0 bytes as if the handle were empty.
Re: Yet another Open3 issue . . . or is it?
by rowdog (Curate) on Jul 15, 2010 at 23:21 UTC
    "/home/me/infile"

    My guess is that you have permissions issues and mod_perl can't read some of the users' home directories.