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:
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?
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
.