生活随笔
收集整理的這篇文章主要介紹了
进程控制2--exec族
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
系統調用exe函數族對當前進程進行替換,替換著為一個指定程序,其參數包括文件名filename,參數列表argv,以及環境變量envp
整個函數家族如下:
#include <unistd.h>
extern char **environ;
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[]);
在名字中缺“e”的是從當前進程中拷貝環境,有字母“p”的是可以在當前路徑中查找文件,而其他函數必須在指定路徑中找,這里要注意執行路徑,有安全隱患,慎用。
?
練習1:用系統命令替換
[cpp]?view plaincopy
?? #include?<unistd.h>?? main()?? {????? ?????? ????char?*envp[]={"PATH=/tmp",??"USER=lei",?"STATUS=testing",NULL};??? ?????? ????char?*argv_execv[]={"echo",?"excuted?by?execv",?NULL};???? ?????? ????char?*argv_execvp[]={"echo",?"executed?by?execvp",?NULL};?? ?????? ????char?*argv_execve[]={"env",?NULL};???? ?????? ????if(fork()==0)????????? ????????if(execl("/bin/echo",?"echo",?"executed?by?execl",?NULL)<0)???? ????????????perror("Err?on?execl");?? ????????if(fork()==0)????? ????????if(execlp("echo",?"echo",?"executed?by?execlp",?NULL)<0)?? ?? ????????????????perror("Err?on?execlp");?????? ????????????if(fork()==0)????????? ????????????????if(execle("/usr/bin/env",?"env",?NULL,?envp)<0)???? ????????????????????perror("Err?on?execle");?????? ????????????????if(fork()==0)????????? ????????????????????if(execv("/bin/echo",?argv_execv)<0)???? ????????????????????????perror("Err?on?execv");??? ????????????????????if(fork()==0)????? ????????????????????if(execvp("echo",?argv_execvp)<0)?????? ????????????????????????????perror("Err?on?execvp");?? ????????????????????????if(fork()==0)????????? ????????????????if(execve("/usr/bin/env",?argv_execve,?envp)<0)???????? ?? ????????????????????????????????perror("Err?on?execve");?? }??
程序里調用了2個Linux常用的系統命令,echo和env。echo會把后面跟的命令行參數原封不動的打印出來,env用來列出所有環境變量。
?
編譯,測試:
$ ./exec
executed by execl
executed by execlp
PATH=/tmp
USER=lei
STATUS=testing
executed by execlp
excuted by execv
executed by execvp
PATH=/tmp
USER=lei
STATUS=testing
?
練習2:子進程執行用戶自己編寫的程序
先寫父進程的程序:
[cpp]?view plaincopy
?? #include?<sys/types.h>?? #include?<unistd.h>?? #include?<stdio.h>?? ?? int?main(void)?? {?? ????pid_t?pid;?? ????const?char?*usr_envp[]?=?{"MYDEFINE=unknown","PATH=/home",NULL};?? ????printf("Begin?Fork()/n");?? ????pid?=?fork();?? ????switch(pid)?? ????{?? ????case?-1:?? ????????perror("fork?failed!/n");?? ????????break;?? ????case?0:?? ?????????? ????????if(execle("/home/child","myarg1","myarg2",(char?*)0,usr_envp))??? ????????perror("execle?failed!/n");?? ????????break;?? ????default:?? ????????break;?? ????}?? ?????? ????if(waitpid(pid,NULL,0)<0)?? ????????perror("waitpid?failed!/n");?? ????printf("parent?excting!");?? ????return?0;?? }??
然后我們編寫子進程要執行的程序:
[cpp]?view plaincopy
?? #include?<sys/types.h>?? #include?<unistd.h>?? #include?<stdio.h>?? int?main(int?argc,char?*argv[])?? {?? ????int?i;?? ????char?**pStr;?? ????extern?char?**environ;?? ????printf("child?starting!/n");?? ?????? ?????? ????for(i?=?0;i?<?argc;i++)?? ????{?? ????????printf("argv[%d]:%s/n",i,argv[i]);?? ????}?? ?????? ????for(pStr?=?environ;?*pStr?!=?0;pStr++)?? ????{?? ????????printf("%s/n",i,*pStr);?? ????}?? ????printf("child?exiting!/n");?? ????return?0;?? }??
然后編譯,執行parent
$ ./parent
Begin Fork()
child starting!
argv[0]:myargv1
argv[1]:myargv2
child exiting!
parent excting!
總結
以上是生活随笔為你收集整理的进程控制2--exec族的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。