linux进程---exec族函数(execl, execlp, execv, execvp, )解释和配合fork的使用
exec族函數(shù)函數(shù)的作用:
 ????????exec函數(shù)族的作用是根據(jù)指定的文件名找到可執(zhí)行文件,并用它來(lái)取代調(diào)用進(jìn)程的內(nèi)容,換句話(huà)說(shuō),就是在調(diào)用進(jìn)程內(nèi)部執(zhí)行一個(gè)可執(zhí)行文件。這里的可執(zhí)行文件既可以是二進(jìn)制文件,也可以是任何Linux下可執(zhí)行的腳本文件。
 ????????與一般情況不同,exec函數(shù)族的函數(shù)執(zhí)行成功后不會(huì)返回,因?yàn)檎{(diào)用進(jìn)程的實(shí)體,包括代碼段,數(shù)據(jù)段和堆棧等都已經(jīng)被新的內(nèi)容取代,只留下進(jìn)程ID等一些表面上的信息仍保持原樣,頗有些神似"三十六計(jì)"中的"金蟬脫殼"??瓷先ミ€是舊的軀殼,卻已經(jīng)注入了新的靈魂。只有調(diào)用失敗了,它們才會(huì)返回一個(gè)-1,從原程序的調(diào)用點(diǎn)接著往下執(zhí)行。
 ????????我們應(yīng)該明白了,Linux下是如何執(zhí)行新程序的,每當(dāng)有進(jìn)程認(rèn)為自己不能為系統(tǒng)和用戶(hù)做出任何貢獻(xiàn)了,他就可以發(fā)揮最后一點(diǎn)余熱,調(diào)用任何一個(gè)exec,讓自己以新的面貌重生;或者,更普遍的情況是,如果一個(gè)進(jìn)程想執(zhí)行另一個(gè)程序,它就可以fork出一個(gè)新進(jìn)程,然后調(diào)用任何一個(gè)exec,這樣看起來(lái)就好像通過(guò)執(zhí)行應(yīng)用程序而產(chǎn)生了一個(gè)新進(jìn)程一樣。
 函數(shù)族
 ????????exec函數(shù)族分別是:execl, execlp, execle, execv, execvp, execvpe 但是對(duì)于初學(xué)者來(lái)說(shuō)先學(xué)習(xí)一下四個(gè)exec族函數(shù)。
 返回值
 ????????如果執(zhí)行成功則函數(shù)不會(huì)返回,執(zhí)行失敗則直接返回-1,原程序接著從調(diào)用處執(zhí)行,失敗原因存于errno 中。
 函數(shù)原型
參數(shù)說(shuō)明
 path:可執(zhí)行文件的路徑名字
 arg:可執(zhí)行程序所帶的參數(shù),第一個(gè)參數(shù)為可執(zhí)行文件名字,沒(méi)有帶路徑且arg必須以NULL結(jié)束
 file:如果參數(shù)file中包含/,則就將其視為路徑名,否則就按 PATH環(huán)境變量,在它所指定的各目錄中搜尋可執(zhí)行文件。
exec族函數(shù)參數(shù)極難記憶和分辨,函數(shù)名中的字符會(huì)給我們一些幫助:
 l : 使用參數(shù)列表
 p:使用文件名,并從PATH環(huán)境進(jìn)行尋找可執(zhí)行文件
 v:應(yīng)先構(gòu)造一個(gè)指向各參數(shù)的指針數(shù)組,然后將該數(shù)組的地址作為這些函數(shù)的參數(shù)。
 e:多了envp[]數(shù)組,使用新的環(huán)境變量代替調(diào)用進(jìn)程的環(huán)境變量
execl函數(shù)
int execl(const char *path, const char *arg, ...); #include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("before execl \n");if(execl("./exec","echoarg","abc",NULL)==-1)//要求exec結(jié)尾必須是NULL//echoarg是argv[0],abc是argv[1] // ./exec是可執(zhí)行程序的路徑名{printf("execl failed \n");perror("why");//用來(lái)打印錯(cuò)誤}printf("after execl\n");return 0; }execl實(shí)現(xiàn)ls指令
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("before execl \n");if(execl("/bin/ls","ls",NULL,NULL)==-1){printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execl實(shí)現(xiàn) ls -l 指令
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("before execl \n");if(execl("/bin/ls","ls","-l",NULL)==-1)//這要在ls后給ls傳參-l即可{printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execl 獲取系統(tǒng)時(shí)間
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");if(execl("/bin/date","date",NULL,NULL)==-1){printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execlp函數(shù)
int execlp(const char *file, const char *arg, ...);file:如果參數(shù)file中包含/,則就將其視為路徑名,否則就按 PATH環(huán)境變量,在它所指定的各目錄中搜尋可執(zhí)行文件
獲取系統(tǒng)時(shí)間代碼
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");if(execlp("date","date",NULL,NULL)==-1)//第一個(gè)參數(shù)不含/所以按 PATH環(huán)境變量,在它所指定的各目錄中搜尋可執(zhí)行文件{printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execvp函數(shù)
int execvp(const char *file, char *const argv[]); //其實(shí)就是將execlp函數(shù)的后三個(gè)參數(shù) //寫(xiě)入創(chuàng)建已好的數(shù)組指針代碼演示
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");char*argv[]={"data",NULL,NULL};if(execvp("date",argv)==-1)printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }execv函數(shù)
int execv(const char *path, char *const argv[]); //其實(shí)就是將execl函數(shù)的后三個(gè)參數(shù) //寫(xiě)入創(chuàng)建已好的數(shù)組指針代碼演示
#include<stdio.h> #include<stdlib.h> #include<unistd.h> //int execl(const char*path,const char *arg,..) int main() {printf("this pro get system date: \n");char*argv[]={"data",NULL,NULL};if(execv("/bin/date",argv)==-1){printf("execl failed \n");perror("why");}printf("after execl\n");return 0; }exec配合fork使用代碼示例
#include<stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> int main() {pid_t fpid;int data;while(1){printf("please input a data\n");scanf("%d",&data);if(data==1){fpid=fork();if(fpid>0){wait(NULL);}if(fpid==0){execl("./changedata","changedata","config.txt",NULL);}}else{printf("do nothing\n");}}return 0; } //調(diào)用在子進(jìn)程中調(diào)用exec去執(zhí)行修改文件中的數(shù)值以下代碼和上面的代碼效果相同
#include<stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> int main() {pid_t fpid;int data;while(1){printf("please input a data\n");scanf("%d",&data);if(data==1){fpid=fork();if(fpid>0){wait(NULL);}if(fpid==0){int fdSrc;char* readbuf=NULL;fdSrc=open("config.txt",O_RDWR);int size=lseek(fdSrc,0,SEEK_END);readbuf=(char *)malloc(sizeof(char)*size+8);lseek(fdSrc,0,SEEK_SET);int n_read=read(fdSrc,readbuf,size);char *p=strstr(readbuf,"LENG=");if(p==NULL){printf("find fail\n");exit(-1);}p=p+strlen("LENG=");*p='5';lseek(fdSrc,0,SEEK_SET);int n_write=write(fdSrc,readbuf,strlen(readbuf));close(fdSrc);}}else{printf("do nothing\n");}}return 0; }總結(jié)
以上是生活随笔為你收集整理的linux进程---exec族函数(execl, execlp, execv, execvp, )解释和配合fork的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 冰点文库下载器绿色版V3.2.15(09
- 下一篇: system函数和popen函数使用方法
