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