(root)/
Python-3.11.7/
Lib/
multiprocessing/
popen_fork.py
       1  import os
       2  import signal
       3  
       4  from . import util
       5  
       6  __all__ = ['Popen']
       7  
       8  #
       9  # Start child process using fork
      10  #
      11  
      12  class ESC[4;38;5;81mPopen(ESC[4;38;5;149mobject):
      13      method = 'fork'
      14  
      15      def __init__(self, process_obj):
      16          util._flush_std_streams()
      17          self.returncode = None
      18          self.finalizer = None
      19          self._launch(process_obj)
      20  
      21      def duplicate_for_child(self, fd):
      22          return fd
      23  
      24      def poll(self, flag=os.WNOHANG):
      25          if self.returncode is None:
      26              try:
      27                  pid, sts = os.waitpid(self.pid, flag)
      28              except OSError:
      29                  # Child process not yet created. See #1731717
      30                  # e.errno == errno.ECHILD == 10
      31                  return None
      32              if pid == self.pid:
      33                  self.returncode = os.waitstatus_to_exitcode(sts)
      34          return self.returncode
      35  
      36      def wait(self, timeout=None):
      37          if self.returncode is None:
      38              if timeout is not None:
      39                  from multiprocessing.connection import wait
      40                  if not wait([self.sentinel], timeout):
      41                      return None
      42              # This shouldn't block if wait() returned successfully.
      43              return self.poll(os.WNOHANG if timeout == 0.0 else 0)
      44          return self.returncode
      45  
      46      def _send_signal(self, sig):
      47          if self.returncode is None:
      48              try:
      49                  os.kill(self.pid, sig)
      50              except ProcessLookupError:
      51                  pass
      52              except OSError:
      53                  if self.wait(timeout=0.1) is None:
      54                      raise
      55  
      56      def terminate(self):
      57          self._send_signal(signal.SIGTERM)
      58  
      59      def kill(self):
      60          self._send_signal(signal.SIGKILL)
      61  
      62      def _launch(self, process_obj):
      63          code = 1
      64          parent_r, child_w = os.pipe()
      65          child_r, parent_w = os.pipe()
      66          self.pid = os.fork()
      67          if self.pid == 0:
      68              try:
      69                  os.close(parent_r)
      70                  os.close(parent_w)
      71                  code = process_obj._bootstrap(parent_sentinel=child_r)
      72              finally:
      73                  os._exit(code)
      74          else:
      75              os.close(child_w)
      76              os.close(child_r)
      77              self.finalizer = util.Finalize(self, util.close_fds,
      78                                             (parent_r, parent_w,))
      79              self.sentinel = parent_r
      80  
      81      def close(self):
      82          if self.finalizer is not None:
      83              self.finalizer()