Stas Bekman wrote:
Steve Hay wrote: [...]
I can't find in the CGI.pm manpage
It's right after the bit that you quoted :-) Lines 4439-4442 in the CGI.pm of 2.97.
, where it says that the filehandle should be closed, even on windows. Perhaps ask Lincoln?
Sorry, I don't understand. I said:
I can't find in the CGI.pm manpage, where it says that the filehandle should be closed, even on windows. Perhaps ask Lincoln?
I don't see where it says that on the lines that you've quoted.
My apologies, I only half-read what you said. I thought you were having trouble finding the bit that I'd quoted ;-)
;)
It doesn't actually say anywhere in the CGI.pm manpage that you must close the filehandle, even on Windows. That's just something that I've found from experience.
The bit that I quoted hints at a possible explanation: It is actually talking about a "private_tempfiles" option that the mod_perl test script doesn't use, but it mentions that on _Unix_ a file can be unlinked while it is open. The implication is that this perhaps can't be done on other OS's, and in practice I find that that is indeed the case on Windows, and probably explains what is going on here.
It does that mainly for security reasons as the manpage explains, so one won't be able to snoop easily on your files. I still maintain that this is either a bug in CGI.pm, or this side-effect should be *at least* documented.
If I run this test script:
========== use CGI; my $cgi = CGI->new(); print $cgi->header(), $cgi->start_html(), $cgi->start_multipart_form(); my $fh = $cgi->upload('upload'); if (defined $fh) { 1 while <$fh>; print $cgi->p(sprintf("Read %d bytes", tell $fh)); } else { print $cgi->filefield({-name => 'upload'}), $cgi->submit(); } print $cgi->end_form(), $cgi->end_html(); ==========
then the filehandle $fh gets left open, so when the DESTROY in CGI.pm's CGITempFile package runs and tries to unlink the temporary file it fails because you can't unlink a file while it is open on Windows.
In fact, adding some debug into that DESTROY subroutine:
unlink $safe # get rid of the file or print STDERR "Can't unlink '$safe': $!\n";
yields this error message in my Apache error.log:
Can't unlink 'C:\temp\CGItemp34790': Permission denied
If I add
close $fh;
to the end of the "if" block in my test script above then the error goes away and the file is deleted.
So, $fh is getting destroyed after $cgi, which leads to the problem. If $fh could be made to destroy before $cgi, the problem could be removed.
I think, the proper solution is for CGI.pm to register a cleanup handler, which will do the cleanup, after $cgi has gone. This will work for mod_perl, for plain cgi scripts perhaps an END block will do. Finally, making the returned filehandle an object, with its own destroy method may do the trick as well.
Another solution I can think of is to use Devel::Peek to reduce the reference count of all filehandles opened by CGI.pm to 0, from CGI::DESTROY, but that's probably too intrusive and it's also not the best idea to rely on dev-module ;)
Do we have the same problem with Apache::Request?
__________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
