I am trying to wait in python until either
There is a function os.sigwait that seems to fit this purpose, but I cannot get it to return on a forked child process exit by calling os.sigwait({signal.SIGCHLD}) - this ends in a deadlock.
What I tried:
#!/usr/bin/env python3
import signal
import os
import time
if __name__ == '__main__':
pid = None # initial value
try:
pid = os.fork() # method is available only on UNIX platforms
if pid != 0: # parent
# Wait for child exit or SIGINT
# (should also work for signals other than SIGINT)
signal.sigwait({signal.SIGCHLD, signal.SIGINT})
print("Got signal")
# never reaching this statement by child exit
else: # child
time.sleep(3)
finally:
if pid is None: # fork failed
pass
elif pid == 0:
print("\nChild cleaning up")
else:
print("\nParent cleaning up")
Pulling the answer out of comments:
The solution is to call pthread_sigmask(SIG_BLOCK, {SIGCHLD, SIGINT}) before calling sigwait().
The sigwait family of functions are designed to accept pending signals, rather than to deliver as do sigaction and signal. For this to work properly, the desired signals need to be masked (blocked) before they can be reliably accepted. Indeed, in the POSIX specification, calling sigwait on a set of signals without first blocking those signals is undefined