exec函数可以把当前进程替换为一个新进程,新进程由path或file指定,可以使用exec函数将程序的执行从一个程序切换到另一个程序,新的程序启动后,原来的程序就不再运行。
#include <unistd.h>
char **environ;
int execl(const char *path, const char *arg0, ..., (char *)0);
int execlp(const char *file, const char *arg0, ..., (char *)0);
int execle(const char *path, const char *arg0, ..., (char *)0, 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[]);
这些函数分为两大类,execl,execlp和execle的参数个数是可变的,参数以一个空指针结束。
execv和execvp的第二个参数是字符串数组,两者在新程序启动时都会把在argv数组中给定的参数传递给main函数。
上面的5个函数通常都是由execve函数实现。
以字母p结尾的函数通过搜索PATH环境变量来查找新程序的可执行文件的路径,如果可执行文件不在PATH定义的路径中,则需要把包括目录在内的使用绝对路径的文件名作为参数传递给函数。
函数execle和execve可以通过参数envp传递字符串数组作为新程序的环境变量。
下面是一个示例程序:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Running ls with execl/n");
execl("/bin/ls", "ls", "-l", NULL);
printf("done./n");
exit(0);
}
保存为pexec.c
编译:gcc -o pexec pexec.c
然后运行:./pexec
在笔者电脑上得到如下结果:
Running ps with execl
总计 36
-rwxr-xr-x 1 deng deng 8371 2010-08-13 21:06 pexec
-rw-r--r-- 1 deng deng 177 2010-08-13 20:11 pexec.c
-rw-r--r-- 1 deng deng 170 2010-08-13 07:54 pexec.c~
-rwxr-xr-x 1 deng deng 8374 2010-08-13 07:35 system1
-rw-r--r-- 1 deng deng 143 2010-08-13 07:35 system1.c
以上是正常的ls命令的输出结果,但字符串done却根本没出现,说明当前程序已经被execl函数替换掉了。
另一个示例:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Running ps with execlp/n");
execlp("ps","ps","ax",NULL);
printf("done./n");
exit(0);
}
该示例程序用于打印当前的进程,保存为pexecp.c
编译:gcc -o pexecp pexecp.c
运行:./pexecp
笔者电脑运行的结果如下:
Running ps with execlp
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 /sbin/init
2 ? S< 0:00 [kthreadd]
3 ? S< 0:00 [migration/0]
4 ? S< 0:00 [ksoftirqd/0]
5 ? S< 0:00 [watchdog/0]
6 ? S< 0:00 [migration/1]
7 ? S< 0:00 [ksoftirqd/1]
8 ? S< 0:00 [watchdog/1]
9 ? S< 0:00 [events/0]
10 ? S< 0:00 [events/1]
11 ? S< 0:00 [cpuset]
12 ? S< 0:00 [khelper]
………………中间还有很多,在此省略
4698 ? Sl 2:48 /usr/lib/firefox-3.6.8/plugin-container /usr/lib/flas
4787 ? S 0:01 gedit /home/deng/workspace/linux_test/chapter11/pexec
4975 ? S 0:00 /usr/lib/gvfs/gvfsd-computer --spawner :1.9 /org/gtk/
4997 ? Rl 0:00 gnome-terminal
4998 ? S 0:00 gnome-pty-helper
4999 pts/0 Ss 0:00 bash
5106 pts/0 R+ 0:00 ps ax
在这里可以看到我们在程序里面用execlp()函数启动的进程ps ax,它相当于shell下的命令ps ax,效果相同
但这里我们依然没有看到最后一句done没有被打印出来
一般情况下,exec函数是不会返回的,除非发生了错误。出现错误时,exec函数会返回-1,并且会设置错误变量errno.