Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   do 'file' -- when is file closed? (http://www.velocityreviews.com/forums/t897321-do-file-when-is-file-closed.html)

Brad Baxter 04-05-2006 03:43 PM

do 'file' -- when is file closed?
 
I am attempting to track down a "Too many open files"
situation in apache. This has led me to suspect some
of my Perl code, which is loaded by mod_rewrite from a
line like the following:

RewriteMap ggpd_do prg:/.../ggpd_do

.... and the script ggpd_do is then resident in memory
while apache is running.

Perl question: If a script like the following were loaded
as described above:

#!/usr/local/bin/perl -T
use warnings;
use strict;

$ENV{PATH} = '';

while( <STDIN> ) {
print get_file( $_ );
}

sub get_file {
my $file = shift;
chomp $file;
$file = $1 if /^(\w+)$/;
return '' unless $file;
my $ret = do "./$file";
return '' unless $ret;
return $ret;
}

.... when would "./$file" be closed? Right after 'do'? After
the script ends (which it wouldn't normally)?

Should I suspect code like this as a possible cause
for a "Too many open files" error?

Thanks,

--
Brad


xhoster@gmail.com 04-05-2006 04:10 PM

Re: do 'file' -- when is file closed?
 
"Brad Baxter" <baxter.brad@gmail.com> wrote:
....
>
> Perl question: If a script like the following were loaded
> as described above:
>
> #!/usr/local/bin/perl -T
> use warnings;
> use strict;
>
> $ENV{PATH} = '';
>
> while( <STDIN> ) {
> print get_file( $_ );
> }
>
> sub get_file {
> my $file = shift;
> chomp $file;
> $file = $1 if /^(\w+)$/;
> return '' unless $file;
> my $ret = do "./$file";
> return '' unless $ret;
> return $ret;
> }
>
> ... when would "./$file" be closed? Right after 'do'? After
> the script ends (which it wouldn't normally)?


I imagine this could be version/OS specific. On my machine, it closes
immediately after the do:

$ strace perl -wle 'use strict; defined do "./empty.pl" or die "1:$!"; \
defined do "./fooooo.pl" or die "2:$!"'


last few lines of the output:
.....
open("./empty.pl", O_RDONLY|O_LARGEFILE) = 3
....
read(3, "\n1;\n", 4096) = 4
read(3, "", 4096) = 0
close(3) = 0
open("./fooooo.pl", O_RDONLY|O_LARGEFILE) = -1
ENOENT (No such file or directory)
write(2, "2:No such file or directory at -"...,
422:No such file or directory at -e line 1.
) = 42
exit_group(2) = ?



So the file empty.pl (which, despite it's name, contains "1;") is opened,
read and closed, before the next statemnet, the non-existant file
fooooo.pl, is attempted.



Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB

Dr.Ruud 04-05-2006 04:24 PM

Re: do 'file' -- when is file closed?
 
Brad Baxter schreef:

> sub get_file {
> my $file = shift;
> chomp $file;
> $file = $1 if /^(\w+)$/;


That regex works on $_, so I assume that you meant

$file = $file if file ~= /^\w+$/;
;)

> return '' unless $file;
> my $ret = do "./$file";
> return '' unless $ret;
> return $ret;
> }


I guess this does about the same:

sub get_file {
chomp( my $file = shift );
return if ( $file !~ /^\w+$/ );
my $ret;
return $ret if ( $ret = do "./$file" );
return;
}

It is using a plain <return> in stead of <return ''>, which is often
better.

--
Affijn, Ruud

"Gewoon is een tijger."


Brad Baxter 04-05-2006 05:23 PM

Re: do 'file' -- when is file closed?
 
xhoster@gmail.com wrote:
> "Brad Baxter" <baxter.brad@gmail.com> wrote:
> ...
> >
> > Perl question: If a script like the following were loaded
> > as described above:
> >
> > #!/usr/local/bin/perl -T
> > use warnings;
> > use strict;
> >
> > $ENV{PATH} = '';
> >
> > while( <STDIN> ) {
> > print get_file( $_ );
> > }
> >
> > sub get_file {
> > my $file = shift;
> > chomp $file;
> > $file = $1 if /^(\w+)$/;
> > return '' unless $file;
> > my $ret = do "./$file";
> > return '' unless $ret;
> > return $ret;
> > }
> >
> > ... when would "./$file" be closed? Right after 'do'? After
> > the script ends (which it wouldn't normally)?

>
> I imagine this could be version/OS specific. On my machine, it closes
> immediately after the do:
>
> $ strace perl -wle 'use strict; defined do "./empty.pl" or die "1:$!"; \
> defined do "./fooooo.pl" or die "2:$!"'
>
>
> last few lines of the output:
> ....
> open("./empty.pl", O_RDONLY|O_LARGEFILE) = 3
> ...
> read(3, "\n1;\n", 4096) = 4
> read(3, "", 4096) = 0
> close(3) = 0
> open("./fooooo.pl", O_RDONLY|O_LARGEFILE) = -1
> ENOENT (No such file or directory)
> write(2, "2:No such file or directory at -"...,
> 422:No such file or directory at -e line 1.
> ) = 42
> exit_group(2) = ?
>
>
>
> So the file empty.pl (which, despite it's name, contains "1;") is opened,
> read and closed, before the next statemnet, the non-existant file
> fooooo.pl, is attempted.
>


Thanks for that. It's what I would have expected. Will check here.
Actually, I'll change the code to open and close explicitly anyway.

--
Brad


Brad Baxter 04-05-2006 05:31 PM

Re: do 'file' -- when is file closed?
 
Dr.Ruud wrote:
> Brad Baxter schreef:
>
> > sub get_file {
> > my $file = shift;
> > chomp $file;
> > $file = $1 if /^(\w+)$/;

>
> That regex works on $_, so I assume that you meant
>
> $file = $file if file ~= /^\w+$/;
> ;)


Good catch, but it needs to assign from $1 to untaint.

>
> > return '' unless $file;
> > my $ret = do "./$file";
> > return '' unless $ret;
> > return $ret;
> > }

>
> I guess this does about the same:
>
> sub get_file {
> chomp( my $file = shift );
> return if ( $file !~ /^\w+$/ );
> my $ret;
> return $ret if ( $ret = do "./$file" );
> return;
> }
>
> It is using a plain <return> in stead of <return ''>, which is often
> better.


Yes, and despite that it's contrived code, there were other
mistakes. Perhaps a little better:

#!/usr/local/bin/perl -T
use warnings;
use strict;

while( <STDIN> ) {
print get_file( $_ );
}

sub get_file {
my $file = shift;
chomp $file;
if( $file =~ /^(\w+)$/ ) {
$file = $1;
}
else {
return;
}
my $ret = do "./$file";
return unless $ret;
return $ret;
}

Cheers,

--
Brad


Brad Baxter 04-05-2006 06:43 PM

Re: do 'file' -- when is file closed?
 
xhoster@gmail.com wrote:
> I imagine this could be version/OS specific. On my machine, it closes
> immediately after the do:
>
> $ strace perl -wle 'use strict; defined do "./empty.pl" or die "1:$!"; \
> defined do "./fooooo.pl" or die "2:$!"'
>
>
> last few lines of the output:
> ....
> open("./empty.pl", O_RDONLY|O_LARGEFILE) = 3
> ...
> read(3, "\n1;\n", 4096) = 4
> read(3, "", 4096) = 0
> close(3) = 0
> open("./fooooo.pl", O_RDONLY|O_LARGEFILE) = -1
> ENOENT (No such file or directory)
> write(2, "2:No such file or directory at -"...,
> 422:No such file or directory at -e line 1.
> ) = 42
> exit_group(2) = ?
>
>
>
> So the file empty.pl (which, despite it's name, contains "1;") is opened,
> read and closed, before the next statemnet, the non-existant file
> fooooo.pl, is attempted.


And similarly here:

This is perl, v5.8.6 built for sun4-solaris

$ truss /usr/local/bin/perl -wle 'use strict; defined do "./empty.pl"
or die "1:$!"; defined do "./fooooo.pl" or die "2:$!"'

....
open64("./empty.pl", O_RDONLY) = 3
fstat64(3, 0xFFBFCB60) = 0
fstat64(3, 0xFFBFCA08) = 0
ioctl(3, TCGETA, 0xFFBFCAEC) Err#25 ENOTTY
read(3, " 1 ;\n\n", 8192) = 4
llseek(3, 0, SEEK_CUR) = 4
read(3, 0x0012DD64, 8192) = 0
llseek(3, 0, SEEK_CUR) = 4
close(3) = 0
open64("./fooooo.pl", O_RDONLY) Err#2 ENOENT
fstat64(2, 0xFFBFF0F8) = 0
write(2, " 2 : N o s u c h f i".., 42) = 42
getcontext(0xFFBFF2B0)
setcontext(0xFFBFF2B0)
getcontext(0xFFBFF650)
_exit(2)

I'm pretty sure that answers my question.

Many thanks,

--
Brad


Glenn Jackman 04-05-2006 06:58 PM

Re: do 'file' -- when is file closed?
 
At 2006-04-05 01:31PM, Brad Baxter <baxter.brad@gmail.com> wrote:
> sub get_file {
> my $file = shift;
> chomp $file;
> if( $file =~ /^(\w+)$/ ) {
> $file = $1;
> }
> else {
> return;
> }
> my $ret = do "./$file";
> return unless $ret;
> return $ret;
> }


That's a lot of returns. How about:

sub get_file {
chomp( my $file = shift );
my $ret;
if ($file =~ /^(\w+)$/) {
$ret = do "./$1";
}
return $ret;
}
my $rc = get_file 'foo.pl';
warn "couldn't do 'foo.pl'\n" unless $rc;


--
Glenn Jackman
Ulterior Designer

A. Sinan Unur 04-05-2006 07:16 PM

Re: do 'file' -- when is file closed?
 
Glenn Jackman <xx087@freenet.carleton.ca> wrote in
news:slrne384q8.p37.xx087@smeagol.ncf.ca:

> At 2006-04-05 01:31PM, Brad Baxter <baxter.brad@gmail.com> wrote:
>> sub get_file {
>> my $file = shift;
>> chomp $file;
>> if( $file =~ /^(\w+)$/ ) {
>> $file = $1;
>> }
>> else {
>> return;
>> }
>> my $ret = do "./$file";
>> return unless $ret;
>> return $ret;
>> }

>
> That's a lot of returns. How about:
>
> sub get_file {
> chomp( my $file = shift );
> my $ret;
> if ($file =~ /^(\w+)$/) {
> $ret = do "./$1";
> }
> return $ret;
> }


I would have used

sub get_file {
# I think chomping should be done by caller, but anyway
chomp(my $file = shift);
return unless $file =~ /^(\w+)$/;
return do "./$1";
}



> my $rc = get_file 'foo.pl';
> warn "couldn't do 'foo.pl'\n" unless $rc;
>
>




--
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc...uidelines.html



All times are GMT. The time now is 04:48 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.