unexpected EXTENDED_OS_ERROR on Windows

G

Griff

hi there

I'm running ActiveState Perl v5.6.1 on Windows XP.

The code

$cmdstr = "copy old.txt new.txt";
system($cmdstr);
print "$^E";

produces the results
------------------------------------------
1 file(s) copied.
The system cannot find the file specified.
------------------------------------------
When I check the files old.txt and new.txt, the file copy has actually worked.
Why do I get this error message in EXTENDED_OS_ERROR ?
(If I print the "$^E" variable before running the program, I can see it is empty.)

Your assistance would be welcomed.

Thanks, Griff
 
T

Tore Aursand

I'm running ActiveState Perl v5.6.1 on Windows XP.

The code

$cmdstr = "copy old.txt new.txt";
system($cmdstr);
print "$^E";

[...]

Why rely on non-portable methods? I don't have the answer to your
question, but I have - most possibly - a solution to your problem.

Use the File::Copy module which comes with Perl;

#!/usr/bin/perl
#
use strict;
use warnings;
use File::Copy;

copy( 'old.txt', 'new.txt' ) or die "Copy failed; $!\n";
move( 'old.txt', 'new.txt' ) or die "Move failed; $!\n";

Please read the documentation for the File::Copy module for more
information and examples.
 
P

Paul Lalli

$cmdstr = "copy old.txt new.txt";
system($cmdstr);
print "$^E";

produces the results
it is empty.)

From perldoc perlvar:

Under Win32, $^E always returns the last error
information reported by the Win32 call
"GetLastError()" which describes the last error from
within the Win32 API. Most Win32-specific code will
report errors via $^E. ANSI C and Unix-like calls
set "errno" and so most portable Perl code will
report errors via $!.

Caveats mentioned in the description of $! generally
apply to $^E, also. (Mnemonic: Extra error
explanation.)

That tells us that $^E is set to th elast error from anywhere within the
Win32 API, regardless of the failure or sucess of the actual call that
initiated the procedure. My guess (and this is a complete guess) is
that Win32 internally makes several API calls for the copy command, one
of which is to see if the target of the copy already exists. Because it
does not, that call to that specific API procedure set the value of $^E.

The "caveats" mentioned above boil down to: The error indicators (such
as $! and $^E) are valid if and only if the immediately preceding system
command failed. That is why you should always check the return value of
the system call. If the system call failed, then and only then should
you bother examining the error indicating variables.

Hope this helps,
Paul Lalli
 
J

Joe Smith

Griff said:
system($cmdstr);
print "$^E";

$^E is set if there is an error.
$^E is *not* cleared on success; the previous (and now
irrelevant) error message is still there.
-Joe
 
G

Griff

Thanks everyone. In future I shall check the return value from system
before going into the detail of $^E.
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top