"copy" from File::Copy fails but returns success

H

Henry Law

The CGI program, running under Apache, supports download of a file from
a Linux server running Perl 5.8.6. The files are stored compressed, so
the download program first copies the compressed file to a temporary
directory, then uncompresses it and handles the HTTP for the download.
My problem is that the use of "copy" from File::Copy appears to succeed
(with a TRUE return code) but then when I go to uncompress the file it's
not there.

Because of the CGI environment it's hard to give a fully-runnable
fragment, but here's the core of it.

$rc = copy ("/home/nfb/temp.txt", "/tmp/nfb");
my $output = "Return code:$rc<br>" . `ls -l /tmp/nfb`;
print "Content-type:
text/html\n\n<html><body><p>$output</p></body></html>\n";
exit 0;

The source file exists and is chmod 777. The result from the code above is

Return code:1
-rw-r--r-- 1 apache apache 5 Oct 16 09:34 /tmp/nfb

.... which shows that the copy succeeded (return code 1) but the file is
nevertheless not in the target directory /tmp/nfb. I'm baffled.

Any ideas? If you think it's a Linux or Apache configuration problem
then please say so and I'll take this to the relevant group; but this
code worked a few weeks ago and I've not touched the Apache
configuration since.
 
A

all mail refused

The CGI program, running under Apache, supports download of a file from
a Linux server running Perl 5.8.6. The files are stored compressed, so
the download program first copies the compressed file to a temporary
directory, then uncompresses it and handles the HTTP for the download.
My problem is that the use of "copy" from File::Copy appears to succeed
(with a TRUE return code) but then when I go to uncompress the file it's
not there.

Are you sure it's not a 0 return code that indicates success?
What is in $! afterward?

http://thinkexist.com/quotation/one_of_the_main_causes_of_the_fall_of_the_roman/165395.html
 
J

Josef Moellers

all said:
Are you sure it's not a 0 return code that indicates success?

From man File::Copy:

RETURN
All functions return 1 on success, 0 on failure. $! will
be set if an error was encountered.
 
J

Josef Moellers

Henry said:
The CGI program, running under Apache, supports download of a file from
a Linux server running Perl 5.8.6. The files are stored compressed, so
the download program first copies the compressed file to a temporary
directory, then uncompresses it and handles the HTTP for the download.
My problem is that the use of "copy" from File::Copy appears to succeed
(with a TRUE return code) but then when I go to uncompress the file it's
not there.

Because of the CGI environment it's hard to give a fully-runnable
fragment, but here's the core of it.

$rc = copy ("/home/nfb/temp.txt", "/tmp/nfb");
my $output = "Return code:$rc<br>" . `ls -l /tmp/nfb`;
print "Content-type:
text/html\n\n<html><body><p>$output</p></body></html>\n";
exit 0;

The source file exists and is chmod 777. The result from the code above is

Return code:1
-rw-r--r-- 1 apache apache 5 Oct 16 09:34 /tmp/nfb

... which shows that the copy succeeded (return code 1) but the file is
nevertheless not in the target directory /tmp/nfb.

Obviously, /tmp/nfb isn't a directory.
Any ideas? If you think it's a Linux or Apache configuration problem
then please say so and I'll take this to the relevant group; but this
code worked a few weeks ago and I've not touched the Apache
configuration since.

That's what they always say ;-)
 
B

Brian Wakem

Henry said:
The CGI program, running under Apache, supports download of a file from
a Linux server running Perl 5.8.6. The files are stored compressed, so
the download program first copies the compressed file to a temporary
directory, then uncompresses it and handles the HTTP for the download.
My problem is that the use of "copy" from File::Copy appears to succeed
(with a TRUE return code) but then when I go to uncompress the file it's
not there.

Because of the CGI environment it's hard to give a fully-runnable
fragment, but here's the core of it.

$rc = copy ("/home/nfb/temp.txt", "/tmp/nfb");
my $output = "Return code:$rc<br>" . `ls -l /tmp/nfb`;
print "Content-type:
text/html\n\n<html><body><p>$output</p></body></html>\n";
exit 0;

The source file exists and is chmod 777. The result from the code above
is

Return code:1
-rw-r--r-- 1 apache apache 5 Oct 16 09:34 /tmp/nfb

... which shows that the copy succeeded (return code 1) but the file is
nevertheless not in the target directory /tmp/nfb. I'm baffled.


The file *is* /tmp/nfb
 
P

Paul Lalli

My problem is that the use of "copy" from File::Copy appears to
succeed (with a TRUE return code) but then when I go to
uncompress the file it's not there.

Because of the CGI environment it's hard to give a fully-runnable
fragment, but here's the core of it.

$rc = copy ("/home/nfb/temp.txt", "/tmp/nfb");
my $output = "Return code:$rc<br>" . `ls -l /tmp/nfb`;
print "Content-type:
text/html\n\n<html><body><p>$output</p></body></html>\n";
exit 0;

The source file exists and is chmod 777. The result from the
code above is

Return code:1
-rw-r--r-- 1 apache apache 5 Oct 16 09:34 /tmp/nfb

... which shows that the copy succeeded (return code 1) but the
file is nevertheless not in the target directory /tmp/nfb. I'm
baffled.

Look at that ls output again. See that first dash? That means that /
tmp/nfb is a file, not a directory. You copied the file /home/nfb/
temp.txt to the *file* /tmp/nfb.

If a directory named /tmp/nfb does not already exist, then you need to
create it first:
unless (-e "/tmp/nfb") {
mkdir "/tmp/nfb" or die $!;
}

(Yes, yes, this is a race condition, and that's potentially bad. Only
you know the internals of your system to know whether or not it's
worth caring about - is /tmp/nfb something that gets repeatedly
created and deleted?)

Paul Lalli
 
B

Ben Morrow

Quoth Paul Lalli said:
Look at that ls output again. See that first dash? That means that /
tmp/nfb is a file, not a directory. You copied the file /home/nfb/
temp.txt to the *file* /tmp/nfb.

If a directory named /tmp/nfb does not already exist, then you need to
create it first:
unless (-e "/tmp/nfb") {
mkdir "/tmp/nfb" or die $!;
}

Better would be

my $dir = '/tmp/nfb';

-e $dir and ! -d $dir and unlink $dir
or die "can't unlink $dir: $!";
-d $dir or mkdir $dir
or die "can't mkdir $dir: $!";

which has the same race condition, but is proof against old copies of
the file hanging around.

Ben
 
H

Henry Law

Josef said:
Obviously, /tmp/nfb isn't a directory.

Danke sehr, Josef; and thanks to Brian, Paul and Ben for the same
observation and for the useful improvements.

Do you know how many times I've looked at that "ls" output, and
_completely_ failed to see that it had no "d" at the beginning? There's
none so blind as them that thinks they know what they see.

But that's the benefit of having other people help you with your problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top