1. 系统调用exec 系列:
它可以用于新程序的运行。exec 系列中的系统调用都完成相同的功能,它们把一个新程序装入调用进程的内存空间,来改变调用进程的执行代码,从而形成新进程。
如果exec 调用成功,调用进程将被覆盖,然后从新程序的入口开始执行。但是它的进程标识符与调用进程相同。
2. exec 系列调用在Linux 系统库中unistd.h 中的函数声明:
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[]);
3.execl():
第一个参数path 给出了被执行的程序所在的文件名,它必须是一个有效的路径名,文件本身也必须含有一个真正的可执行程序。
第二个以及用省略号表示的其它参数一起组成了该程序执行时的参数表;被调用的程序可以访问这个参数表,它们相当于shell 下的命令行参数。
由于参数的个数是任意的,所以必须用一个null 指针来标记参数表的结尾。
4.例程execl():
#include <stdio.h>
#include <unistd.h>
main()
{
printf(“Executing ls\n”);
execl(“/bin/ls”,”ls”,”-l”,NULL);
/* 如果execl 返回,说明调用失败 */
perror(“execl failed to run ls”);
exit(1);
}
只要execl()和其它exec 调用成功,就肯定清除了调用程序而代之以新的程序。
5.execv()只有两个参数:
char *argv []
第一个参数指向被执行的程序文件的路径名,
第二个参数argv 是一个字符型指针的数组,如下所示:
这个数组中的第一个元素指向被执行程序的文件名(不含路径),剩下的元素指向程序
所用的参数。因为该参数表的长度是不确定的,所以要用null 指针作结尾。
6. 下面给出一个用execv()运行ls 命令的例子:
#include <stdio.h>
#include <unistd.h>
main()
{
char* av[]={"ls","-l",NULL};
execv("/bin/ls",av);
perror("execv failed");
exit(1);
}
7.以在shell 中用下述命令序列来设置环境变量PATH:
$PATH=/bin;/usr/bin;/sbin
$export PATH
execlp()和execvp()的第一个参数指向的是一个简单的文件名,而不是一个路径名。
它们通过检索shell 环境变量PATH指出的目录,来得到该文件名的路径前缀部分。 这就使execlp()和execvp()首先在目录/bin,然后在目录/usr/bin,最后在目录/sbin 中搜索程序文件。
另外,execlp 和execvp 还可以用于运行shell 程序,而不只是普通的程序。