Perl system command and return codes

Many of you must have used Perl as part of day to day automation.

Some teams use test harnesses made exclusively of Perl. This makes it easier to leverage various functionalitiesof text manipulation, file operations and process monitoring, etc which is needed for a functional test harness.

More often, system command is used to run an executable and its return code ($?) is used to compare with expected return code. Normally, a successs means value of $? is zero and failure if otherwise. This is good if you plan to write tests from scratch and team decides to go with certain conventions.

But, if you have no option but to run a set of tests which have been developed by other teams, and they might have decided to go with different return scheme, make sure you understand the following.

According to Perl documentation (search for "system PROGRAM LIST"): 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.

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;

}

Thus, if a test returns 10, then the value of $? after running system is 2560. You shift 8 bits to right and you get 1.

But, what they don't tell you is, if a test is returning 666, instead of returning 170496, you will get 154 (10011010)

system command will return only lowermost 8 bits after you have already shifted 8 bits (for signals and core dumps)

Thus,

If test is expected to return 666 --- 10 1001 1010 0000 0000

After shifting lowermost 8 bits, you would expect system to return --- 10 1001 1010 <- gone ->

But, system will return only lowermost 8 bits again :) --- <-gone-> 1001 1010 <- gone ->

so after shifting 8 bits you will get 154 (1001 1010 ) instead of 666 (10 1001 1010 )