Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: $? set to strange values on failure under Win32

by BrowserUk (Patriarch)
on Jul 07, 2007 at 09:18 UTC ( [id://625398]=note: print w/replies, xml ) Need Help??


in reply to $? set to strange values on failure under Win32

You can distinguish between a successfully run command returning 1 and a failed command by checking $^E.

If $^E is empty, the command ran successfully and the contents of $? are the lower 8 bits << 8 of the 16-bit value returned by the executable.

If $^E is set, usually to The system cannot find the file specified, then the command could not be found--either directly, nor by running cmd.exe passing the parameter(s) supplied on the system call as argument(s) in the hope it can be resolved via the path--and $? contains the failure code (1) from cmd.exe.

This is when the ...' is not recognised as an internal or external command message is produced. This can be suppressed by redirecting stderr to null as in the 3rd example below:

#! perl -slw use strict; print 'Successful command returning 1'; system 'c:/perl/bin/perl.exe -e"sleep 5; exit 1"'; print "![$!] ?[@{[$?, ':', $?>>8]}] E[$^E]"; print "\nNonexistant command, attempted direct but fallback to via cmd +"; system 'c:/doesNotExists.exe'; print "![$!] ?[@{[$?, ':', $?>>8]}] E[$^E]"; print "\nNonexistant via cmd because of the presence of shell chars se +nding stderr >null"; system 'c:/doesNotExists.exe 2>null'; print "![$!] ?[@{[$?, ':', $?>>8]}] E[$^E]"; __END__ c:\test>junk Successful command returning 1 ![Bad file descriptor] ?[256 : 1] E[] Nonexistent command, attempted direct but fallback to via cmd 'c:/doesNotExists.exe' is not recognized as an internal or external co +mmand, operable program or batch file. ![No such file or directory] ?[256 : 1] E[The system cannot find the f +ile specified] Nonexistent via cmd because of the presence of shell chars sending std +err >null ![No such file or directory] ?[256 : 1] E[The system cannot find the f +ile specified]

The real problem here is that the win32 implementation of the posix system call attempts to emulate that call as best it can.

So, for example, return codes from executables above 255 get truncated to 8-bits and shifted left to leave room for signal values, which you can never receive.

And even if you supply multiple arguments to system, if the first attempt to run the command directly fails, it defaults to trying again, by supplying the commands you supply, to 'cmd.exe' to see if it can find the command.

This is not an exhaustive explanation of what goes on in Win32.c. I seem to recall tye posting a pretty comprehensive breakdown, but I can't persuade google to find it for me.

You might also want to look into using SetErrorMode() to (optionally) suppress system popups for things like segfaults and 'Insert disk for drive x:' and similar..


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: $? set to strange values on failure under Win32
by syphilis (Archbishop) on Jul 07, 2007 at 10:09 UTC
    If $^E is empty, the command ran successfully

    Yes, but the command can run successfully and, yet, there will still be an error message in $^E (which is merely the last error, n'est-ce pas ?). When I run the script you provided I get the following output:
    C:\_32\pscrpt>perl try.pl Successful command returning 1 ![Bad file descriptor] ?[256 : 1] E[The specified image file did not c +ontain a r esource section] Nonexistant command, attempted direct but fallback to via cmd 'c:/doesNotExists.exe' is not recognized as an internal or external co +mmand, operable program or batch file. ![No such file or directory] ?[256 : 1] E[There are no more files] Nonexistant via cmd because of the presence of shell chars sending std +err >null ![No such file or directory] ?[256 : 1] E[There are no more files]
    Admittedly 1) and 3) are different, but I wouldn't like to have to work out which had succeeded and which had failed based solely upon the ouptut :-)

    I'm at a loss for the moment to understand why the expected error message never appears in $^E for me. (I'm on Windows Vista - but I don't think that's an issue. I'll switch to XP and see what happens.)

    Cheers,
    Rob
    Update:On Windows 2000 I find that BrowserUk's script runs as he has reported. However, if one inserts a system'c:/doesNotExist.exe'; immediately below the use strict; in BrowserUk's script then $^E is no longer useful for determining whether the other three ensuing commands ran successfully or not. (My XP laptop has shit itself again, so I had to resort to Windows 2000).

      What results do you get on vista from this version?

      #! perl -slw use strict; undef $^E; undef $!; print 'Successful command returning 1'; system 'c:/perl/bin/perl.exe -e"sleep 5; exit 1"'; print "![$!] ?[@{[$?, ':', $?>>8]}] E[$^E]"; undef $^E; undef $!; print "\nNonexistent command, attempted direct but fallback to via cmd +"; system 'c:/doesNotExists.exe'; print "![$!] ?[@{[$?, ':', $?>>8]}] E[$^E]"; undef $^E; undef $!; print "\nNonexistent via cmd because 'shell chars'; sending stderr >nu +ll"; system 'c:/doesNotExists.exe 2>null'; print "![$!] ?[@{[$?, ':', $?>>8]}] E[$^E]"; __END__ C:\test>junk Use of uninitialized value in undef operator at C:\test\junk.pl line 4 +. Successful command returning 1 ![] ?[256 : 1] E[] Use of uninitialized value in undef operator at C:\test\junk.pl line 1 +0. Nonexistent command, attempted direct but fallback to via cmd 'c:/doesNotExists.exe' is not recognized as an internal or external co +mmand, operable program or batch file. ![No such file or directory] ?[256 : 1] E[The system cannot find the f +ile specified] Use of uninitialized value in undef operator at C:\test\junk.pl line 1 +6. Nonexistent via cmd because 'shell chars'; sending stderr >null ![] ?[256 : 1] E[The system cannot find the file specified]

      Aside: That Use of uninitialized value in undef operator ... wins the

      BrowserUk Award with Special Commendation" in the category of "Most Useless Warning of the Week Month Year Ever".

      And that's in a highly contested category. :)


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        What results do you get on vista from this version?

        It makes no difference on Vista (apart from occurrences of Use of uninitialized value in undef operator ... :-)

        However, on Windows 2000 (and probably XP, too) it has the desired effect. As long as the op does an undef($^E); before running the system command, I don't envisage any problem with your proposed solution on XP and Windows 2000.

        Here's a copy'n'paste of what I get on Vista:
        C:\_32\pscrpt>perl try.pl Use of uninitialized value in undef operator at try.pl line 4. Successful command returning 1 ![] ?[256 : 1] E[The specified image file did not contain a resource s +ection] Use of uninitialized value in undef operator at try.pl line 10. Nonexistent command, attempted direct but fallback to via cmd 'c:/doesNotExists.exe' is not recognized as an internal or external co +mmand, operable program or batch file. ![No such file or directory] ?[256 : 1] E[There are no more files] Use of uninitialized value in undef operator at try.pl line 16. Nonexistent via cmd because 'shell chars'; sending stderr >null ![] ?[256 : 1] E[There are no more files]
        I tried a couple of different builds of perl-5.8.8 on Vista (being sure to ammend the path to perl appropriately each time) and the output doesn't change.

        Anyway, pjf did specify "XP".

        Cheers,
        Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://625398]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-26 05:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found