最近有用到system()調用,對它的返回值很是模糊,先貼下源碼,以下:shell
int system(const char *command) { pid_t pid; sig_t intsave, quitsave; sigset_t mask, omask; int pstat; char *argp[] = {"sh", "-c", NULL, NULL}; if (!command) /* just checking... */ return(1); argp[2] = (char *)command; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &omask); switch (pid = vfork()) { case -1: /* error */ sigprocmask(SIG_SETMASK, &omask, NULL); return(-1); case 0: /* child */ sigprocmask(SIG_SETMASK, &omask, NULL); execve(_PATH_BSHELL, argp, environ); // 若是順利執行的話,該子進程上下文就被shell進程上下文給替換了 _exit(127); //只有execve執行失敗,纔有可能執行這行代碼! } intsave = signal(SIGINT, SIG_IGN); quitsave = signal(SIGQUIT, SIG_IGN); pid = waitpid(pid, (int *)&pstat, 0); // 等待子進程退出,也有可能被信號中斷 sigprocmask(SIG_SETMASK, &omask, NULL); (void)signal(SIGINT, intsave); (void)signal(SIGQUIT, quitsave); return (pid == -1 ? -1 : pstat); // 返回-1表明waitpid被信號中斷,不然返回pstat //這個pstat通常包含兩部分信息:最低 8 位, 表明命令是否被順利執行的信息, 再往高8位表明執行該命令的結果 } 如今讓咱們我看下返回的結果。 1 表明 command 爲 NULL -1 表明 vfork 失敗 或者 waitpid 被中斷 127 (0x7F) execve調用shell執行命令切換上下文不成功 (緣由多是 命令不存在或者系統沒有shell 等) pstat 須要經過下面幾個宏對命令是否被順利執行以及命令執行的結果 //1.肯定命令是否被順利執行 #define WIFEXITED(s) (WTERMSIG(s) == 0) //命令被順利執行 #define WIFSTOPPED(s) (WTERMSIG(s) == 0x7f) //被信號暫停 #define WIFSIGNALED(s) (WTERMSIG((s)+1) >= 2) //被信號中斷 //2.查看命令執行的效果,以及出現沒執行完的緣由 #define WEXITSTATUS(s) (((s) & 0xff00) >> 8) #define WCOREDUMP(s) ((s) & 0x80) #define WTERMSIG(s) ((s) & 0x7f) #define WSTOPSIG(s) WEXITSTATUS(s)
如來自http://my.oschina.net/renhc/blog/53580?fromerr=wEsSYHbL 的例子:函數
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被信號暫停執行,取得信號值 }
未完待續...ui