| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- ###############################################################################
- # Launch a subprocess using forkexec and make sure only the needed fd are
- # shared in the two process.
- #
- # author: Thomas Moreau and Olivier Grisel
- #
- import os
- import sys
- if sys.platform == "darwin" and sys.version_info < (3, 3):
- FileNotFoundError = OSError
- def close_fds(keep_fds): # pragma: no cover
- """Close all the file descriptors except those in keep_fds."""
- # Make sure to keep stdout and stderr open for logging purpose
- keep_fds = set(keep_fds).union([1, 2])
- # We try to retrieve all the open fds
- try:
- open_fds = set(int(fd) for fd in os.listdir('/proc/self/fd'))
- except FileNotFoundError:
- import resource
- max_nfds = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
- open_fds = set(fd for fd in range(3, max_nfds))
- open_fds.add(0)
- for i in open_fds - keep_fds:
- try:
- os.close(i)
- except OSError:
- pass
- def fork_exec(cmd, keep_fds, env=None):
- # copy the environment variables to set in the child process
- env = {} if env is None else env
- child_env = os.environ.copy()
- child_env.update(env)
- pid = os.fork()
- if pid == 0: # pragma: no cover
- close_fds(keep_fds)
- os.execve(sys.executable, cmd, child_env)
- else:
- return pid
|