Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

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

by syphilis (Archbishop)
on Jul 07, 2007 at 11:56 UTC ( [id://625411]=note: print w/replies, xml ) Need Help??


in reply to Re^3: $? set to strange values on failure under Win32
in thread $? set to strange values on failure under Win32

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

Replies are listed 'Best First'.
Re^5: $? set to strange values on failure under Win32
by pjf (Curate) on Jul 08, 2007 at 00:03 UTC

    BrowserUk/Rob, your responses are gold. Your answers are exactly the sort of information I was after.

    However it appears that $^E isn't yet my saviour. Under my Windows XP system I get the following results (uninitalized warnings trimmed):

    #! 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__ Successful command returning 1 ![] ?[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[] Nonexistent via cmd because 'shell chars'; sending stderr >null ![] ?[256 : 1] E[]

    It appears that redirecting stderr makes an unsuccessful command appear to be a successful command. When an error does occur, it's found inside $! and not $^E, which seems to never be set. Oh my!

    Unfortunately this leaves me with the same tangle as Perl itself has in emulating system() under Windows. Ideally I want to preserve the following behaviours:

    1. Single argument call always goes via the shell
    2. Multi argument call never goes via the shell
    3. It's possible to tell when a command didn't start (ostensibly via $? being set to -1)

    Using the shell means I don't have a reliable way of determining failure to start a command. Not using the shell means I may have to potentially go searching through $ENV{PATH} by hand.

    I guess this is an excellent opportunity for me to go searching for that discussion by tye, and potentially go looking through Perl's source for system() under Windows. I suspect my final result will make heavy use of Win32:: modules to provide the required behaviour.

    Many thanks again!

    Update: Working with Win32::Process is showing great promise.

      When an error does occur, it's found inside $! and not $^E

      Could $! then be used (instead of $^E) to determine the info you need ? Looking at what you, BrowserUk, and I have posted, it seems that $! might be all you need to consider (so long as it's undeffed before the system call). Or am I missing something ?

      Cheers,
      Rob
      Update: I have no problem with Paul's preference for Win32::Process. The variablility in $^E and $!, wrt to system(), doesn't inspire a lot of confidence.

        Using $! may be a possibility, but I've decided that moving with your suggestion of Win32::Process is better. It appears to be more consistent across operating systems, it allows us to access the whole 16 bits of the command's return value, it can be used to check if the command was successfully executed, and (at least on my system) it sets $^E to a meaningful value on failure.

        I've also discovered that my problem isn't unique to Windows. Under Unix, if Perl uses the shell then a value of 127 >> 8 is placed into $? on failure to find the command, which is indistinguishable from the command completing with a return of 127. Fundamentally, whenever we invoke the shell, we lose the ability to tell the difference between our final command failing to spawn, or spawning but returning a funny value. One should stress the wisdom of avoiding commands that return 1 under Windows, or 127 under Unix.

        It appears that Windows will still try to invoke the shell even if called with a multi-argument system(), whereas under Unix this never happens.

        The whole thing is still a huge pain for what I'm trying to achieve, but at least it's a (mostly) consistent huge pain across platforms.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-04-19 15:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found