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

Hi Monks,
I want to create a temporary file in a mod_perl2 handler. I thought this would work:
... open my $fh, '+>', undef or die $!; print $fh "hello"; # $r->send_fd is no longer in mod_perl, so I need a file name: $r->sendfile("<=&" . fileno($fh)); ...
Instead I get the error
"Apache2::RequestIO::sendfile('<=&24'): (2) No such file or directory ..."
What am I doing wrong? Thanks.

Replies are listed 'Best First'.
Re: temp filehandle to filename
by tilly (Archbishop) on Mar 31, 2009 at 16:22 UTC
    From the documentation it looks like sendfile is trying to find an actual file named <=&24 rather than (as you wanted) passing through some layer that will interpret that as an open filehandle.

    So you need an actual filename. For that I would suggest:

    use File::Temp qw(tempfile); use IO::Handle; # time passes my ($fh, $filename) = tempfile(); print $fh "hello"; $fh->flush(); $r->sendfile($filename);
      That works, thank you, tilly.
      It's moot now, but I'm still puzzled by the warning in the File::Temp doc:
      "For maximum security, endeavour always to avoid ever looking at, touching, or even imputing the existence of the filename. ...
      "If you need to pass the handle to something that expects a filename then use ... "+<=&" . fileno($fh) for Perl programs."
      Must depend on the internals of sendfile as you say.
        You're not passing it a Perl program, where there is a good chance of it getting passed to 2-arg open. You're passing it to sendfile which will definitely not call Perl's 2-arg open.
        The meaning of the security warning is that if you insist on having a filename, then there will be a file in the filesystem that other processes can find and look at. If you do not insist on having a filename then in many operating systems File::Temp will create and immediately unlink the temporary file. That gives you a file on disk which no other process can find, let alone read.

        The advice on passing data to Perl programs is bad. It will work if people use a 2 argument open. But not if they use a 3 argument open. But as Two-arg open() considered dangerous points out, you really should use the 3 argument version, which will break that meme. Someone should submit a patch to improve the documentation. (If I remember, I'll do it from home tonight.)

        Update: I remembered to send it in this morning.

Re: temp filehandle to filename
by ikegami (Patriarch) on Mar 31, 2009 at 16:13 UTC
    $r->sendfile requires a file name and <=&24 isn't the name of a file. Perhaps you shouldn't create a file with no name, or perhaps you should read in the file yourself and send it using $r->print.