perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stas Bekman <>
Subject Re: Fw: Re: mod_perl closes apache's stdin and/or stdout
Date Tue, 03 Apr 2007 23:20:06 GMT
Stephane Chazelas wrote:
> On Mon, Apr 02, 2007 at 03:52:50PM -0700, Stas Bekman wrote:
>> Stephane, you are correct in your observations that original STDIN and
>> STDOUT filehandles are not preserved when perlio CGI mode is used.
>> This is because how Perl works. Consider the following perl program, run from the
command line (not mod_perl!):
> Hi Stas, that's not what I think happens though.
> I suspected as well that the responsible code was in
> src/modules/perl/modperl_io.c
> And it does IIUC:
> open STDIN_SAVED, "<&STDIN" or die "Can't dup STDIN: $!";
> close STDIN;
> open STDIN, "<:apache"
> and same for STDOUT.
> And it should work, except that the second open, which should
> resolve to a dup2 or dup system call doesn't seem to do anything
> file-descriptor-wise. It rather looks like is assignes the STDIN
> perl handle to the Socket, so that STDIN no longer has the fd 0
> (as demonstrated by my test of executing a lsof command within a
> CGI script), but something more like 16, which was returned by
> the accept() of the incoming HTTP connection.

That's correct, Stephane. The :Apache perlio layer does not use a 
socket. It uses $r instead, which is already interfacing an existing 
non-STD socket. That's why the :Apache perlio layer doesn't take over 
the just released fd.

There is a problem with using a socket with :Apache perlio layer. If we 
do so Perl will attempt to use that socket. I suppose it's still 
possible to work around that, you are more than welcome to change the 
:Apache perlio layer to dup(2). It can be found in 
modperl_io_apache.[ch] files. modperl_io.c invokes it via open 
"<:Apache". You can find the documentation of perlio layers in the 
perliol manpage.

>>          handle_save = gv_fetchpv(Perl_form(aTHX_
>>                                             "Apache2::RequestIO::_GEN_%ld",
>> +        /* now grab the just released fd, normally 0 */
>> +        handle_save_fd = gv_fetchpv("GENX2", TRUE, SVt_PVIO);
>> +
>> +        /* open my $oldout, "<&=0" or die "Can't save STDIN's fd: $!"; */
>> +        status = do_open(handle_save_fd, "</dev/null", 10, FALSE,
>> +                         O_RDONLY, 0, Nullfp);
> [...]
> You don't want that IMO, you want the fd 0 and 1 to point to the
> socket so that the CGI has both its stdin and stdout pointing to
> the socket, because that's how unmodified CGI scripts do.
> system("echo foo");
> Should output "foo\n" to the page returned by the CGI. and echo
> foo does a write(1, "foo\n", 4);
> I must confess I tried to follow in the perl code what that
> do_open9 call that was supposed to dup the socket into
> stdin/stdout was doing but didn't get very far. I tried to
> replace those perl functions to real close() and dup()s but it
> didn't help either.

Yes, do_openn (do_open9 is just a wrapper) is hairy. I spent hours 
deciphering it. I hope the above explanation makes the issue with lack 
of dup() clear.

Stas Bekman
The "Practical mod_perl" book

View raw message