HEADSUP: waitpid(2), pdwait(2), and pdopenpid(2) changes

Konstantin Belousov <[email protected]> Sat, 1 Aug 2026 15:19:48 +0300
Newsgroups gmane.os.freebsd.architechture
Message-ID <[email protected]>
I just pushed a series of commits that modify how waitpid(2) behaves
in presence of the process descriptors for the waited process.  The
changes are breaking, but I believe that the current behavior is
at least useless, and practically broken.

Right now, waitpid(2) and pdwait(2) collide badly: the first syscall
issued reaps the child and makes the exit status unavailable.  For
instance, the possible scenario is that program forks a child, then
waits for its status which would be never delivered because some other
process did pdopenpid() and pdwait()-ed on the child already.

There is also a racy and strange interaction in the different direction,
where waitpid(2) is (sometimes) allowed on the child created with
pdfork(2).

Overall, I think that it is very hard to reliably use the combination
of waitpid() (or any other syscalls from the wait by pid family) and
pdopenpid()/pdwait() together.

Changes committed aim to make this interaction sane.  The summary of
the new behavior is the following:

- if the child was forked, the parent is guaranteed that waitpid()
  returns the exit status after the child exit

- If child was pdforked, waitpid() behavior is managed by the new pdfork
  flag PD_NOWAITPID: if flag is specified, the waitpid() would not see
  the child, otherwise (the current behavior) waitpid() is guaranteed
  to succeed and actually needed to reap

- if there are procdescs on the child (does not matter, was the child
  forked or pdforked), pdwait() returns the exit status each time it is
  called after the process exit.  The zombie is reaped on the last procdesc
  close.

Several tests required adjustments because they dutifully encoded the
present behavior.

The patch series was reviewed by markj@ and tested by pho@.