580 Chapter 27
be available if the program called chroot() before calling system(). If command is
non-NULL, then the return value for system() is determined according to the
remaining rules in this list.
z If a child process could not be created or its termination status could not be
retrieved, then system() returns –1.
z If a shell could not be execed in the child process, then system() returns a value
as though the child shell had terminated with the call _exit(127).
z If all system calls succeed, then system() returns the termination status of the
child shell used to execute command. (The termination status of a shell is the ter-
mination status of the last command it executes.)
It is impossible (using the value returned by system()) to distinguish the case
where system() fails to exec a shell from the case where the shell exits with the
status 127 (the latter possibility can occur if the shell could not find a program
with the given name to exec).
In the last two cases, the value returned by system() is a wait status of the same
form returned by waitpid(). This means we should use the functions described in
Section 26.1.3 to dissect this value, and we can display the value using our
printWaitStatus() function (Listing 26-2, on page 546).
Example program
Listing 27-7 demonstrates the use of system(). This program executes a loop that
reads a command string, executes it using system(), and then analyzes and displays
the value returned by system(). Here is a sample run:
$ ./t_system
Command: whoami
mtk
system() returned: status=0x0000 (0,0)
child exited, status=0
Command: ls | grep XYZ Shell terminates with the status of...
system() returned: status=0x0100 (1,0) its last command (grep), which...
child exited, status=1 found no match, and so did an exit(1)
Command: exit 127
system() returned: status=0x7f00 (127,0)
(Probably) could not invoke shell Actually, not true in this case
Command: sleep 100
Type Control-Z to suspend foreground process group
[1]+ Stopped ./t_system
$ ps | grep sleep Find PID of sleep
29361 pts/6 00:00:00 sleep
$ kill 29361 And send a signal to terminate it
$ fg Bring t_system back into foreground
./t_system
system() returned: status=0x000f (0,15)
child killed by signal 15 (Terminated)
Command: ^D$ Type Control-D to terminate program