|
Normally a process terminates in one of the two ways. Either the executing program calls the exit function, or the program’s main function returns. Each process has an exit code: a number that the process returns to its parents. The exit code is the argument passed to the exit function or the value returned from the main.
In response to a signal, abnormal termination of a process can also take place. For instance a SIGBUS, SIGSEGV, and SIGFPE signals cause the process to terminate. Other signals are used to terminate a process explicitly. The SIGINT signal is sent to a process when the user attempts to end it by typing Ctrl+C in its terminal. The SIGTERM signal is sent by the kill command. The default disposition for both of these is to terminate the process. By calling the abort function, a process sends itself a SIGABRT signal, which terminates the process and produces a core file. The most powerful termination signal is SIGKILL, which ends a process immediately and cannot be blocked or handled by a program.
Any of these signals can be sent using the kill command by specifying an extra command-line flag, for instance, to end a troublesome process by sending it a SIGKILL, invoke the following, where PID is its process id:
% kill –KILL pid
To send a signal from a program, use the kill function. The first parameter is the target process id. The second parameter is the signal number; use SIGTERM to simulate the default behavior of the kill command. For instance, where child pid contains the process id of the child process, you can use the kill function to terminate a child process from the parent by calling it like this:
kill(child_pid,SIGTERM);
Include the <sys/types.h> and <signal.h> headers if kill function is to be used.
By convention, the exit code is used to indicate whether the program executed correctly.
Correct execution of code is indicated by an exit code of zero, while for error representation a non-zero exit code is used. Nature of the error can also be deduced by the non-zero value returned for errors. It is a good idea to stick with this convention in programs because other components of the GNU/Linux system assume this behavior. For instance, shell assume this convention when you connect multiple programs && (logical end) and || (logical or) operators. Therefore if not an error always an explicit zero should be returned from your main function.
With most shells, it is possible to obtain the exit code of the most recently executed program using the special $? variable. Here is an example where two times invocation of ls command is done along with its exit code being displayed each time. In the first case, ls execute correctly and return the exit code zero. In the second case, ls encounter an error (because the file name specified on the command line does not exist) and thus returns a non-zero exit code.
% ls
bin
etc
lib
tmp
var
% echo $?
0
% ls bogusfile
ls : bogusfile : No such file or directory
% echo $?
1
Note that even though the parameter type of the exit function is int and the main function returns an in, linux does not preserve the full 32 bits of the return code. Exit codes from 0 to 127 should only be used. A special meaning is attached to exit codes above 128 i.e. exit code is 128 plus the signal number if a signal is used to terminate the process.
Waiting for Process Termination
In some situations it is desirable for the parent process to wait until one or more child processes have completed. This can be done with the wait family of system calls. These functions allow you to wait for a process to finish executing. There are four different system calls in the wait family; user can choose to get a little or a lot of information about the process that exited, and user can choose whether he wants to care about which child process terminated.
|