进程控制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:用系统命令替换

/* exec.c */ #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) //调用echo命令,参数:executed by execl perror("Err on execl"); if(fork()==0) if(execlp("echo", "echo", "executed by execlp", NULL)<0) //调用echo命令,参数:executed by execlp perror("Err on execlp"); if(fork()==0) if(execle("/usr/bin/env", "env", NULL, envp)<0) //env命令,打印当前环境envp perror("Err on execle"); if(fork()==0) if(execv("/bin/echo", argv_execv)<0) //echo命令,参数argv_execv指向的内容 perror("Err on execv"); if(fork()==0) if(execvp("echo", argv_execvp)<0) //echo命令,参数argv_execvp指向的内容 perror("Err on execvp"); if(fork()==0) if(execve("/usr/bin/env", argv_execve, envp)<0) //env命令 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:子进程执行用户自己编写的程序

先写父进程的程序:

/*parent.c*/ #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)) //路径/home/child,参数... perror("execle failed!/n"); break; default: break; } //等待子进程退出 if(waitpid(pid,NULL,0)<0) perror("waitpid failed!/n"); printf("parent excting!"); return 0; }

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

/*child.c*/ #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!

你可能感兴趣的:(linux,File,null,exe,Path,testing)