Catch ECHILD from os.waitpid()
[arvados.git] / crunch_scripts / arvados_ipc.py
1 import os
2 import re
3 import sys
4 import subprocess
5
6 def pipe_setup(pipes, name):
7     pipes[name,'r'], pipes[name,'w'] = os.pipe()
8
9 def pipe_closeallbut(pipes, *keepus):
10     for n,m in pipes.keys():
11         if (n,m) not in keepus:
12             os.close(pipes.pop((n,m), None))
13
14 def named_fork(children, name):
15     children[name] = os.fork()
16     return children[name]
17
18 def waitpid_and_check_children(children):
19     """
20     Given a dict of childname->pid, wait for each child process to
21     finish, and report non-zero exit status on stderr. Return True if
22     all children exited 0.
23     """
24     all_ok = True
25     for (childname, pid) in children.items():
26         # all_ok must be on RHS here -- we need to call waitpid() on
27         # every child, even if all_ok is already False.
28         all_ok = waitpid_and_check_exit(pid, childname) and all_ok
29     return all_ok
30
31 def waitpid_and_check_exit(pid, childname=''):
32     """
33     Wait for a child process to finish. If it exits non-zero, report
34     exit status on stderr (mentioning the given childname) and return
35     False. If it exits zero, return True.
36     """
37     _, childstatus = os.waitpid(pid, 0)
38     exitvalue = childstatus >> 8
39     signal = childstatus & 127
40     dumpedcore = childstatus & 128
41     if childstatus != 0:
42         sys.stderr.write("%s child %d failed: exit %d signal %d core %s\n"
43                          % (childname, pid, exitvalue, signal,
44                             ('y' if dumpedcore else 'n')))
45         return False
46     return True
47