-
-
Save wesQ3/b1ee0bfe45a6746d7c66 to your computer and use it in GitHub Desktop.
replacement Plack::App::WrapCGI (perl only)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# from Plack 1.0051 2024-01-05 | |
package Plack::App::WrapCGI; | |
use strict; | |
use warnings; | |
use parent qw(Plack::Component); | |
use Plack::Util::Accessor qw(script execute _app); | |
use File::Spec; | |
use CGI::Emulate::PSGI; | |
use CGI::Compile; | |
use Carp; | |
use POSIX ":sys_wait_h"; | |
sub slurp_fh { | |
my $fh = $_[0]; | |
local $/; | |
my $v = <$fh>; | |
defined $v ? $v : ''; | |
} | |
sub prepare_app { | |
my $self = shift; | |
my $script = $self->script | |
or croak "'script' is not set"; | |
$script = File::Spec->rel2abs($script); | |
if ($self->execute) { | |
my $app = sub { | |
my $env = shift; | |
pipe( my $stdoutr, my $stdoutw ); | |
pipe( my $stdinr, my $stdinw ); | |
local $SIG{CHLD} = 'DEFAULT'; | |
my $pid = fork(); | |
Carp::croak("fork failed: $!") unless defined $pid; | |
if ($pid == 0) { # child | |
local $SIG{__DIE__} = sub { | |
print STDERR @_; | |
exit(1); | |
}; | |
close $stdoutr; | |
close $stdinw; | |
local %ENV = (%ENV, CGI::Emulate::PSGI->emulate_environment($env)); | |
open( STDOUT, ">&=" . fileno($stdoutw) ) | |
or Carp::croak "Cannot dup STDOUT: $!"; | |
open( STDIN, "<&=" . fileno($stdinr) ) | |
or Carp::croak "Cannot dup STDIN: $!"; | |
chdir(File::Basename::dirname($script)); | |
# RUN NON-EXECUTABLE SCRIPTS LIKE WINDOWS | |
# exec($script) or Carp::croak("cannot exec: $!"); | |
exec($^X, $script) or Carp::croak("cannot exec: $!"); | |
exit(2); | |
} | |
close $stdoutw; | |
close $stdinr; | |
syswrite($stdinw, slurp_fh($env->{'psgi.input'})); | |
# close STDIN so child will stop waiting | |
close $stdinw; | |
my $res = ''; my $waited_pid; | |
while (($waited_pid = waitpid($pid, WNOHANG)) == 0) { | |
$res .= slurp_fh($stdoutr); | |
} | |
$res .= slurp_fh($stdoutr); | |
# -1 means that the child went away, and something else | |
# (probably some global SIGCHLD handler) took care of it; | |
# yes, we just reset $SIG{CHLD} above, but you can never | |
# be too sure | |
if (POSIX::WIFEXITED($?) || $waited_pid == -1) { | |
return CGI::Parse::PSGI::parse_cgi_output(\$res); | |
} else { | |
Carp::croak("Error at run_on_shell CGI: $!"); | |
} | |
}; | |
$self->_app($app); | |
} else { | |
my $sub = CGI::Compile->compile($script); | |
my $app = CGI::Emulate::PSGI->handler($sub); | |
$self->_app($app); | |
} | |
} | |
sub call { | |
my($self, $env) = @_; | |
$self->_app->($env); | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This change enables running CGI scripts that are not marked as executable, such as scripts developed on windows or usually run with a non-standard Apache cgi exec setup.
You may see this error when calling your scripts:
The change above on line 59 will fix this by using the current perl to execute the script directly.