【问题标题】:Proper way to use execlp and execvp while reporting exit status in C在 C 中报告退出状态时使用 execlp 和 execvp 的正确方法
【发布时间】:2020-06-27 05:53:48
【问题描述】:

我是一名学习 C 以及如何使用 fork() 创建进程的学生 你能解释一下这两个代码有什么区别吗,因为我都试过了,但它们都没有按预期工作。

child = fork();
child1 = fork();
if (child == 0 && child1 == 0){//Parent}
else if (child > 0 && child1 == 0){//first child}
else if (child == 0 && child1 > 0){//second child}
else {third child}

这是创建孩子的正确方法还是下面的方法?

child = fork();
if (child == 0)
{
    child1 = fork();
    if (child1 == 0)
    {// grandchild
    }
    else
    {//child
    }
}
else 
{//parent
}

这些是我写的让我感到困惑的例子。 这是我遇到问题的代码

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

int main(int argc, char ** argv)
{
    pid_t child;
    pid_t child1;
    // at least, there should be 3 arguments
    // 2 for the first command, and the rest for the second command
    //printf("%d\n", argc);
    if (argc < 4) {
        fprintf(stderr, "Usage: %s cmd1 cmd1_arg cmd2 [cmd2_args ..]\n", argv[0]);
        return 1;
    }
    child = fork();
    //pid_t child1;
    // TODO
    if (child < 0)
    {
        perror("fork()");
        exit(EXIT_FAILURE);
    }
    if (child == 0)//child1
    {
        //printf("exited=%d exitstatus=%d\n", WIFEXITED(exitStatus), WEXITSTATUS(exitStatus));
        child1 = fork();

        if (child1 == 0)//grandchild
        {
            execlp(argv[1],argv[1],argv[2],NULL); 
            perror("execlp()");
            exit(EXIT_FAILURE);
        }

        else //first child
        {
            int status1;
            waitpid(child1, &status1, 0);
            printf("exited=%d exitstatus=%d\n", WIFEXITED(status1), WEXITSTATUS(status1));
            execvp(argv[3], (argv + 3));
            perror("execlp()");
            exit(EXIT_FAILURE);
        }
    }
    else//parent
    {
        int status;
        waitpid(child, &status, 0);
        printf("exited=%d exitstatus=%d\n", WIFEXITED(status), WEXITSTATUS(status));
    }
    return 0;
}

我能够让代码按预期工作,但我对如何使用 WIFEXITED 和 WEXITSTATUS 感到困惑。 我运行此代码时的代码输出是

execlp(): No such file or directory
Makefile
exited=1 exitstatus=0

正确的输出是:

execlp(): No such file or directory
Makefile
exited=1 exitstatus=1
exited=1 exitstatus=0

本测试用例中使用的参数

cal -3 ls Makefile

为什么我错过了第二个出口打印?

【问题讨论】:

  • 你有评论if (child == 0 &amp;&amp; child1 == 0){//Parent}——这是错误的;父级的 PID 值均非零。 PID 值都为零的进程是孙进程。
  • @JonathanLeffler 对不起,这是一个错字,我明白你在说什么,但我不确定解决我手头问题的最佳方法是什么。我想运行两个 exe 命令并打印退出状态。你能告诉我我做错了什么吗?
  • 您的示例命令行令人费解。你说cal -3 ls Makefile,你的使用信息说Usage: %s cmd1 cmd1_arg cmd2 [cmd2_args ..]。假设你的程序叫做cal(请注意,至少在许多系统上,有一个标准程序叫做cal——试试cal 9 1752),那么你的cmd1-3,它的参数是@ 987654335@,而cmd2就是Makefile,不是很常规。我希望像./cal ls -l cat Makefile 这样的调用。假设您希望 cmd1 cmd1arg 在运行 cmd2 [cmd2arg ...] 之前运行并完成,我们是否正确?

标签: c fork child-process execvp waitpid


【解决方案1】:

你的前两个代码 sn-ps 根本不一样

第一种情况,

第二种情况,

【讨论】:

  • 我现在明白了这段代码的含义,并且我能够解决我的大部分问题。我仍然面临的唯一问题是如何控制先运行哪个 exe 命令?如果我出于某种原因翻转它们似乎不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-08
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
  • 2018-08-30
相关资源
最近更新 更多