linux exec 二程序,二十五、Linux 进程与信号---exec函数
25.1 介紹
在用 fork 函數(shù)創(chuàng)建子進(jìn)程后,子進(jìn)程往往要調(diào)用一種 exec 函數(shù)以執(zhí)行另一個(gè)程序
當(dāng)進(jìn)程調(diào)用一種 exec 函數(shù)時(shí),該進(jìn)程完全由新程序代換,替換原有進(jìn)程的正文,而新程序則從其 main 函數(shù)開始執(zhí)行。因?yàn)檎{(diào)用 exec 并不創(chuàng)建新進(jìn)程,所以前后的進(jìn)程 ID 并未改變。exec 只是用另一個(gè)新程序替換了當(dāng)前進(jìn)程的正文、數(shù)據(jù)、堆和棧段。
exec 函數(shù)族也稱為代碼替換函數(shù)族
25.1.1 函數(shù)說明
#include
int execl(const char * path,const char * arg,....);
int execv (const char * path, char * const argv[ ]);
int execle(const char * path,const char * arg,....,char *const envp[]);
int execve(const char * filename,char * const argv[ ],char * const envp[ ]);
int execvp(const char *file ,char * const argv []);
int execlp(const char * file,const char * arg,……);
函數(shù)功能:
execl()用來執(zhí)行參數(shù) path 字符串所代表的文件路徑,接下來的參數(shù)代表執(zhí)行該文件時(shí)傳遞過去的argv(0)、argv[1]……,最后一個(gè)參數(shù)必須用空指針(NULL)作結(jié)束。
execv() 用來執(zhí)行參數(shù) path 字符串所代表的文件路徑,與 execl() 不同的地方在于 execve() 只需兩個(gè)參數(shù),第二個(gè)參數(shù)利用數(shù)組指針來傳遞給執(zhí)行文件。
execle() 是用來執(zhí)行參數(shù) path 字符串所代表的文件路徑,并為新程序復(fù)制最后一個(gè)參數(shù)所指示的環(huán)境變量。接下來的參數(shù)代表執(zhí)行該文件時(shí)傳遞過去的argv(0)、argv[1]……,最后一個(gè)參數(shù)必須用空指針(NULL)作結(jié)束。
execve()用來執(zhí)行參數(shù) filename 字符串所代表的文件路徑,第二個(gè)參數(shù)系利用數(shù)組指針來傳遞給執(zhí)行文件,最后一個(gè)參數(shù)則為傳遞給執(zhí)行文件的新環(huán)境變量數(shù)組。
execvp()會(huì)從PATH 環(huán)境變量所指的目錄中查找符合參數(shù)file 的文件名,找到后便執(zhí)行該文件,然后將第二個(gè)參數(shù)argv傳給該欲執(zhí)行的文件。
execlp() 會(huì)從 PATH 環(huán)境變量所指的目錄中查找符合參 file 的文件名,找到后便執(zhí)行該文件,然后將第二個(gè)以后的參數(shù)當(dāng)做該文件的 argv[0]、argv[1]……,最后一個(gè)參數(shù)必須用空指針 (NULL) 作結(jié)束。
返回值
出錯(cuò)返回 -1,錯(cuò)誤碼存放,成功則不返回
錯(cuò)誤碼
EACCES
欲執(zhí)行的文件不具有用戶可執(zhí)行的權(quán)限。
欲執(zhí)行的文件所屬的文件系統(tǒng)是以 noexec 方式掛上。
欲執(zhí)行的文件或 script 翻譯器非一般文件。
EPERM
進(jìn)程處于被追蹤模式,執(zhí)行者并不具有 root 權(quán)限,欲執(zhí)行的文件具有 SUID 或 SGID 位。
欲執(zhí)行的文件所屬的文件系統(tǒng)是以 nosuid 方式掛上,欲執(zhí)行的文件具有 SUID 或 SGID 位元,但執(zhí)行者并不具有 root 權(quán)限。
E2BIG 參數(shù)數(shù)組過大
ENOEXEC 無法判斷欲執(zhí)行文件的執(zhí)行文件格式,有可能是格式錯(cuò)誤或無法在此平臺(tái)執(zhí)行。
EFAULT 參數(shù) filename 所指的字符串地址超出可存取空間范圍。
ENAMETOOLONG 參數(shù) filename 所指的字符串太長(zhǎng)。
ENOENT 參數(shù) filename 字符串所指定的文件不存在。
ENOMEM 核心內(nèi)存不足
ENOTDIR 參數(shù) filename 字符串所包含的目錄路徑并非有效目錄
EACCES 參數(shù) filename 字符串所包含的目錄路徑無法存取,權(quán)限不足
ELOOP 過多的符號(hào)連接
ETXTBUSY 欲執(zhí)行的文件已被其他進(jìn)程打開而且正把數(shù)據(jù)寫入該文件中
EIO I/O 存取錯(cuò)誤
ENFILE 已達(dá)到系統(tǒng)所允許的打開文件總數(shù)。
EMFILE 已達(dá)到系統(tǒng)所允許單一進(jìn)程所能打開的文件總數(shù)。
EINVAL 欲執(zhí)行文件的ELF執(zhí)行格式不只一個(gè)PT_INTERP節(jié)區(qū)
EISDIR ELF翻譯器為一目錄
ELIBBAD ELF翻譯器有問題
注意點(diǎn)
execve 函數(shù)為系統(tǒng)調(diào)用,其余為庫函數(shù)。執(zhí)行 execve 函數(shù)后面的代碼不執(zhí)行
execlp 和 execvp 函數(shù)中的 path,相對(duì)和絕對(duì)路徑均可使用,其他四個(gè)函數(shù)中的 path 只能使用絕對(duì)路徑。相對(duì)路徑一定要在進(jìn)程環(huán)境表對(duì)應(yīng)的 PATH 中。
argv 參數(shù)為新程序執(zhí)行 main 函數(shù)中傳遞的 ?argv 參數(shù),最后一個(gè)元素為 NULL
envp 為進(jìn)程環(huán)境表
六個(gè)函數(shù)都使以 "exec"四個(gè)字母開頭的,后面的字母表示了其用法上的區(qū)別:
帶有字母 " l " 的函數(shù),表明后面的參數(shù)列表是要傳遞給程序的參數(shù)列表,參數(shù)列表的第一個(gè)參數(shù)必須是 要執(zhí)行的程序,最后一個(gè)參數(shù)必須是 NULL
帶有字母 “ p ”的函數(shù),第一個(gè)參數(shù)可用是相對(duì)路徑或程序名,如果無法立即找到要執(zhí)行的程序,那么就在環(huán)境變量 PATH 指定的路徑中搜索。其他函數(shù)的第一個(gè)參數(shù)必須是絕對(duì)路徑
帶有字母 " v "的函數(shù),表明程序的參數(shù)列表通過一個(gè)字符串?dāng)?shù)組來傳遞。這個(gè)數(shù)組和最后傳遞給程序的 main 函數(shù)的字符串?dāng)?shù)據(jù) argv 完全一樣。第一個(gè)參數(shù)必須是程序名,最后一個(gè)參數(shù)也必須是 NULL
帶有字母 " e " 的函數(shù),用戶可用自己設(shè)置程序接收一個(gè)設(shè)置環(huán)境變量的數(shù)組
六個(gè)函數(shù)之間的關(guān)系如下:
25.2 例子
#include
#include
#include
#include
#include
char *cmd1 = "cat"; //相對(duì)路徑
char *cmd2 = "/bin/cat";//絕對(duì)路徑
char *argv1 = "/etc/passwd";
char *argv2 = "/etc/group";
int main(void)
{
pid_t pid;
if((pid = fork()) < ){
perror("fork error");
exit();
} else if(pid == ) {
//子進(jìn)程調(diào)用 exec 函數(shù)執(zhí)行新的程序
//execl 不帶 p 需要用絕對(duì)路徑的
if(execl(cmd2, cmd1, argv1, argv2, NULL) < ) {
perror("execl error");
exit();
} else {
printf("execl %s success\n", cmd1);
}
}
wait(NULL);
printf("=================================\n");
if((pid = fork()) < ){
perror("fork error");
exit();
} else if(pid == ) {
char *argv[] = {cmd1, argv1, argv2, NULL};
if(execvp(cmd1, argv) < ) {
perror("execl error");
exit();
} else {
printf("execvp %s success\n", cmd1);
}
}
wait(NULL);
printf("=================================\n");
return ;
}
二十、Linux 進(jìn)程與信號(hào)---非局部跳轉(zhuǎn)
20.1 setjmp 和 longjmp 函數(shù) 20.1.1 函數(shù)介紹 #include int setjmp(jmp_buf env); 函數(shù)功能:設(shè)置非局部跳轉(zhuǎn) ...
二十六、Linux 進(jìn)程與信號(hào)---system 函數(shù) 和進(jìn)程狀態(tài)切換
26.1 system 函數(shù) 26.1.1 函數(shù)說明 system(執(zhí)行shell 命令)相關(guān)函數(shù) fork,execve,waitpid,popen #include
三十、Linux 進(jìn)程與信號(hào)——信號(hào)的概念及 signal 函數(shù)
30.1 信號(hào)的基本概念 信號(hào)(signal)機(jī)制是Linux 系統(tǒng)中最為古老的進(jìn)程之間的通信機(jī)制,解決進(jìn)程在正常運(yùn)行過程中被中斷的問題,導(dǎo)致進(jìn)程的處理流程會(huì)發(fā)生變化 信號(hào)是軟件中斷 信號(hào)是異步事件 ...
二十三、Linux 進(jìn)程與信號(hào)---進(jìn)程鏈和進(jìn)程扇、守護(hù)進(jìn)程和孤兒進(jìn)程以及僵尸進(jìn)程
23.1?進(jìn)程鏈和進(jìn)程扇 23.1.1 概念 進(jìn)程鏈:一個(gè)父進(jìn)程構(gòu)建出一個(gè)子進(jìn)程,子進(jìn)程再構(gòu)建出子子進(jìn)程,子子進(jìn)程構(gòu)建出子子子進(jìn)程.... 這種就為進(jìn)程鏈 進(jìn)程扇:一個(gè)父進(jìn)程構(gòu)建出多個(gè)子進(jìn)程,子進(jìn)程都 ...
二十四、Linux 進(jìn)程與信號(hào)---wait 函數(shù)
24.1 wait 函數(shù)說明 24.1.1 waitpid---等待子進(jìn)程中斷或結(jié)束 waitpid(等待子進(jìn)程中斷或結(jié)束) 相關(guān)函數(shù) wait,fork #include
二十一、Linux 進(jìn)程與信號(hào)---進(jìn)程查看和進(jìn)程狀態(tài)、進(jìn)程調(diào)度和進(jìn)程狀態(tài)變化、進(jìn)程標(biāo)識(shí)
21.1 進(jìn)程查看和進(jìn)程狀態(tài) 21.1.1 ps 指令 ps 指令通常可以查看到進(jìn)程的 ID.進(jìn)程的用戶 ID.進(jìn)程狀態(tài)和進(jìn)程的 Command ps:查看當(dāng)前用戶啟動(dòng)的進(jìn)程 ps -ef:詳細(xì)查看后 ...
二十一、Linux 進(jìn)程與信號(hào)---進(jìn)程資源限制
21.1 進(jìn)程資源限制 在操作系統(tǒng)中,我們能夠通過函數(shù)getrlimit().setrlimit()分別獲得.設(shè)置每個(gè)進(jìn)程能夠創(chuàng)建的各種系統(tǒng)資源的限制使用量. 21.1.1 函數(shù) #include & ...
二十七、Linux 進(jìn)程與信號(hào)---進(jìn)程組和組長(zhǎng)進(jìn)程
27.1 進(jìn)程組 27.1.1 進(jìn)程組介紹 進(jìn)程組為一個(gè)或多個(gè)進(jìn)程的集合 進(jìn)程組可以接受同一終端的各種信號(hào),同一個(gè)信號(hào)發(fā)送進(jìn)程組等于發(fā)送給組中的所有進(jìn)程 每個(gè)進(jìn)程組有唯一的進(jìn)程組 ID 進(jìn)程組的消亡要 ...
Linux學(xué)習(xí)之CentOS(二十六)--Linux磁盤管理:LVM邏輯卷的創(chuàng)建及使用
在上一篇隨筆里面?Linux學(xué)習(xí)之CentOS(二十五)--Linux磁盤管理:LVM邏輯卷基本概念及LVM的工作原理,詳細(xì)的講解了Linux的動(dòng)態(tài)磁盤管理LVM邏輯卷的基本概念以及LVM的工作原理, ...
隨機(jī)推薦
兩個(gè)viewport的故事(第二部分)
原文:http://www.quirksmode.org/mobile/viewports2.html 在這個(gè)迷你系列的文章里邊我將會(huì)解釋viewport,以及許多重要元素的寬度是如何工作的,比如&l ...
[vijos P1035] 貪婪的送禮者
為何我要做此等弱智題,只因我太久不碼代碼,心有所虛… 明天的任務(wù)是,做些難題,累了就理房間,實(shí)在不行就睡覺,不要做別的事情w?目測(cè)自己做不到呢OAO program vijos_p1035; ..] ...
Redis數(shù)據(jù)導(dǎo)入工具優(yōu)化過程總結(jié)
Redis數(shù)據(jù)導(dǎo)入工具優(yōu)化過程總結(jié) 背景 使用C++開發(fā)了一個(gè)Redis數(shù)據(jù)導(dǎo)入工具 從oracle中將所有表數(shù)據(jù)導(dǎo)入到redis中: 不是單純的數(shù)據(jù)導(dǎo)入,每條oracle中的原有記錄,需要經(jīng)過業(yè)務(wù)邏 ...
NSString+URLEncoding.h --使用Obj-C對(duì)數(shù)據(jù)等進(jìn)行URLEncoding編碼
在Objective-c進(jìn)行網(wǎng)絡(luò)編程時(shí),經(jīng)常需要把數(shù)據(jù)轉(zhuǎn)換成URLEncoding編碼,如對(duì)+號(hào)編碼后,變成%2b.這里我們給出一種實(shí)現(xiàn). //NSString+URLEncoding.h #impo ...
java和php實(shí)現(xiàn)RSA加密互通-b
java和PHP RSA加密實(shí)現(xiàn)互通 1:通過openssl?生成公鑰和密鑰文件(linux) (1)??生產(chǎn)私鑰文件命令 openssl genrsa -out rsa_private_key.pe ...
Oracle 最簡(jiǎn)單的隨系統(tǒng)自己主動(dòng)啟動(dòng)
Oracle 最簡(jiǎn)單的隨系統(tǒng)自己主動(dòng)啟動(dòng) 俗話說用戶是上帝,他們有時(shí)候提出一個(gè)問題很的簡(jiǎn)單,就僅僅須要一句話,一分鐘就完事了.可是拿到我們DBA來說,可能至少得半個(gè)小時(shí)甚至半個(gè)月才干滿足他的一句話.有 ...
新時(shí)代的Vim C++自動(dòng)補(bǔ)全插件 clang_complete
Vimer的福音 新時(shí)代的Vim C++自動(dòng)補(bǔ)全插件 clang_complete ? 使用vim的各位肯定嘗試過各種各樣的自動(dòng)補(bǔ)全插件,比如說大名鼎鼎的?OmniCppComplete?.這一類的插 ...
C# 之 反射性能優(yōu)化1
反射是一種很重要的技術(shù),然而它與直接調(diào)用相比性能要慢很多,因此如何優(yōu)化反射性能也就成為一個(gè)不得不面對(duì)的問題. 目前最常見的優(yōu)化反射性能的方法就是采用委托:用委托的方式調(diào)用需要反射調(diào)用的方法(或者屬性. ...
轉(zhuǎn)載 jQuery和js自定義函數(shù)和文件的方法(全網(wǎng)最全)
jQuery和js自定義函數(shù)和文件的方法(全網(wǎng)最全) ? ?版權(quán)聲明:本文為像霧像雨又像風(fēng)_http://blog.csdn.net/topdandan的原創(chuàng)文章,未經(jīng)允許不得轉(zhuǎn)載. https:// ...
我靠,上班eclipse看糗事百科
package test; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; ...
總結(jié)
以上是生活随笔為你收集整理的linux exec 二程序,二十五、Linux 进程与信号---exec函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中如何java联网,如何在Ja
- 下一篇: 基于linux的java学习,Java学