linuxwaitpid

Linux C program: waitpid() with options=WEXITED, why fail with EINVAL?


I have a small program waitpidx.cpp:

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

int main(int argc, char* argv[])
{
    pid_t child_pid = fork();
    if (child_pid != 0)
    {
        printf("Parent process: getpid()=%d\n", (int)getpid());

        int wstatus = 0;
        int waitflags = WEXITED; // 0 is OK, but WEXITED not OK.
        pid_t wpid = waitpid(child_pid, &wstatus, waitflags);
        if (wpid == -1)
        {
            printf("waitpid() fail. errno=%d, %s\n", errno, strerror(errno));
            exit(4);
        }
        assert(wpid == child_pid);
        printf("Parent process waitpid(,,%d) success.\n", waitflags);
        exit(0);
    }

    // Child process

    printf("Child  process: getpid()=%d\n", (int)getpid());
    sleep(1);
}

Running it on Ubuntu Linux 20.04 and 22.04, waitpid() fails with EINVAL(22).

enter image description here

In order for waitpid() to succeed, I need to set waitflags=0.

Why is it so? The man waitpid says:

WEXITED Wait for children that have terminated.

Then I think waitflags=0 and waitflags=WEXITED should have the same meaning.

What's wrong with using WEXITED, and what is its correct use case?


Solution

  • This is an easy mistake to make since a single man page covers all three of wait(), waitpid(), and waitid() -- but WEXITED is only valid in the newer syscall waitid, not in waitpid.