How to get the exit status of a child process?

前端 未结 1 1927
北海茫月
北海茫月 2021-01-28 01:06

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

 ibrahim@ibrahim-latech:~$ ./prog2 .
 Current working directory: /         


        
相关标签:
1条回答
  • 2021-01-28 01:31

    Transferring key information from comments into an answer.

    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).

    Modifying your code:

    #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;
    }
    

    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.

    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)
    $
    
    0 讨论(0)
提交回复
热议问题