Linux 还提供了系统调用 exec 系列,它可以用于新程序的运行。exec 系列中的系统调用都完成相同的功能,它们把一个新程序装入调用进程的内存空间,来改变调用进程的执行代码,从而形成新进程。如果 exec 调用成功,调用进程将被覆盖,然后从新程序的入口开始执行。这样就产生了一个新的进程,但是它的进程标识符与调用进程相同。这就是说,exec 没有建立一个与调用进程并发的新进程,而是用新进程取代了原来的进程。所以, exec 调用成功后,对没有任何数据返回,这与 fork()不同。下面给出了 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[]);
程序:
#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);
}
gcc -o execltest execltest.c
execltest.c: In function ‘main’:
execltest.c:11:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
$ ./execltest
Executing ls
total 28
-rwxrwxr-x 1 zhshyii zhshyii 7274 2012-06-19 06:32 execltest
-rw-rw-r-- 1 zhshyii zhshyii 202 2012-06-19 06:32 execltest.c
-rw-rw-r-- 1 zhshyii zhshyii 210 2012-06-19 06:32 execltest.c~
-rwxrwxr-x 1 zhshyii zhshyii 7236 2012-06-19 06:15 forktest
-rw-rw-r-- 1 zhshyii zhshyii 284 2012-06-19 06:14 forktest.c
请注意,程序在 execl()调用后紧跟着一个对库例行程序 perror()的无条件调用。这是因为,如果调用程序还存在,并且 execl()调用返回,那么肯定是 execl()调用出错了。这时,
execl()和其它 exec 调用总是返回-1。这也就是说,只要 execl()和其它 exec 调用成功,就肯定清除了调用程序而代之以新的程序。