Dawood Sangameshwari


Open Mind, Open Source
dawood [at] dawood.in
/ :: OpenSource :: *nix :: Understanding Exit Codes

Understanding exit codes

This article helps to understand what are exit codes and how they are used.
Execute following commands
ls /etc/passwd
echo $?
output of above command would be
0
On Unix, when you write C code, function main looks as
int main(int argc, char * argv[],char *envp[])
{
    return 0;
}
which says, return type of main is int,and main returns 0. Return (exit) code plays very important role. consider following command examples
command1 && command2
command1 || command2
In first example above, we want command2 to execute ONLY IF command1 is successful and in second example we want to execute command2 ONLY IF command1 is unsuccessful.
So, what is successful and unsuccessful?Lets try to understand this.
We have following four terms to understand.
1. Normal Program Termination
2. Abnormal Program Termination
3. Successful Program Termination
4. Unsuccessful Program Termination

1. Normal Program Termination

    If program executes all instructions written by developer its called as Normal Program Termination.

2. Abnormal Program Termination

    if program terminates without executing all instructions written by developer , is called as Abnormal Program Termination.
    This happens if program crashes OR is killed.

3. Successful Program Termination

    This is relative term. If program gives desired results, its successful program termination

4. Unsuccessful Program Termination

    This is relative term. If program does not give desired results, its successful program termination

So,
  1. If program terminates successfully it has to be normal termination.
  2. If program terminates abnormally it has to be unsuccessful termination.
  3. If program terminates unsuccessfully then
     - it could be normal termination
     - it could be abnormal termination

Exit codes:

     0
         Indicates successful program termination, hence normal termination.
     !0 (non zero)
         Indicates unsuccessful program termination, could be normal or abnormal termination
When you type command on shell, shell calls fork to create child process and then calls wait for child process to terminate. Once child process terminates kernel sends SIGCHLD or SIGCLD signal to shell. Now, Shell calls wait to get exit code of child process by calling wait system call.
wait system call allows to check how process died using macros.
     - WIFEXITED
         returns true if process terminated normally. then shell uses macro WEXITSTATUS to get exit code.
     - WIFSIGNALED
         returns true if the child process was terminated by a signal.thes shell uses macro WTERMSIG to get signal number.
Now what shell does is, if WIFEXITED is true then assigns value returned by WEXITSTATUS to $? and if WIFSIGNALED is true then assigns value returned by WTERMSIG to $?.
While assigning values to $?, shell assigns values as follows
1. Normal termination
     assigns return value of WEXITSTATUS
2. Abnormal termination i.e. process terminating because of some signal.
     assigns return value of WTERMSIG + 128
So,
if exit code of process is 0, this means program terminated successfully hence normally.
if exit code of process is !0 and < 128, this means program terminated unsuccessfully and normally so check manual of that program and find out what is meaning of that exit code.
if exit code of process is !0 and > 128, this means program terminated unsuccessfully and abnormally so exit code - 128 would give you signal number because of which process died.
Try following examples

Example 1

cat
now press ^D. this would terminate cat.
echo $?
this would print
0
cat terminated normally and successfully

Example 2

cat this_file_does_not_exist
cat would give error message and
echo $?
would print some non zero number < 128, on my Mac i got
1
cat terminated normally and unsuccessfully, you might want to check man page of cat and see what does exit code 1 mean.

Example 3

cat
Now, press ^C, this would terminate cat.
echo $?
this would print
130
As exit code is !0 this is unsuccessful termination and as its > 128 its abnormal termination.
exit code - 128 would give us signal number because of which cat terminated.
130 - 128 = 2. In this case cat terminated because of signal 2 (SIGINT) was delivered to it.
pressing ^C sends signal SIGINT to foreground process.


Was this tutorial useful? if yes consider writing comment.