17db96d56Sopenharmony_ciimport os 27db96d56Sopenharmony_ciimport signal 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_cifrom . import util 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci__all__ = ['Popen'] 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci# 97db96d56Sopenharmony_ci# Start child process using fork 107db96d56Sopenharmony_ci# 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ciclass Popen(object): 137db96d56Sopenharmony_ci method = 'fork' 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci def __init__(self, process_obj): 167db96d56Sopenharmony_ci util._flush_std_streams() 177db96d56Sopenharmony_ci self.returncode = None 187db96d56Sopenharmony_ci self.finalizer = None 197db96d56Sopenharmony_ci self._launch(process_obj) 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci def duplicate_for_child(self, fd): 227db96d56Sopenharmony_ci return fd 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci def poll(self, flag=os.WNOHANG): 257db96d56Sopenharmony_ci if self.returncode is None: 267db96d56Sopenharmony_ci try: 277db96d56Sopenharmony_ci pid, sts = os.waitpid(self.pid, flag) 287db96d56Sopenharmony_ci except OSError: 297db96d56Sopenharmony_ci # Child process not yet created. See #1731717 307db96d56Sopenharmony_ci # e.errno == errno.ECHILD == 10 317db96d56Sopenharmony_ci return None 327db96d56Sopenharmony_ci if pid == self.pid: 337db96d56Sopenharmony_ci self.returncode = os.waitstatus_to_exitcode(sts) 347db96d56Sopenharmony_ci return self.returncode 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci def wait(self, timeout=None): 377db96d56Sopenharmony_ci if self.returncode is None: 387db96d56Sopenharmony_ci if timeout is not None: 397db96d56Sopenharmony_ci from multiprocessing.connection import wait 407db96d56Sopenharmony_ci if not wait([self.sentinel], timeout): 417db96d56Sopenharmony_ci return None 427db96d56Sopenharmony_ci # This shouldn't block if wait() returned successfully. 437db96d56Sopenharmony_ci return self.poll(os.WNOHANG if timeout == 0.0 else 0) 447db96d56Sopenharmony_ci return self.returncode 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci def _send_signal(self, sig): 477db96d56Sopenharmony_ci if self.returncode is None: 487db96d56Sopenharmony_ci try: 497db96d56Sopenharmony_ci os.kill(self.pid, sig) 507db96d56Sopenharmony_ci except ProcessLookupError: 517db96d56Sopenharmony_ci pass 527db96d56Sopenharmony_ci except OSError: 537db96d56Sopenharmony_ci if self.wait(timeout=0.1) is None: 547db96d56Sopenharmony_ci raise 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci def terminate(self): 577db96d56Sopenharmony_ci self._send_signal(signal.SIGTERM) 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci def kill(self): 607db96d56Sopenharmony_ci self._send_signal(signal.SIGKILL) 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci def _launch(self, process_obj): 637db96d56Sopenharmony_ci code = 1 647db96d56Sopenharmony_ci parent_r, child_w = os.pipe() 657db96d56Sopenharmony_ci child_r, parent_w = os.pipe() 667db96d56Sopenharmony_ci self.pid = os.fork() 677db96d56Sopenharmony_ci if self.pid == 0: 687db96d56Sopenharmony_ci try: 697db96d56Sopenharmony_ci os.close(parent_r) 707db96d56Sopenharmony_ci os.close(parent_w) 717db96d56Sopenharmony_ci code = process_obj._bootstrap(parent_sentinel=child_r) 727db96d56Sopenharmony_ci finally: 737db96d56Sopenharmony_ci os._exit(code) 747db96d56Sopenharmony_ci else: 757db96d56Sopenharmony_ci os.close(child_w) 767db96d56Sopenharmony_ci os.close(child_r) 777db96d56Sopenharmony_ci self.finalizer = util.Finalize(self, util.close_fds, 787db96d56Sopenharmony_ci (parent_r, parent_w,)) 797db96d56Sopenharmony_ci self.sentinel = parent_r 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci def close(self): 827db96d56Sopenharmony_ci if self.finalizer is not None: 837db96d56Sopenharmony_ci self.finalizer() 84