Search code examples
clinuxasynchronousprocessembedded-linux

How to asynchronously wait for process termination and find out the exit code?


The waiting works fine with pidfd_open and poll.

The problem I’m facing, after the process quits, apparently the poll() API removes the information about the now dead process, so the waitid with P_PIDFD argument fails at once saying code 22 “Invalid argument”

I don’t think I can afford launching a thread for every child process to sleep on the blocking waitpid, I have multiple processes, and another handles which aren’t processes I need to poll efficiently.

Any workarounds?

If it matters, I only need to support Linux 5.13.12 and newer running on ARM64 and ARMv7 CPUs.

The approximate sequence of kernel calls is following:

  1. fork
  2. In the child: setresuid, setresgid, execvpe
  3. In the new child: printf, sleep, _exit
  4. Meanwhile in the parent: pidfd_open, poll, once completed waitid with P_PIDFD first argument.

Expected result: waitid should give me the exit code of the child.

Actual result: it does nothing and sets errno to EINVAL


Solution

  • There is one crucial bit. From man waitid:

    Applications shall specify at least one of the flags WEXITED, WSTOPPED, or WCONTINUED to be OR'ed in with the options argument.

    I was passing was WNOHANG

    And you want to pass WNOHAND | WEXITED ;)