进程控制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 plain copy
  1. /* exec.c */  
  2. #include <unistd.h>  
  3. main()  
  4. {     
  5.     /*定义参数*/  
  6.     char *envp[]={"PATH=/tmp",  "USER=lei""STATUS=testing",NULL};   
  7.       
  8.     char *argv_execv[]={"echo""excuted by execv", NULL};    
  9.       
  10.     char *argv_execvp[]={"echo""executed by execvp", NULL};  
  11.       
  12.     char *argv_execve[]={"env", NULL};    
  13.     /*全部在子进程运行*/  
  14.     if(fork()==0)         
  15.         if(execl("/bin/echo""echo""executed by execl", NULL)<0)  //调用echo命令,参数:executed by execl   
  16.             perror("Err on execl");  
  17.         if(fork()==0)     
  18.         if(execlp("echo""echo""executed by execlp", NULL)<0)  
  19. //调用echo命令,参数:executed by execlp      
  20.                 perror("Err on execlp");      
  21.             if(fork()==0)         
  22.                 if(execle("/usr/bin/env""env", NULL, envp)<0)  //env命令,打印当前环境envp  
  23.                     perror("Err on execle");      
  24.                 if(fork()==0)         
  25.                     if(execv("/bin/echo", argv_execv)<0)  //echo命令,参数argv_execv指向的内容  
  26.                         perror("Err on execv");   
  27.                     if(fork()==0)     
  28.                     if(execvp("echo", argv_execvp)<0)    //echo命令,参数argv_execvp指向的内容  
  29.                             perror("Err on execvp");  
  30.                         if(fork()==0)         
  31.                 if(execve("/usr/bin/env", argv_execve, envp)<0)        
  32. //env命令  
  33.                                 perror("Err on execve");  
  34. }  

程序里调用了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 plain copy
  1. /*parent.c*/  
  2. #include <sys/types.h>  
  3. #include <unistd.h>  
  4. #include <stdio.h>  
  5.   
  6. int main(void)  
  7. {  
  8.     pid_t pid;  
  9.     const char *usr_envp[] = {"MYDEFINE=unknown","PATH=/home",NULL};//路径  
  10.     printf("Begin Fork()/n");  
  11.     pid = fork();  
  12.     switch(pid)  
  13.     {  
  14.     case -1:  
  15.         perror("fork failed!/n");  
  16.         break;  
  17.     case 0:  
  18.         /*准备执行子进程的程序*/  
  19.         if(execle("/home/child","myarg1","myarg2",(char *)0,usr_envp)) //路径/home/child,参数...  
  20.         perror("execle failed!/n");  
  21.         break;  
  22.     default:  
  23.         break;  
  24.     }  
  25.     //等待子进程退出  
  26.     if(waitpid(pid,NULL,0)<0)  
  27.         perror("waitpid failed!/n");  
  28.     printf("parent excting!");  
  29.     return 0;  
  30. }  

然后我们编写子进程要执行的程序:

[cpp]  view plain copy
  1. /*child.c*/  
  2. #include <sys/types.h>  
  3. #include <unistd.h>  
  4. #include <stdio.h>  
  5. int main(int argc,char *argv[])  
  6. {  
  7.     int i;  
  8.     char **pStr;  
  9.     extern char **environ;  
  10.     printf("child starting!/n");  
  11.       
  12.     //打印出参数名  
  13.     for(i = 0;i < argc;i++)  
  14.     {  
  15.         printf("argv[%d]:%s/n",i,argv[i]);  
  16.     }  
  17.     //打印出路径名  
  18.     for(pStr = environ; *pStr != 0;pStr++)  
  19.     {  
  20.         printf("%s/n",i,*pStr);  
  21.     }  
  22.     printf("child exiting!/n");  
  23.     return 0;  
  24. }  

然后编译,执行parent

$ ./parent

Begin Fork()

child starting!

argv[0]:myargv1

argv[1]:myargv2

child exiting!

parent excting!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值