如何在C/C++中使用execvp()函数

时间:2020-02-23 14:29:56  来源:igfitidea点击:

在本文中,我们将介绍如何在C/C++中使用execvp()函数。

在UNIX中,如果要使用我们的C程序运行另一个程序,execvp()函数将非常有用。

说明:此功能仅适用于基于UNIX的操作系统。
在Windows上不起作用

让我们看一下示例,从程序中执行UNIX命令!

execvp()的基本语法

此函数将要运行的UNIX命令的名称作为第一个参数。

该文件位于<unistd.h>头文件中,因此我们必须将其包含在程序中。

#include <unistd.h>

int execvp(const char* command, char* argv[]);

其中我们将"命令"称为" PATH"环境变量一部分的任何二进制可执行文件。
因此,如果要运行自定义程序,请确保将其添加到PATH变量中!

第二个参数(" argv")表示"命令"的参数列表。
这是一个char *字符串数组。

其中argv包含完整的命令及其参数。

例如,以下数组遵循" argv"的格式。

char* argument_list[] = {"ls", "-l", NULL}; //NULL terminated array of char* strings

//Ok! Will execute the command "ls -l"
execvp("ls", argument_list);

该数组必须以" NULL"终止,即," argv"的最后一个元素必须是" NULL"指针。

现在我们的C程序会怎样?

该功能将控制当前过程(C程序)到命令。
因此,C程序立即被实际命令替换。

因此,execvp()之后的任何内容都将不会执行,因为我们的程序已被完全接管!

但是,如果命令由于某种原因而失败,execvp()将返回-1。

因此,每当使用execvp()时,如果要维护C程序,通常都使用fork()首先产生一个新进程,然后在该新进程上使用execvp()

这称为" fork-exec"模型,是使用C运行多个进程的标准实践。

现在来看一些示例,以更好地理解此功能。
我们还将使用fork()execvp(),以便我们仍然可以使用C程序!

在C/C++中使用execvp()–一些示例

如果您想看看在尝试使用execvp()而不使用fork()产生新进程的情况下到底发生了什么。
下面的程序显示了这一点。

我们将从C程序中执行" ls -l"。

注意,由于其他进程已经控制了,execvp()之后的printf()语句没有执行!

#include <stdio.h>
#include <unistd.h>

int main() {
  char* command = "ls";
  char* argument_list[] = {"ls", "-l", NULL};

  printf("Before calling execvp()\n");

  //Calling the execvp() system call
  int status_code = execvp(command, argument_list);

  if (status_code == -1) {
      printf("Process did not terminate correctly\n");
      exit(1);
  }

  printf("This line will not be printed if execvp() runs correctly\n");

  return 0;
}

输出

Before calling execvp()
total 3
-rwxrwxrwx 1 user user 22088 Jan 30 16:37 a.out
-rwxrwxrwx 1 user user 16760 Jan 30 16:37 sample
-rw-rw-rw- 1 user user  1020 Jan 30 16:37 sample.c

如您所见,execvp()之后的部分根本不执行,因为" ls -l"控制了我们的过程!

让我们重写相同的示例,但使用fork()execvp()系统调用包含在另一个进程中。

让我们看看现在会发生什么。

#include <stdio.h>
#include <unistd.h>

int main() {
  char* command = "ls";
  char* argument_list[] = {"ls", "-l", NULL};

  printf("Before calling execvp()\n");

  printf("Creating another process using fork()...\n");

  if (fork() == 0) {
      //Newly spawned child Process. This will be taken over by "ls -l"
      int status_code = execvp(command, argument_list);

      printf("ls -l has taken control of this child process. This won't execute unless it terminates abnormally!\n");

      if (status_code == -1) {
          printf("Terminated Incorrectly\n");
          return 1;
      }
  }
  else {
      //Old Parent process. The C program will come here
      printf("This line will be printed\n");
  }

  return 0;
}

输出

Before calling execvp()
Creating another process using fork()...
This line will be printed
user@shell:$total 3
-rwxrwxrwx 1 user user 22088 Jan 30 16:37 a.out
-rwxrwxrwx 1 user user 16760 Jan 30 16:37 sample
-rw-rw-rw- 1 user user  1020 Jan 30 16:37 sample.c

如果您使用的是Shell,则输出可能看起来很奇怪,但这是因为多个进程并行运行!确实输出了两个输出,因此我们能够解决问题。