#include <stdlib.h>
int system(const char *command);
?system()
executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.int system(const char *cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL)
{
return(1);//如果cmdstring爲空,返回非零值,一般爲1
}
if((pid = fork()) < 0)
{
status = -1; //fork失敗,返回-1
}
else if(pid == 0)
{
execl("/bin/sh","sh","-c", cmdstring, (char*)0);
_exit(127);// exec執行失敗返回127,注意exec只在失敗時才返回現在的進程,成功的話現在的進程就不存在啦~~
}
else//父進程
{
while(waitpid(pid, &status, 0) < 0)
{
if(errno!= EINTR)
{
status = -1; //如果waitpid被信號中斷,則返回-1
break;
}
}
}
returnstatus;//如果waitpid成功,則返回子進程的返回狀態
}
intstatus;
if(NULL == cmdstring) //如果cmdstring爲空趁早閃退吧,儘管system()函數也能處理空指針
{
returnXXX;
}
status = system(cmdstring);
if(status < 0)
{
printf("cmd: %s\t error: %s", cmdstring, strerror(errno));// 這裏務必要把errno信息輸出或記入Log
returnXXX;
}
if(WIFEXITED(status))
{
printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); //取得cmdstring執行結果
}
elseif(WIFSIGNALED(status))
{
printf("abnormal termination,signal number =%d\n", WTERMSIG(status)); //如果cmdstring被信號中斷,取得信號值
}
elseif(WIFSTOPPED(status))
{
printf("process stopped, signal number =%d\n", WSTOPSIG(status)); //如果cmdstring被信號暫停執行,取得信號值
}
system()函數用起來很容易出錯,返回值太多,而且返回值很容易跟command的返回值混淆。這裏推薦使用popen()函數替代,關於popen()函數的簡單使用也可以通過上面的鏈接查看。
popen()函數較於system()函數的優勢在於使用簡單,popen()函數只返回兩個值:
成功返回子進程的status,使用WIFEXITED相關宏就可以取得command的返回結果;
失敗返回-1,我們可以使用perro()函數或strerror()函數得到有用的錯誤信息。
這篇文章只涉及了system()函數的簡單使用,還沒有談及SIGCHLD、SIGINT和SIGQUIT對system()函數的影響,事實上,之所以今天寫這篇文章,是因爲項目中因有人使用了system()函數而造成了很嚴重的事故。現像是system()函數執行時會產生一個錯誤:“No child processes”。
關於這個錯誤的分析,感興趣的朋友可以看一下:http://my.oschina.net/renhc/blog/54582