lienhua34
2014-10-07

在文档“进程控制三部曲”中,我们提到 fork 函数创建子进程之后,通常都会调用 exec 函数来执行一个新程序。调用 exec 函数之后,该进程就将执行的程序替换为新的程序,而新的程序则从 main 函数开始执行。

UNIX 提供了 6 种不同的 exec 函数供我们使用。它们的原型如下所示,

#include <unistd.h>
int execl(const char *pathname, const char *arg0, ... /* (char *)0 */);
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, ... /* (char *)0, char *const envp[] */);
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg0, ... /* (char *)0 */);
int execvp(cosnt char *filename, char *const argv[]);
6个函数的返回值:若出错则返回-1,若成功则没有返回值

可能很多人会觉得这六个函数太难记了。但是,我们仔细观察会发现,这六个函数的命名是有一些规律的。

• 含有 l 和 v 的 exec 函数的参数表传递方式是不同的。

• 含有 e 结尾的 exec 函数会传递一个环境变量列表。

• 含有 p 结尾的 exec 函数取的是新程序的文件名作为参数,而其他exec 函数取的是新程序的路径。

exec 函数给新程序传递参数表方式的不同可以通过 exec 函数名称来体现。含有 l(l 表示 list)的 exec 函数(execl、execle 和 execlp)将新程序的参数表以列表的方式传递,要求每个命令行参数作为一个单独的参数,最后空指针结尾。含有 v(v 表示 vector)的 exec 函数(execv、execve 和execvp)将新程序的参数表构造成一个数组进行传递。下面我们来看一个例子,我们有一个程序 echoargs.c,其输出所有的命令行参数。

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
  int i;
  for (i = 1; i < argc; i++) {
    printf("arg%d: %s\n", i, argv[i]);
  }
  exit(0);
}

编译该程序,生成 echoargs 文件,

lienhua34:demo$ gcc -o echoargs echoargs.c

然后在我们的 execdemo.c 中分别以两种不同参数表传递方式来调用execl 和 execv 函数,

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>

char echoargsPath[] = "/home/lienhua34/program/c/apue/ch08/demo/echoargs";
char *myargs[] = {"echoargs", "This", "is", "a", "demo" };

int
main(void)
{
  pid_t pid;

  if ((pid = fork()) < 0) {
    printf("fork error: %s\n", strerror(errno));
    exit(-1);
  } else if (pid == 0) {
    printf("Transmits arguments by vector\n");
    if (execv(echoargsPath, myargs) < 0) {
      printf("execv error: %s\n", strerror(errno));
      exit(-1);
    }
  }
  wait(NULL);

  if ((pid = fork()) < 0) {
    printf("fork error: %s\n", strerror(errno));
    exit(-1);
  } else if (pid == 0) {
    printf("Transmits arguments by list\n");
    if (execl(echoargsPath, myargs[0], myargs[1],
              myargs[2], myargs[3], "another", myargs[4], (char *)0) < 0) {
      printf("execv error: %s\n", strerror(errno));
      exit(-1);
    }
  }
  wait(NULL);
  
  exit(0);
}
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-29
  • 2021-10-21
  • 2021-08-03
  • 2021-09-02
  • 2021-08-30
猜你喜欢
  • 2021-07-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-14
相关资源
相似解决方案