()
| 66 | |
| 67 | |
| 68 | def _fork_process() -> int: |
| 69 | assert os.name == "posix" |
| 70 | |
| 71 | # NOTE: using os._exit instead of sys.exit, because dvc built |
| 72 | # with PyInstaller has trouble with SystemExit exception and throws |
| 73 | # errors such as "[26338] Failed to execute script __main__" |
| 74 | try: |
| 75 | pid = os.fork() # type: ignore[attr-defined] |
| 76 | if pid > 0: |
| 77 | return pid |
| 78 | except OSError: |
| 79 | logger.exception("failed at first fork") |
| 80 | os._exit(1) |
| 81 | |
| 82 | os.setsid() # type: ignore[attr-defined] |
| 83 | |
| 84 | try: |
| 85 | pid = os.fork() # type: ignore[attr-defined] |
| 86 | if pid > 0: |
| 87 | os._exit(0) |
| 88 | except OSError: |
| 89 | logger.exception("failed at second fork") |
| 90 | os._exit(1) |
| 91 | |
| 92 | # disconnect from the terminal |
| 93 | fd = os.open(os.devnull, os.O_RDWR) |
| 94 | for fd2 in range(3): |
| 95 | os.dup2(fd, fd2) |
| 96 | os.close(fd) |
| 97 | return pid |
| 98 | |
| 99 | |
| 100 | def _posix_detached_subprocess(args: Sequence[str], **kwargs) -> int: |
no test coverage detected