日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

execve系统调用_Linux系统编程——进程替换:exec 函数族

發布時間:2024/7/23 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 execve系统调用_Linux系统编程——进程替换:exec 函数族 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 Windows 平臺下,我們可以通過雙擊運行可執行程序,讓這個可執行程序成為一個進程;而在 Linux 平臺,我們可以通過 ./ 運行,讓一個可執行程序成為一個進程。

但是,如果我們本來就運行著一個程序(進程),我們如何在這個進程內部啟動一個外部程序,由內核將這個外部程序讀入內存,使其執行起來成為一個進程呢?這里我們通過 exec 函數族實現。

exec 函數族,顧名思義,就是一簇函數,在 Linux 中,并不存在 exec() 函數,exec 指的是一組函數,一共有 6 個:

#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[]);

其中只有execve()是真正意義上的系統調用,其它都是在此基礎上經過包裝的庫函數。

exec 函數族提供了六種在進程中啟動另一個程序的方法。exec 函數族的作用是根據指定的文件名或目錄名找到可執行文件,并用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行文件。

進程調用一種 exec 函數時,該進程完全由新程序替換,而新程序則從其 main 函數開始執行。因為調用 exec 并不創建新進程,所以前后的進程 ID (當然還有父進程號、進程組號、當前工作目錄……)并未改變。exec 只是用另一個新程序替換了當前進程的正文、數據、堆和棧段(進程替換)。

exec 函數族的 6 個函數看起來似乎很復雜,但實際上無論是作用還是用法都非常相似,只有很微小的差別。

l(list):參數地址列表,以空指針結尾。

v(vector):存有各參數地址的指針數組的地址。

p(path):按 PATH 環境變量指定的目錄搜索可執行文件。

e(environment):存有環境變量字符串地址的指針數組的地址。

exec 函數族裝入并運行可執行程序 path/file,并將參數 arg0 ( arg1, arg2, argv[], envp[] ) 傳遞給此程序。

exec 函數族與一般的函數不同,exec 函數族中的函數執行成功后不會返回,而且,exec 函數族下面的代碼執行不到。只有調用失敗了,它們才會返回 -1,失敗后從原程序的調用點接著往下執行。

需要C/C++ Linux服務器架構師學習資料加qun獲取(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等),免費分享

execl() 示例代碼:

#include <stdio.h> #include <unistd.h>int main(int argc, char *argv[]) {printf("before execnn");/* /bin/ls:外部程序,這里是/bin目錄的 ls 可執行程序,必須帶上路徑(相對或絕對)ls:沒有意義,如果需要給這個外部程序傳參,這里必須要寫上字符串,至于字符串內容任意-a,-l,-h:給外部程序 ls 傳的參數NULL:這個必須寫上,代表給外部程序 ls 傳參結束*/execl("/bin/ls", "ls", "-a", "-l", "-h", NULL);// 如果 execl() 執行成功,下面執行不到,因為當前進程已經被執行的 ls 替換了perror("execl");printf("after execnn");return 0; }

運行結果如下:

execv()示例代碼:

execv() 和 execl() 的用法基本是一樣的,無非將列表傳參,改為用指針數組。

#include <stdio.h> #include <unistd.h>int main(int argc, char *argv[]) {// execv() 和 execl() 的用法基本是一樣的,無非將列表傳參,改為用指針數組// execl("/bin/ls", "ls", "-a", "-l", "-h", NULL);/* 指針數組ls:沒有意義,如果需要給這個外部程序傳參,這里必須要寫上字符串,至于字符串內容任意-a,-l,-h:給外部程序 ls 傳的參數NULL:這個必須寫上,代表給外部程序 ls 傳參結束*/char *arg[]={"ls", "-a", "-l", "-h", NULL};// /bin/ls:外部程序,這里是/bin目錄的 ls 可執行程序,必須帶上路徑(相對或絕對)// arg: 上面定義的指針數組地址execv("/bin/ls", arg);perror("execv");return 0; }

execlp() 或 execvp() 示例代碼:

execlp() 和 execl() 的區別在于,execlp() 指定的可執行程序可以不帶路徑名,如果不帶路徑名的話,會在環境變量 PATH指定的目錄里尋找這個可執行程序,而 execl() 指定的可執行程序,必須帶上路徑名。

#include <stdio.h> #include <unistd.h>int main(int argc, char *argv[]) {// 第一個參數 "ls",沒有帶路徑名,在環境變量 PATH 里尋找這個可執行程序// 其它參數用法和 execl() 一樣execlp("ls", "ls", "-a", "-l", "-h", NULL);/*char *arg[]={"ls", "-a", "-l", "-h", NULL};execvp("ls", arg);*/perror("execlp");return 0; }

execle() 或 execve() 示例代碼:

execle() 和 execve() 改變的是 exec 啟動的程序的環境變量(只會改變進程的環境變量,不會影響系統的環境變量),其他四個函數啟動的程序則使用默認系統環境變量。

execle()示例代碼:

#include <stdio.h> #include <unistd.h> #include <stdlib.h> // getenv()int main(int argc, char *argv[]) {// getenv() 獲取指定環境變量的值printf("before exec:USER=%s, HOME=%sn", getenv("USER"), getenv("HOME"));// 指針數據char *env[]={"USER=MIKE", "HOME=/tmp", NULL};/* ./mike:外部程序,當前路徑的 mike 程序,通過 gcc mike.c -o mike 編譯mike:這里沒有意義NULL:給 mike 程序傳參結束env:改變 mike 程序的環境變量,正確來說,讓 mike 程序只保留 env 的環境變量*/execle("./mike", "mike", NULL, env);/*char *arg[]={"mike", NULL}; execve("./mike", arg, env); */perror("execle");return 0; }

外部程序,mike.c 示例代碼:

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char *argv[]) {printf("nin the mike fun, after exec: n");printf("USER=%sn", getenv("USER"));printf("HOME=%sn", getenv("HOME"));return 0; }

運行結果如下:

總結

以上是生活随笔為你收集整理的execve系统调用_Linux系统编程——进程替换:exec 函数族的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。