exec函數族
函數族說明
fork() 函數用於建立一個新的子進程,該子進程幾乎複製了父進程的全 部內容,但是,這個新建立的子進程如何執行呢?exec 函數族就提供了一個在進程中啟動另一個程式執行的 方法。它可以根據指定的檔案名稱或目錄名找到可執行檔,並用它來取代原調用進程的資料區段、程式碼片段和堆棧 段,在執行完之後,原調用進程的內容除了進程號外,其他全部被新的進程替換了。另外,這裡的可執行檔 既可以是二進位檔案,也可以是Linux下任何可執行檔指令檔。
在 Linux 中使用exec函數族主要有 兩種情況:
當進程認為自己不能再為系統和使用者做出任何貢獻時,就可以調用 exec 函數族中的任意 一個函數讓自己重生。
如果一個進程想執行另一個程式,那麼它就可以調用 fork() 函數建立一個進 程,然後調用 exec 函數族中的任意一個函數,這樣看起來就像通過執行應用程式而產生了一個新進程(這種 情況非常普遍)。
函數族文法
實際上,在Linux中並沒有exec()函數,而是由6個以 exec 開頭 的函數,它們之間的文法有細微差別。下表列出了 exec 函數族的6個成員函數的文法:
這6個函數在函數名和使用文法的規則上都有細微的區別,下面就從可執行檔尋找方式、參數傳遞方式和環 境變數這幾個方面進行比較。
尋找方式:表1中的前4個函數的尋找方式都是完整的檔案目錄路徑,而 最後兩個函數(也就是以 p 結尾的兩個函數)可以只給出檔案名稱,系統就會自動按照環境變數“$PATH” 所 指定的路徑進行尋找。
參數傳遞方式:exec函數族的參數傳遞有兩種:一種是逐個列舉的方式,而另 一種則是將所有參數整體構造指標數組傳遞。在這裡是以函數名的第5位字母來區分的,字母為 "l"(list)的表示逐個列舉參數的方式,其文法為const char *arg;字母為“v”(vector)的表示將 所有參數整體構造指標數組傳遞,其文法為 char *const argv[]。這裡的參數實際上就是使用者在使用這個可 執行檔案時所需的全部命令選項字串(包括該可執行程式命令本身)。要注意的是,這些參數必須以NULL結 束。
環境變數: exec函數族可以預設系統的環境變數,也可以傳入指定的環境變數。這裡以 “e” (environment)結尾的兩個函數 execle()和 execve()就可以在 envp[]中指定當前進程所使用的環境變數。
表2再對這6個函數中的函數名和對應文法做了一個小結,主要指出了函數名中每一位對應所表明的含 義,以此表加以記住這6個函數。
事實上,這6個函數中真正的系統調用只有execve(),其他5個都是庫函數,它們最終都會調用execve()這 個系統調用。在使用exec函數族時,一定要加上錯誤判斷語句。exec 很容易執行失敗,其中最常見的原因有 :
① 找不到檔案或路徑,此時 errno 被設定為 ENOENT。
② 數組argv 和 envp 忘記用NULL結束,此時,errno被設定為 EFAUL。
③ 沒有對應可執行檔的運行 許可權,此時 errno 被設定為EACCES。