syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I'm used to successful system() calls returning zero, but I'm finding one (apparently) successful call that's returning 256:
C:\_32\pscrpt>type t1.txt Hello C:\_32\pscrpt>type t2.txt World C:\_32\pscrpt>perl -wle "$ret = system 'diff', '-u', 't1.txt', 't2.txt +';print $ret; print $?" --- t1.txt Mon Jun 6 22:42:29 2011 +++ t2.txt Mon Jun 6 22:42:42 2011 @@ -1 +1 @@ -Hello +World 256 256
Why would that system 'diff',... call be returning that value ?

Cheers,
Rob

Replies are listed 'Best First'.
Re: [Win32] Successful system() call returns 256
by toolic (Bishop) on Jun 06, 2011 at 13:18 UTC
    From my unix diff manpage:
    An exit status of 0 means no differences were found, 1 means some differences were found, and 2 means trouble.
    My unix diff returns 1 (not 0, as you expect) if there is a difference between the files (at the command line).

    But, the situation is a little different from within a Perl script. From system

    The return value is the exit status of the program as returned by the wait call. To get the actual exit value, shift right by eight (see below).
    This prints 1 for me on linux:
    print $? >> 8, "\n";

    Update: major re-wording.

Re: [Win32] Successful system() call returns 256
by BrowserUk (Patriarch) on Jun 06, 2011 at 14:20 UTC

    Try running the command from the command line and displaying what windows sees as the exit code before perl gets it hands on it:

    c:\test\xx>diff junk5.png junk6.png >nul & echo %errorlevel% 0 c:\test\xx>diff junk5.png junk4.png >nul & echo %errorlevel% 1

    The likely cause is that whilst Windows exit codes are ints, Perl internally truncates them to 8-bits before concatenating it with other bits that are meant to emulate child termination reasoning per the system docs:

    If you'd like to manually inspect system's failure, you can check all +possible failure modes by inspecting $? like this: if ($? == -1) { print "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; }

    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.
Re: [Win32] Successful system() call returns 256
by rovf (Priest) on Jun 06, 2011 at 14:24 UTC
    You probably have the Gnu diff for Windows? Try diff --version.

    Your diff returns exit code 1 (not 256 - you need to look at the "upper" byte), which typically means that the files are different. Nothing unusual here.
    -- 
    Ronald Fischer <ynnor@mm.st>
Re: [Win32] Successful system() call returns 256
by zek152 (Pilgrim) on Jun 06, 2011 at 13:21 UTC

    My win32 system does not have diff as a built in command. My guess is that you downloaded it. It would be difficult to help you without knowing what program you are using.

    From memory and experience often 'diff' type programs return 'succesful' when the compared files are identical and return '!successful' when the files differ. The typical thought is that it is more useful to use the exit code to indicate file difference (or lack thereof) in addition to if the command ran without error.

    Typically the exit code will be one value (say 1) if the files differ, another value (say 0) if they are the same, and a third value (say 2) if there was an error.

    Hope this helps.

    Update: typo found and fixed.

Re: [Win32] Successful system() call returns 256
by Anonymous Monk on Jun 06, 2011 at 22:14 UTC
    autodie, IPC::System::Simple, eval
    $ echo Hello >t1.txt $ echo World >t2.txt $ perl -wle " $ret = system q[diff -u t1.txt t2.txt >NUL 2>&1] ; print + $ret; print $?" 256 256 $ perl -Mautodie=system -wle " $ret = system q[diff -u t1.txt t2.txt > +NUL 2>&1] ; print $ret; print $?" "diff -u t1.txt t2.txt >NUL 2>&1" unexpectedly returned exit value 1 a +t (eval 10) line 13 at -e line 1 $ perl -MIPC::System::Simple=system -wle " $ret = system q[diff -u t1. +txt t2.txt >NUL 2>&1] ; print $ret; print $?" "diff -u t1.txt t2.txt >NUL 2>&1" unexpectedly returned exit value 1 a +t -e line 1
    After consulting
    $ diff --help |grep -i exit Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
    and some docs, you don't need eval, you could write
    $ perl -MIPC::System::Simple=system -wle " $ret = system [0,1], q[diff + -u t1.txt t2.txt >NUL 2>&1] ; print $ret; print $?" 1 256 $ perl -Mautodie=system -wle " $ret = system [0,1], q[diff -u t1.txt t +2.txt >NUL 2>&1] ; print $ret; print $?" 1 256
    [0, 1] are acceptable exit value, any others and IPC::System::Simple will croak
      Yeah - thanks guys.
      Like you say, it's just diff doing what it's supposed to do.

      Cheers,
      Rob