【问题标题】:execl is suceeding - however exit(1) is being calledexcel 成功 - 但是 exit(1) 被调用
【发布时间】:2026-01-12 06:50:02
【问题描述】:

我试图更好地理解 exec() - 所以我在 testing.c 中有以下脚本


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

int main(int argc, char ** argv)
{
  if(argc < 2) {
    fprintf(stderr,"Error:: Expecting an Argument!\n");
    exit(-1);
  }
  pid_t pid;
  pid = fork();
  if (pid==0) {
    execlp("./testing","testing",NULL);
    fprintf(stderr, "I want to get to here...\n");
    exit(-1);
  }
  wait(NULL);
  printf("Parent and child done\n");
  return 0;
}

下面的块是我用./testing one执行后的输出:

Error:: Expecting an Argument!
Parent and child done

在阅读exec() 的工作原理时,我希望在我的execlp 调用之后能够fprintf,因为它应该返回-1,我想知道我是否需要设置一个errno 或其他东西更明确地抛出一些东西以便execlp 识别错误?

【问题讨论】:

  • man 3 exec: 返回值 exec() 函数仅在发生错误时返回。返回值为 -1,设置 errno 以指示错误。
  • 是什么让你认为execlp 调用失败了?
  • 关于:Error:: Expecting an Argument! 此消息是因为您没有提供代码所期望的命令行参数
  • 贴出的代码无法编译!它缺少以下#include 语句:#include #include #include #include #include
  • 如果包含命令行参数,则输出为:I want to get to here... Parent and child done

标签: c error-handling exec


【解决方案1】:

如果execlp 函数成功启动给定程序,它返回。当前程序映像被新程序的程序映像替换。所以即使新程序以状态-1退出,它仍然不会回到调用execlp的程序。

如果要获取子进程的退出状态,请将int 的地址传递给wait 并读取:

int main(int argc, char ** argv)
{
  if(argc < 2) {
    fprintf(stderr,"Error:: Expecting an Argument!\n");
    exit(-1);
  }
  pid_t pid;
  pid = fork();
  if (pid == -1 {
      perror("fork failed");
      exit(-1);
  } else if (pid == 0) {
    execlp("./testing","testing",NULL);
    perror("execlp failed");
    exit(-1);
  }
  int status;
  wait(&status);
  printf("child exit status: %d\n", WEXITSTATUS(status));
  printf("Parent and child done\n");
  return 0;
}

【讨论】:

    【解决方案2】:

    输出:

    Error:: Expecting an Argument!
    Parent and child done
    

    来自

    (first line) child process tries to run but no command line parameter.  
    (second line) parent process finishes
    

    【讨论】:

    • 是的,我明白 - 但我在想 fprintf(stderr, "I want to get to here...\n"); 也应该运行,因为子进程正在返回 -1
    • 一个重要的细节。 exec*() 函数不会返回,除非操作失败