Three Programs: test1.c test2.c test3.c
GCC test1.c-O test1
Call System ("./test1") in test2.c ");
GCC test2.c-O Test2
Call popen ("./Test2", "R") in test2.c ");
GCC test3.c-O test3
./Test3 found that system in test2.cz returned-1, but test1 was executed. View system source code
# Include <sys/types. h> <br/> # include <sys/Wait. h> <br/> # include <errno. h> <br/> # include <unistd. h> </P> <p> INT system (const char * character string) </P> <p >{< br/> pid_t PID; <br/> int status; <br/> If (empty string = NULL) {<br/> return (1 ); <br/>}</P> <p> If (pid = fork () <0) {<br/> Status =-1; <br/>}< br/> else if (pid = 0) {<br/> execl ("/bin/sh", "sh", "-c ", optional string, (char *) 0); <br/> _ exit (127 );// If the sub-process runs normally, this statement is not executed </P> <p >}< br/> else </P> <p >{< br/> while (waitpid (PID, & status, 0) <0) {<br/> If (errno! = Eintr) </P> <p >{< br/> Status =-1; <br/> break; <br/>}</P> <p> return status; <br/>}< br/>
It can be found that the system calls fork, exec, and waitpid in its implementation process, so there are three return values:
1) if fork fails or waitpid returns an error other than eintr, system returns-1 and errno sets the error type.
2) If exec fails (Exec cannot be executed), the return value is the same as that of exit (127) executed by shell.
3) otherwise, all three functions (fork, exec, and waitpid) are successful, and the return value of system is the termination state of shell. The format is described in waitpid.
So here I want system to return-1, which should be returned when waitpid is used, so I changed waitpid to wait and found that the return value of system is correct.
Check the Linux source code unistd. h and we will find that wait is the packaged waitpid:
Static inline pid_t wait (int * wait_stat)
{
Return waitpid (-1, wait_stat, 0 );
}
The return value of waitpid is slightly more complex than that of wait. There are three cases:
1. When the returned result is normal, waitpid returns the ID of the collected sub-process;
2. If the wnohang option is set, and waitpid in the call finds that no child process has exited to collect data, 0 is returned;
3. If an error occurs during the call,-1 is returned. errno is set to a value to indicate the error;
When the sub-process indicated by the PID does not exist or the process exists but is not a sub-process that calls the process, waitpid will return an error, and errno is set to echild.
Here, the error returned by waitpid should be when the parent process of the PID exits. Try to let the parent process sleep (10) and it will be OK.