#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.shell
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; } } } return status; //若是waitpid成功,則返回子進程的返回狀態 }
仔細看完這個system()函數的簡單實現,那麼該函數的返回值就清晰了吧,那麼何時system()函數返回0呢?只在command命令返回0時。
int status; if(NULL == cmdstring) //若是cmdstring爲空趁早閃退吧,儘管system()函數也能處理空指針 { return XXX; } status = system(cmdstring); if(status < 0) { printf("cmd: %s\t error: %s", cmdstring, strerror(errno)); // 這裏務必要把errno信息輸出或記入Log return XXX; } if(WIFEXITED(status)) { printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); //取得cmdstring執行結果 } else if(WIFSIGNALED(status)) { printf("abnormal termination,signal number =%d\n", WTERMSIG(status)); //若是cmdstring被信號中斷,取得信號值 } else if(WIFSTOPPED(status)) { printf("process stopped, signal number =%d\n", WSTOPSIG(status)); //若是cmdstring被信號暫停執行,取得信號值 }
到於取得子進程返回值的相關介紹能夠參考另外一篇文章:http://my.oschina.net/renhc/blog/35116bash
system()函數用起來很容易出錯,返回值太多,並且返回值很容易跟command的返回值混淆。這裏推薦使用popen()函數替代,關於popen()函數的簡單使用也能夠經過上面的連接查看。函數
popen()函數較於system()函數的優點在於使用簡單,popen()函數只返回兩個值:
成功返回子進程的status,使用WIFEXITED相關宏就能夠取得command的返回結果;
失敗返回-1,咱們能夠使用perro()函數或strerror()函數獲得有用的錯誤信息。spa
這篇文章只涉及了system()函數的簡單使用,尚未談及SIGCHLD、SIGINT和SIGQUIT對system()函數的影響,事實上,之因此今天寫這篇文章,是由於項目中因有人使用了system()函數而形成了很嚴重的事故。現像是system()函數執行時會產生一個錯誤:「No child processes」。.net
關於這個錯誤的分析,感興趣的朋友能夠看一下:http://my.oschina.net/renhc/blog/54582debug
2012-04-14 qdurenhongcai@163.com指針
轉載請註明出處。code