Reprinted from: http://my.oschina.net/renhc/blog/53580
LinuxTry to avoid using system. Once, it was tortured by the system () function, because the system () function was not well understood. Simply knowing that using this function to execute a system command is not enough, it is not sufficient, its return value, the return value of the command it executes, and the reason for the failure of the command execution, which is the point. Originally because of this function risk is more, so abandon not use, use other method. Let's not say what I'm using here, it's important to understand the system () function, because there are still a lot of people using the system () function, and sometimes you have to face it. Let's take a look at a brief introduction to the System () function:
2 |
int system ( const char *command); |
System () executes a command specified in command by CALLING/BIN/SH-C command, and returns after the command have been Completed. During execution of the command, SIGCHLD would be blocked, and SIGINT and Sigquit would be ignored.
The system () function calls/bin/sh to execute the command specified by the parameter,/bin/sh is typically a soft connection, pointing to a specific shell, such as the BASH,-C option, which tells the Shell to read the command from the String command, and during the command execution, SIGCHLD is blocked, like saying: Hi, kernel, this will not send me sigchld signal, and so on I am busy to say; During the command execution, SIGINT and sigquit are ignored, meaning that the process receives both signals without any action. Take a look at the system () function return value: The value returned is-1 on error (e.g. fork (2) failed), and the return status of the command oth Erwise. This latter return status was in the format specified in Wait (2). Thus, the exit code of the command would be Wexitstatus (status). In case/bin/sh could not being executed, the exit status would be, the a command that does exit (127). If the value of command is NULL, System () returns nonzero if the shell was available, and zero if not. To better understand the system () function return value, To understand its execution, the system () function actually performs a three-step operation: 1.fork a subprocess; 2. Call the EXEC function in the subprocess to execute command;3. Call wait in the parent process to wait for the child process to end. For fork failure, the system () function returns-1. If exec executes successfully, that is, command executes successfully, returns the value returned by command via exit or return. (Note that command smooth execution does not mean execution succeeds, such as command: "rm debuglog.txt", regardless of whether the file does not exist, the command is executed successfully) if Exec fails, that is, command is not executed smoothly, such as by signal interruption, or command commands do not exist at all, the system () functionReturns 127. If command is NULL, the system () function returns a value other than 0, usually 1. look at the source code of the system () function read these, I want to be sure someone to the system () function return value is unclear, see the source is the clearest, The implementation of a system () function is given below:
01 |
int system ( const char * cmdstring) |
08 |
return (1); //如果cmdstring为空,返回非零值,一般为1 |
13 |
status = -1; //fork失败,返回-1 |
17 |
execl( "/bin/sh" , "sh" , "-c" , cmdstring, ( char *)0); |
18 |
_exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~ |
22 |
while (waitpid(pid, &status, 0) < 0) |
26 |
status = -1; //如果waitpid被信号中断,则返回-1 |
32 |
return status; //如果waitpid成功,则返回子进程的返回状态 |
After reading through the simple implementation of the system () function, the return value of the function is clear, so when does the system () function return 0? Returns 0 o'clock only in command commands. Take a look at how to monitor the system () function execution State Here's what I'm doing:
02 |
if (NULL == cmdstring) //如果cmdstring为空趁早闪退吧,尽管system()函数也能处理空指针 |
06 |
status = system (cmdstring); |
09 |
printf ( "cmd: %s\t error: %s" , cmdstring, strerror ( errno )); // 这里务必要把errno信息输出或记入Log |
15 |
printf ( "normal termination, exit status = %d\n" , WEXITSTATUS(status)); //取得cmdstring执行结果 |
17 |
else if (WIFSIGNALED(status)) |
19 |
printf ( "abnormal termination,signal number =%d\n" , WTERMSIG(status)); //如果cmdstring被信号中断,取得信号值 |
21 |
else if (WIFSTOPPED(status)) |
23 |
printf ( "process stopped, signal number =%d\n" , WSTOPSIG(status)); //如果cmdstring被信号暂停执行,取得信号值 |
To get a description of the return value of the child process refer to another article: http://my.oschina.net/renhc/blog/35116
The system () function is easily error-prone, returns too many values, and the return value can easily be confused with the command's return value. It is recommended to use the Popen () function instead, and the simple use of the Popen () function can also be viewed through the links above.
The advantage of the Popen () function over the system () function is that it is simple to use, and the Popen () function returns only two values:
The status of the child process is successfully returned, and the return result of the command can be obtained using the wifexited related macro;
Failure returns-1, we can use the Perro () function or the strerror () function to get useful error information.
This article deals only with the simple use of the system () function, and does not talk about the effects of SIGCHLD, SIGINT, and Sigquit on system () functions, and in fact, this article was written today because the system was used by someone in the project () The function caused a very serious accident. Now, as the system () function executes, an error occurs: "No child Processes".
For the analysis of this error, interested friends can take a look: http://my.oschina.net/renhc/blog/54582
Using the system () function under Linux must be cautious