Subject: | Spawn::Safe breaks under FCGI, patch applied |
Hi John,
first of all, thanks for Spawn::Safe. I'll use it under FCGI in a
webapp. FCGI is buggy, we know, and Spawn::Safe croaks with the ever
annoying message from FCGI:
Not a GLOB reference at .../FCGI.pm line 125
It's an old problem as you can see if you google for that. It is
triggered by Spawn::Safe reopening STDIN at Spawn/Safe.pm line 199:
198 # Be 5.6 compatible and do it the old way.
199 open( STDIN, '<&' . fileno( $dummy_stdin_read ) ) || goto
CHILD_ERR;
200 open( STDOUT, '>&' . fileno( $child_write_stdout ) ) || goto
CHILD_ERR;
201 open( STDERR, '>&' . fileno( $child_write_stderr ) ) || goto
CHILD_ERR;
Attached is a small testscript tiedhandle.pl and a patch to solve this
general problem. Maybe it will be helpful.
Best Regards
Charly
Subject: | runs-with-buggy-tied-fhs.diff |
diff --git a/lib/Spawn/Safe.pm b/lib/Spawn/Safe.pm
index db47e3a..0b46f87 100644
--- a/lib/Spawn/Safe.pm
+++ b/lib/Spawn/Safe.pm
@@ -195,6 +195,17 @@ sub spawn_safe {
my ( $dummy_stdin_read, $dummy_stdin_write );
pipe( $dummy_stdin_read, $dummy_stdin_write ) || goto CHILD_ERR;
+ # be defensive, filehandles maybe tied() and (re)opening
+ # fails as seen under FCGI, sigh
+
+ local *STDIN;
+ local *STDOUT;
+ local *STDERR;
+
+ open( STDIN, '<&=0' );
+ open( STDOUT, '>>&=1' );
+ open( STDERR, '>>&=2' );
+
# Be 5.6 compatible and do it the old way.
open( STDIN, '<&' . fileno( $dummy_stdin_read ) ) || goto CHILD_ERR;
open( STDOUT, '>&' . fileno( $child_write_stdout ) ) || goto CHILD_ERR;
Subject: | tiedhandle.pl |
use strict;
use warnings;
use Data::Dumper qw(Dumper);
use Spawn::Safe;
# tie STDIN to a buggy Tie::Handle implementation like FCGI does
tie *STDIN, 'My::Handle';
my $result = spawn_safe('date');
warn Dumper($result);
exit;
# buggy Tie::Handle implementation, play wrong as FCGI does
{
package My::Handle;
use Carp qw(croak);
require Tie::Handle;
@My::Handle::ISA = qw(Tie::Handle);
sub TIEHANDLE { bless {}, shift }
sub OPEN { croak "Buggy OPEN in package 'My::Handle', died"; }
sub PRINT { croak "Buggy PRINT in package 'My::Handle', died"; }
}