如何获得子进程的退出状态? [英] How to get the exit status of a child process?

查看:216
本文介绍了如何获得子进程的退出状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两个示例输出(由我的教授提供)是(这些输入在Linux终端中):

Two example outputs (provided by my professor) are (these are inputted in the Linux terminal):

 ibrahim@ibrahim-latech:~$ ./prog2 .
 Current working directory: /home/ibrahim
 Executing ls . --all -l --human-readable
 total 24M
 drwxr-xr-x 74 ibrahim ibrahim 20K Oct 26 16:08 .
 drwxr-xr-x 6 root root 4.0K Apr 10 2014 ..
 -rw-r--r-- 1 ibrahim ibrahim 4.1K Sep 13 12:09 .bashrc
 drwxr-xr-x 7 ibrahim ibrahim 4.0K Oct 11 14:51 Desktop/
 ...snip...
 Exit status: 0

因此,如果该代码有效,则退出状态为0,但此示例为:

so the Exit status is 0 if the code works but this example:

 ibrahim@ibrahim-latech:~$ ./prog2 /root
 Current working directory: /home/ibrahim
 Executing ls /root --all -l --human-readable
 Can't chdir to /root
 Exit status: 1 

退出状态为1,因为它为false.

The exit status is 1 because it is false.

这是我的代码:

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

int main(int argc, char *argv[]){
    pid_t pid;
    pid = fork();
    char cwd[255];
    if(pid == 0){
        printf("Current working directory: %s\n",getcwd(cwd, sizeof(cwd)));
        printf("Executing ls %s --all -l --human-readable\n",argv[1]);
        if(chdir(argv[1])!=0){
            printf("this is not a valid directory");
        }
        else{
            execl("/bin/ls","ls","--all","-l","--human-readable", NULL);
        }
    }
    else{
        wait(NULL):
        printf("Exit status:");// not sure how to put the 1 or 0 in this
    }
}

必须从父进程输出退出状态.我不知道如何使退出状态正常工作.

The exit status must be outputted from the parent process. I can't figure out how to get the exit status to work.

推荐答案

将关键信息从评论转换为答案.

wait() 函数会告诉您PID和退出状态-您只需要捕获它们,而不必忽略它们.您需要使用WIFEXITEDWEXITSTATUS(如果WIFEXITED报告为false,则还有其他宏可用于信号和核心转储等).

The wait() function tells you the PID and the exit status — you just have to capture them, not ignore them. You'll need to use WIFEXITED and WEXITSTATUS (and if WIFEXITED reports false, there are other macros to use for signals and core dumps, etc).

修改代码:

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

#ifndef LS_PATH
#define LS_PATH "/bin/ls"
#endif

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s directory\n", argv[0]);
        return 1;
    }
    pid_t pid = fork();
    if (pid == 0)
    {
        char cwd[255];
        printf("Current working directory: %s\n", getcwd(cwd, sizeof(cwd)));
        printf("Executing 'ls -a -l' in %s\n", argv[1]);
        if (chdir(argv[1]) != 0)
        {
            fprintf(stderr, "%s: %s is not a valid directory\n", argv[0], argv[1]);
            return 1;
        }
        //execl(LS_PATH, "ls", "--all", "-l", "--human-readable", (char*) NULL);
        execl(LS_PATH, "ls", "-a", "-l", (char*) NULL);
        fprintf(stderr, "Failed to execute %s\n", LS_PATH);
        return 1;
    }
    else
    {
        int status;
        int corpse = wait(&status);
        if (corpse < 0)
            printf("Failed to wait for process %d (errno = %d)\n", (int)pid, errno);
        else if (corpse != pid)
            printf("Got corpse of process %d (status 0x%.4X) when expecting PID %d\n",
                   corpse, status, (int)pid);
        else if (WIFEXITED(status))
            printf("Process %d exited with normal status 0x%.4X (status %d = 0x%.2X)\n",
                   corpse, status, WEXITSTATUS(status), WEXITSTATUS(status));
        else if (WIFSIGNALED(status))
            printf("Process %d exited because of a signal 0x%.4X (signal %d = 0x%.2X)\n",
                   corpse, status, WTERMSIG(status), WTERMSIG(status));
        else
            printf("Process %d exited with status 0x%.4X which is %s\n",
                   corpse, status, "neither a normal exit nor the result of a signal");
    }
    return 0;
}

我在不使用GNU ls的Mac上工作,因此我已将代码的编译时可配置为ls的位置进行了配置,并且它仅使用可移植的选项(-a-l和而不是双破折号选项).我更改了消息传递并检测到更多错误.像您的代码一样,这假定fork()不会失败-它也应该在那里检查错误.

I work on a Mac which doesn't use GNU ls so I've made the code compile-time configurable for the location of ls and it only uses portable options (-a and -l and not the double-dash options). I've changed the messaging and detected some more errors. Like your code, this assumes fork() does not fail — it should check for an error there too.

样本输出(缩写)—来自从es61.c编译的程序es61:

Sample output (abbreviated) — from program es61 compiled from es61.c:

$ es61 /orthography
Current working directory: /Users/jonathanleffler/soq
Executing 'ls -a -l' in /orthography
es61: /orthography is not a valid directory
Process 64463 exited with normal status 0x0100 (status 1 = 0x01)
$ es61 $PWD
Current working directory: /Users/jonathanleffler/soq
Executing 'ls -a -l' in /Users/jonathanleffler/soq
total 1016
drwxr-xr-x  100 jonathanleffler  staff   3200 Oct 31 15:53 .
drwxr-xr-x+  69 jonathanleffler  staff   2208 Oct 31 15:53 ..
…
-rwxr-xr-x    1 jonathanleffler  staff   9028 Oct 31 15:53 es61
-rw-r--r--    1 jonathanleffler  staff   1806 Oct 31 15:53 es61.c
drwxr-xr-x    3 jonathanleffler  staff     96 Oct 31 15:43 es61.dSYM
drwxr-xr-x    9 jonathanleffler  staff    288 Nov  5  2018 etc
…
-rw-r--r--    1 jonathanleffler  staff    390 Nov 16  2017 makefile
…
Process 64557 exited with normal status 0x0000 (status 0 = 0x00)
$

这篇关于如何获得子进程的退出状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆