17db96d56Sopenharmony_ciimport io 27db96d56Sopenharmony_ciimport os 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_cifrom .context import reduction, set_spawning_popen 57db96d56Sopenharmony_cifrom . import popen_fork 67db96d56Sopenharmony_cifrom . import spawn 77db96d56Sopenharmony_cifrom . import util 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci__all__ = ['Popen'] 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci# 137db96d56Sopenharmony_ci# Wrapper for an fd used while launching a process 147db96d56Sopenharmony_ci# 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ciclass _DupFd(object): 177db96d56Sopenharmony_ci def __init__(self, fd): 187db96d56Sopenharmony_ci self.fd = fd 197db96d56Sopenharmony_ci def detach(self): 207db96d56Sopenharmony_ci return self.fd 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci# 237db96d56Sopenharmony_ci# Start child process using a fresh interpreter 247db96d56Sopenharmony_ci# 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ciclass Popen(popen_fork.Popen): 277db96d56Sopenharmony_ci method = 'spawn' 287db96d56Sopenharmony_ci DupFd = _DupFd 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci def __init__(self, process_obj): 317db96d56Sopenharmony_ci self._fds = [] 327db96d56Sopenharmony_ci super().__init__(process_obj) 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci def duplicate_for_child(self, fd): 357db96d56Sopenharmony_ci self._fds.append(fd) 367db96d56Sopenharmony_ci return fd 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci def _launch(self, process_obj): 397db96d56Sopenharmony_ci from . import resource_tracker 407db96d56Sopenharmony_ci tracker_fd = resource_tracker.getfd() 417db96d56Sopenharmony_ci self._fds.append(tracker_fd) 427db96d56Sopenharmony_ci prep_data = spawn.get_preparation_data(process_obj._name) 437db96d56Sopenharmony_ci fp = io.BytesIO() 447db96d56Sopenharmony_ci set_spawning_popen(self) 457db96d56Sopenharmony_ci try: 467db96d56Sopenharmony_ci reduction.dump(prep_data, fp) 477db96d56Sopenharmony_ci reduction.dump(process_obj, fp) 487db96d56Sopenharmony_ci finally: 497db96d56Sopenharmony_ci set_spawning_popen(None) 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci parent_r = child_w = child_r = parent_w = None 527db96d56Sopenharmony_ci try: 537db96d56Sopenharmony_ci parent_r, child_w = os.pipe() 547db96d56Sopenharmony_ci child_r, parent_w = os.pipe() 557db96d56Sopenharmony_ci cmd = spawn.get_command_line(tracker_fd=tracker_fd, 567db96d56Sopenharmony_ci pipe_handle=child_r) 577db96d56Sopenharmony_ci self._fds.extend([child_r, child_w]) 587db96d56Sopenharmony_ci self.pid = util.spawnv_passfds(spawn.get_executable(), 597db96d56Sopenharmony_ci cmd, self._fds) 607db96d56Sopenharmony_ci self.sentinel = parent_r 617db96d56Sopenharmony_ci with open(parent_w, 'wb', closefd=False) as f: 627db96d56Sopenharmony_ci f.write(fp.getbuffer()) 637db96d56Sopenharmony_ci finally: 647db96d56Sopenharmony_ci fds_to_close = [] 657db96d56Sopenharmony_ci for fd in (parent_r, parent_w): 667db96d56Sopenharmony_ci if fd is not None: 677db96d56Sopenharmony_ci fds_to_close.append(fd) 687db96d56Sopenharmony_ci self.finalizer = util.Finalize(self, util.close_fds, fds_to_close) 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci for fd in (child_r, child_w): 717db96d56Sopenharmony_ci if fd is not None: 727db96d56Sopenharmony_ci os.close(fd) 73