execve替换进程映像(加载程序):
execve系统调用,意味着代码段、数据段、堆栈段和PCB全部被替换。
在UNIX中采用一种独特的方法,它将进程创建与加载一个新进程映像分离。这样的好处是有更多的余地对两种操作进行管理。当我们创建一个进程之后,通常将子进程替换成新的进程映像,这可以用exec系列的函数来进行。当然,exec系列的函数也可以将当前进程替换掉。
例如:shell进程中,运行ps程序,首先fork一个新进程,再将新进程用ps程序替换。
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...); 后面是可变参数,以NULL结尾.带p会在环境变量路径下搜索程序。
int execle(const char *path, const char *arg,.., char * const envp[]); 不在环境变量下搜索,但是可以带一个环境信息,可以见下面的例2。
int execv(const char *path, char *const argv[ ]); v是将参数以NULL结尾放入一个char* const数组中[指针是const]
int execvp(const char *file, char *const argv[ ]);
例1:
1 #include<unistd.h> 2 #include<sys/types.h> 3 #include<stdlib.h> 4 #include<stdio.h> 5 #include<errno.h> 6 #define ERR_EXIT(m) 7 do 8 { 9 perror(m); 10 exit(EXIT_FAILURE); 11 }while(0) //宏要求一条语句 12 int main() 13 { 14 printf("Entering mian... "); 15 execlp("ps","ps","-x",NULL); //将当前进程替换成ps程序
//char *const args[]={"ps","-x",NULL};
//execvp("ps",args); 16 /* 17 ps -a:显示现行终端机下的所有程序,包括其他用户的程序 18 ps -A:显示所有程序。 19 ps -u: 以用户为主的格式来显示程序状况 20 ps -x:显示所有程序,不以终端机来区分。 21 */ 22 printf("Exiting main... ");//不会输出了 23 return 0; 24 }
例2:
1 //hello程序 2 #include<unistd.h> 3 #include<stdio.h> 4 //hello程序打印程序环境变量 5 extern char** environ;//全局变量,C库中已定义。指针的指针,指向一个指针数组 environ-->[...]数组中每一项指向一个环境信息。例如"TERM=VI00","SHELL=/bin/bash" 6 int main(void) 7 { 8 printf("hello pid=%d ",getpid()); 9 //打印环境变量 10 int i; 11 for(i=0;environ[i]!=NULL;i++) 12 { 13 printf("%s ",environ[i]); 14 } 15 return 0; 16 } 17 18 //execle程序,将进程替换为上面的hello程序。 19 #include<unistd.h> 20 #include<sys/types.h> 21 #include<stdlib.h> 22 #include<stdio.h> 23 #include<errno.h> 24 #define ERR_EXIT(m) 25 do 26 { 27 perror(m); 28 exit(EXIT_FAILURE); 29 }while(0) //宏要求一条语句 30 int main() 31 { 32 printf("Entering mian... "); 33 //execl执行hello,execl就会将当前环境信息传递给hello.而当前进程环境信息从shell继承。所以hello打印的环境信息就是shell传给execl,再传过来的
//printf("pid=%d ",getpid()); 34 //execl("./hello","hello",NULL); //替换前后进程ID不变
//execl("hello","hello",NULL); //替换失败 No such file or dic...
35 char * const envp[]={"AA=11","BB=22",NULL}; 36 execle("./hello","hello",NULL,envp);//不再是从shell继承环境变量信息,而是有自己指定 37 /* 38 Entering mian... 39 hello pid=53447 40 AA=11 41 BB=22 42 */ 43 printf("Exiting main... ");//不输出了 44 return 0; 45 }
例三:
#include<unistd.h> #include<sys/types.h> #include<stdlib.h> #include<stdio.h> #include<errno.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) //宏要求一条语句 int main() { printf("Entering mian... "); char * const args[]={"ls","-l",NULL}; // execlp("ls","ls","-l",NULL); //将当前进程替换成ps程序 execvp("ls",args); printf("Exiting main... ");//不会输出了 return 0; }