exec函數族

         用fork函數創建子進程後,子進程往往要調用一種exec函數以執行另一個程序。當進程調用一種exec函數時,該進程完全由新程序代換,而新程序則從其 main函數開始執行。因爲調用exec並不創建新進程,所以前後的進程ID並未改變。exec只是用另一個新程序替換了當前進程的正文、數據、堆和棧段。有六種不同的exec函數可供使用,它們常常被統稱爲exec函數。這些exec函數都是UNIX進程控制函數。用fork可以創建新進程,用exec可以執行新的程序。exit函數和兩個wait函數處理終止和等待終止。這些是我們需要的基本的進程控制函數
        exec函數族的作用是根據指定的文件名找到可執行文件,並用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行文件。這裏的可執行文件既可以是二進制文件,也可以是任何Linux下可執行的腳本文件,如果不是可以執行的文件,那麼就解釋成爲一個shell文件
    與一般情況不同,exec函數族的函數執行成功後不會返回,因爲調用進程的實體,包括代碼段,數據段和堆棧等都已經被新的內容取代,只留下進程ID等一些表面上的信息仍保持原樣,頗有些神似"三十六計"中的"金蟬脫殼"。看上去還是舊的軀殼,卻已經注入了新的靈魂。只有調用失敗了,它們纔會返回一個-1,從原程序的調用點接着往下執行。

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);

首先execl和execv開頭的函數的區別是:execl開頭的函數採用了我們更容易習慣的方式,把參數一個一個列出來,然後以一個NULL表示結束。execv開頭的函數是以"char *argv[]"這樣的形式傳遞命令行參數。

注:
  • 命令行參數的第一個參數一般爲程序名本身。最後一個參數爲NULL;
  • 當exec函數執行完畢後,便立即退出當前進程,不執行後面的語句,所以常常先fork一個子進程,然後調用exec函數。
  • 其中只有execve是真正意義上的系統調用,其它都是在此基礎上經過包裝的庫函數。

不加:搜索路徑名,要求參數path必須是一個完整的路徑名
p:只賦一個文件名即可,函數會到環境變量PATH目錄中尋找可執行文件。否則要求參數path必須是一個完整的路徑名
e:函數傳遞指定參數envp,允許改變子進程的環境,無後綴e時,子進程使用當前程序的環境。envp也是一個以NULL結尾的字符串數組指針

返回值:出錯返回-1,成功不返回值。

system()會調用fork()產生子進程,由子進程來調用/bin/sh-c string來執行參數string字符串所代表的命令,此命令執行完後隨即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略。

int system(const char * string);
功能:執行shell命令
參數:string:要執行的shell命令
返回值:
        如果fork()失敗 返回-1:出現錯誤
                  如果exec()失敗,表示不能執行Shell,返回值相當於Shell執行了exit(127)
        如果執行成功則返回子Shell的終止狀態
如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數string爲空指針(NULL),則返回非零值>;。如果system()調用成功則最後會返回執行shell命令後的返回值,但是此返回值也有可能爲 system()調用/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。














發佈了44 篇原創文章 · 獲贊 14 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章