exec函数族的使用研究
exec函数族的使用研究
?首先我们来简单了解一下exec函数的作用是干嘛的,它是在程序中启用一个新的程序,这个程序会替代原有的进程,但是它的进程PID是不变的,还是启动它的这个进程的PID,就相当于交接一样,一个进程把它所举的牌子给了另外一个进程,另外一个进程可以继续举着这个牌子跑。
?Ok,下面我们来详细看一下这个函数的使用。错了,我不应该说这个函数的使用,而是应该说这一系列函数的使用。为什么这样说呢?呵呵,兄弟们,出来给大家见一下:
int?? execl(? char *pathname,char *arg0,char *arg1,...,char *argn,NULL)
int?? execle( char *pathname,char *arg0,char *arg1,...,char *argn,NULL,char *envp[])
int?? execlp( char *pathname,char *arg0,char *arg1,...,NULL)
int?? execlpe(char *pathname,char *arg0,char *arg1,...,NULL,char *envp[])
int?? execv(? char *pathname,char *argv[])
int?? execve( char *pathname,char *argv[],char *envp[])
int?? execvp( char *pathname,char *argv[])
int?? execvpe(char *pathname,char *argv[],char *envp[])
?啦啦的,这可是多胞胎啊,各自有什么用呢,其实很简单,他们的总体意义是一样的:装入并运行程序pathname,并将参数arg0(arg1,arg2,argv[],envp[])传递给子程序,出错返回-1。
那么这个多胞胎是怎么辨认呢,很简单,看胎记啊,这个胎记就是跟在exec后面的东东,总共有4种,l、e、p、v。凡是有后缀? p的,函数可以利用DOS的PATH变量查找子程序文件。有后缀v时,希望接收到一个以NULL结尾的字符串数组的指针。有后缀 l时,希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志。e时,函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境。
?好了,下面我们来逐个认识他们。
1、?execl:
首先,man execl。我们得到以下信息:
头文件:?????? #include <unistd.h>
函数原型:? int execl(const char *path, const char *arg, ...);
函数说明:execl()用来执行参数path字符串所代表的文件路径,接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
函数返回:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
下面我们来做个简单的测试程序:
代码一:
#include <stdio.h>
#include <unistd.h>
main(){
??execl("/bin/ls","ls","-al","/home/xdyang",NULL);?
?}
很简单的代码。就是执行/bin/ls –al /home/xdyang
执行的结果如下(这个我里面的东西比较乱,我就不全部显示了,呵呵):
[xdyang@SEP4020 learning]$ gcc -o exec exec.c
[xdyang@SEP4020 learning]$ ./exec
总计 1167140
drwx------ 55 xdyang xdyang????? 4096 02-12 19:50 .
drwxr-xr-x 27 root?? root??????? 4096 12-13 18:22 ..
drwxr-xr-x 10 xdyang xdyang????? 4096 2004-07-28 3.4.1
-rwxr--r--? 1 xdyang xdyang? 46235538 2009-04-25 3.4.1-fp-minigui-lts.tar.bz2
drwxrwxr-x? 5 xdyang xdyang????? 4096 12-13 16:10 611_system_r1
-rwxr-xr-x? 1 xdyang xdyang????? 1457 12-13 16:08 611_system_r1.sh
2、?execlp
其他不多说,跟上面差不多,就说两个重要的说明:
函数原型:??? int execlp(const char * file,const char * arg,……);
函数说明:??? execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
测试程序如下:
代码二:
main(){
?execlp("ls","ls","-al","/home/xdyang",NULL);?
}
这个地方,我们使用execlp,将会依PATH变量中的/bin找到/bin/ls,假如我们使用execl,它就不会去找PATH了,将不会有啥显示了。
执行结果:
[xdyang@SEP4020 learning]$ ./exec
总计 1167144
drwx------ 55 xdyang xdyang????? 4096 02-12 20:13 .
drwxr-xr-x 27 root?? root??????? 4096 12-13 18:22 ..
drwxr-xr-x 10 xdyang xdyang????? 4096 2004-07-28 3.4.1
3、?execv
函数原型:?? int execv (const char * path, char * const argv[ ]);
函数说明:?? execv()用来执行参数path字符串所代表的文件路径,与execl()不同的地方在于execve()只需两个参数,第二个参数利用数组指针来传递给执行文件。
测试程序三:
main(){
?char *argv[]={"ls","-al","/home/xdyang",NULL};
?execv("/bin/ls",argv);
}
其实这个说起来也没什么,结果是一样的,不再赋值出来了。
4、?execve
函数原型:?? int execve(const char * filename,char * const argv[ ],char * const envp[ ]);
函数说明:?? execve()用来执行参数filename字符串所代表的文件路径,第二个参数系利用数组指针来传递给执行文件,argv要传递给程序的完整参数列表,包括argv[0],它一般是执行程序的名字;最后一个参数则为传递给执行文件的新环境变量数组。
测试程序四:
main(){
?char *argv[]={"/bin/ls","-al",NULL};?
?execve("/bin/ls",argv,NULL);
}
其实写法差不多吧,我只是换了个路径,哈哈~~
执行结果如下:
[xdyang@SEP4020 learning]$ gcc -o exec exec.c
[xdyang@SEP4020 learning]$ ./exec
total 420
drwxrwxr-x? 2 xdyang xdyang? 4096 Feb 12 20:32 .
drwx------ 55 xdyang xdyang? 4096 Feb 12 20:32 ..
-rw-------? 1 xdyang xdyang 12288 Jan? 5 10:58 .exit.c.swp
换了个路径,呵呵,还是很多,哎……
至此,我们差不多就把这个函数族的用法讲解差不多了,就不多说了,有问题再加吧。