剖析system()函數

     system()函數調用/bin/sh來執行參數指定的命令,/bin/sh 一般是一個軟連接,指向某個具體的shell,比如bash,-c選項是告訴shell從字符串command中讀取命令;
在該command執行期間,SIGCHLD是被阻塞的,好比在說:hi,內核,這會不要給我送SIGCHLD信號,等我忙完再說;
在該command執行期間,SIGINT和SIGQUIT是被忽略的,意思是進程收到這兩個信號後沒有任何動作。

     爲了更好的理解system()函數返回值,需要了解其執行過程,實際上system()函數執行了三步操作:
1.fork一個子進程;
2.在子進程中調用exec函數去執行command;
3.在父進程中調用wait去等待子進程結束。

對於fork失敗,system()函數返回-1。
如果exec執行成功,也即command順利執行完畢,則返回command通過exit或return返回的值。
(注意,command順利執行不代表執行成功,比如command:"rm debuglog.txt",不管文件存不存在該command都順利執行了)
如果exec執行失敗,也即command沒有順利執行,比如被信號中斷,或者command命令根本不存在,system()函數返回127.
如果command爲NULL,則system()函數返回非0值,一般爲1.

看完這些,可能有人對system()函數返回值還是不清楚,看源碼最清楚不過了,下面給出一個system()函數的實現
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成功,則返回子進程的返回狀態
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章