【问题标题】:execvp in C not going through arC中的execvp不通过ar
【发布时间】:2018-03-04 08:56:45
【问题描述】:

我正在尝试使用exec 来执行作为参数给出的命令列表。

程序运行时的示例输入为 ./assn2 ls date。

当我这样做时,只执行第一个命令。

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


int main(int argc, char *argv[])
{
  int args = argc-1;

  pid_t childpid = fork();

  // error
  if (childpid < 0)
  {
    perror("fork() error");
    exit(-1);
  }

  // parent process
  if (childpid != 0)
  {
    printf("Parent Process started, now waiting for ID: %d\n", childpid);
    wait(NULL);
    printf("Parent Process resumeed. Child exit code 0. Now terminating\n");
    exit(0);
  }

  // child process
  if (args > 0)
  {
    printf("Child process has begun.  %d argument/s provided\n", args);

    int i;
    for (i = 1; i <= argc; i++)
    {
      execlp(argv[i], argv[i], NULL);
    }
    execvp(argv[1], argv);
  }
  else
  {
    printf("No arguments provided, terminating child\n");
  }

  return 0;
}

【问题讨论】:

  • for(i = 1; i &lt;= argc; i++) - 这超出了数组范围。结束exec*函数不返回,所以显然你不能在同一个进程中顺序执行它们..
  • 如果你要执行两个程序,你需要两个子进程,所以你需要调用fork 两次。我相信您会希望将 fork 调用移入循环中。如果你只有一个子进程(就像你在这里所做的那样),一旦你成功调用了 exec,你就用你执行的新代码覆盖了那个进程,你以后对 exec 的调用将永远不会发生。
  • execlp(argv[i] ,argv[i], NULL); --> execlp(argv[i] ,argv[i], (void*)NULL); 需要转换为NULL 可能是int 0。Ref

标签: c exec


【解决方案1】:

一旦第一个子进程执行(并成功),for 循环将不再继续,因为 execlp 只会用正在执行的命令替换当前进程映像。

您要做的是循环遍历父进程中的命令行参数并为每个命令执行一次。类似的东西可能就是你所追求的:

   for(int i = 1; i < argc; i++) {
       pid_t pid = fork();
       if (pid == 0) {
           execlp(argv[i] ,argv[i], (char*)0);
           perror("exec");
       } else if (pid > 0) {
           wait(NULL);
       } else {
           perror("fork");
           exit(1);
       }
  }

【讨论】:

    【解决方案2】:

    您想通过连续调用execlp()execvp() 来达到什么目的?这些函数并不意味着返回。我认为你应该阅读ref

    exec() 系列函数用新的进程映像替换当前进程映像。 [..] exec() 函数仅在发生错误时返回。

    因此,您无法在同一进程中一个接一个地执行它们。

    阅读fork()

    fork() 通过复制调用进程来创建一个新进程。


    此外,这里:

    for(i = 1; i <= argc; i++)
    

    你超出了界限,因为argv 从 0 开始索引,并在 argc - 1 结束。

    改成:

    for(i = 1; i < argc; i++)
    

    【讨论】:

    • 如果“替换过程映像”的重要性对 OP 来说不是很明显,那么从同一个参考资料中,您再清楚不过了:“exec() 仅功能如果发生错误则返回。”
    猜你喜欢
    • 2013-02-15
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 2012-12-23
    • 1970-01-01
    • 2012-12-05
    相关资源
    最近更新 更多