文章目錄
- 1.進程替換
- 2.替換過程
- 3.替換函數exec
- 3.1命名解釋
- 4.細說6個exe函數
- execl函數
- execv
- execlp、execvp
- execle、execve
1.進程替換
fork()函數在創建子進程后,子進程如果想要執行一個新的程序,就可以使用進程的程序替換來完成。
程序替換是通過特定的接口,加載磁盤上的一個全新的程序(代碼和數據),加載到調用進程的地址空間中。
2.替換過程
創建子進程后,子進程可以通過調用exec函數,來執行另一個程序。當程序調用exec函數時,該進程的用戶空間代碼和數據完完全全被新程序所替換,從新程序的啟動開始執行。調用exec函數并不創建新進程,所以該進程前后的id并未改變。
3.替換函數exec
實際上有六種以exec開頭的函數,統稱exec函數:
#include <unistd.h>
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 execve(const char *path, char *const argv[], char *const envp[]);
- 這些函數調用成功則加載新的程序從啟動代碼開始執行,不在返回。
- 如果調用失敗返回-1。
- exec函數只有出錯才有返回值。
參數
- filename / pathname:
filename:指定文件名作參數(filename當參數時,包含"/"會在指定路徑查找,不然按照PATH環境變量在指定路徑目錄查看可執行文件)
pathname:指定環境變量路徑作參數(路徑名+程序)
- 函數表傳參:
函數execl、execlp以及execle要求新程序的每一個命令行參數都說明一個單獨的參數,參數表以空指針結尾,一般方法:
> char *arg(), char *argl, ..., char *argn, (char *)0
這種語法說明了最后一個命令行參數之后跟一個空指針,如果用常量0表示,需要將它強制轉換成一個空指針,不然它將被解釋成整形參數,(比如上面:ls -l -a 被解釋成 ls -l -a 0),如果一個整形的長度與char*的長度不同,那么exec函數的實際參數將出錯。
其余4個函數,則先構造一個指向各參數的指針數組,然后將該數組指針地址作為這4個函數的參數。
- 環境變量表傳參
以e結尾的三個函數:execle、execve、fexecve:可以傳遞一個指向環境字符串指針數組的指針。
3.1命名解釋
- l(list):表示參數采用列表
- v(vector):參數用數組
- p(path):有p自動搜索環境變量PATH
- e(env):表示自己維護環境變量
4.細說6個exe函數
execl函數
原型:
int execl(const char *path, const char *arg, ...);
解釋:
- path:表示PATH環境變量路徑
- arg:表示執行什么命令
- …:可變參數列表,可以傳多個參數
例子:
execv
原型:
int execv(const char *path, char *const argv[]);
解釋:
- 與execl不同,execv傳遞的是一個char* const的數組,而execl傳遞的是一個個const char*
- v表示的就是數組
例子:
execlp、execvp
原型:
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
解釋:
結尾有p,表示自動搜索環境變量,不需要寫路徑,寫文件路徑就好。
實列:
execlp
execvp
execle、execve
以e結尾是要進行自己組裝環境變量
原型:
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execve(const char *filename, char *const argv[],char *const envp[]);
解釋:
- env是我們傳遞的全新的環境變量,對于env我們可以傳遞父進程的環境變量,也可以在父進程的環境變量上新增。
- 可以通過getenv()函數獲取環境變量
#include <stdlib.h>
char *getenv(const char *name);
實例:
execle
execvpe