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).
In order for waitpid() to succeed, I need to set waitflags=0.
Why is it so? The man waitpid says:
WEXITEDWait 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?

This is an easy mistake to make since a single man page covers all three of
wait(),waitpid(), andwaitid()-- butWEXITEDis only valid in the newer syscallwaitid, not inwaitpid.