FAQ

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 mailto:stas@stason.org http://stason.org/
http://www.linkedin.com/in/stasbekman http://stasosphere.com/
The "Practical mod_perl" book http://modperlbook.org/
http://stason.org/photos/gallery/ http://healingcloud.com

Search Discussions

Discussion Posts

Previous

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 11 of 11 | next ›
Discussion Overview
groupmodperl @
categoriesmodperl, perl
postedMar 29, '07 at 8:21p
activeApr 3, '07 at 11:20p
posts11
users5
websiteperl.apache.org

People

Translate

site design / logo © 2017 Grokbase