MCPcopy Create free account
hub / github.com/Dispatcharr/Dispatcharr / posix_spawn_proc

Function posix_spawn_proc

apps/proxy/live_proxy/utils.py:119–234  ·  view source on GitHub ↗

Spawn a subprocess using os.posix_spawn() with stdin, stdout, and stderr piped. Returns an object compatible with subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE). Under gevent+uWSGI, fork() hangs indefinitely in gevent's _before_fork atfork handler regardless of whethe

(cmd)

Source from the content-addressed store, hash-verified

117
118
119def posix_spawn_proc(cmd):
120 """
121 Spawn a subprocess using os.posix_spawn() with stdin, stdout, and stderr piped.
122
123 Returns an object compatible with subprocess.Popen(cmd, stdin=PIPE,
124 stdout=PIPE, stderr=PIPE). Under gevent+uWSGI, fork() hangs indefinitely
125 in gevent's _before_fork atfork handler regardless of whether it is called
126 from a hub greenlet or a threadpool thread. os.posix_spawn() is explicitly
127 defined by POSIX to not call pthread_atfork handlers.
128 """
129 import os
130 import shutil
131 import signal
132 import subprocess
133 import time
134
135 stdin_r, stdin_w = os.pipe() # child reads stdin (FD 0) from here
136 stdout_r, stdout_w = os.pipe() # child writes stdout (FD 1) here; parent reads
137 stderr_r, stderr_w = os.pipe() # child writes stderr (FD 2) here; parent reads
138
139 stdin_w_ok = stdout_r_ok = stderr_r_ok = False
140 try:
141 executable = shutil.which(cmd[0]) or cmd[0]
142 child_pid = os.posix_spawn(
143 executable, cmd, os.environ,
144 file_actions=[
145 (os.POSIX_SPAWN_DUP2, stdin_r, 0),
146 (os.POSIX_SPAWN_DUP2, stdout_w, 1),
147 (os.POSIX_SPAWN_DUP2, stderr_w, 2),
148 (os.POSIX_SPAWN_CLOSE, stdin_r),
149 (os.POSIX_SPAWN_CLOSE, stdout_w),
150 (os.POSIX_SPAWN_CLOSE, stderr_w),
151 ],
152 )
153
154 import fcntl
155 fcntl.fcntl(stdin_w, fcntl.F_SETFL, fcntl.fcntl(stdin_w, fcntl.F_GETFL) | os.O_NONBLOCK)
156 stdin_file = os.fdopen(stdin_w, 'wb', buffering=0)
157 stdin_w_ok = True
158 stdout_file = os.fdopen(stdout_r, 'rb', buffering=0)
159 stdout_r_ok = True
160 stderr_file = os.fdopen(stderr_r, 'rb', buffering=0)
161 stderr_r_ok = True
162
163 class _Proc:
164 stdin = stdin_file
165 stdout = stdout_file
166 stderr = stderr_file
167
168 def __init__(self):
169 self.pid = child_pid
170 self.returncode = None
171
172 def _reap(self, status):
173 if os.WIFEXITED(status):
174 self.returncode = os.WEXITSTATUS(status)
175 elif os.WIFSIGNALED(status):
176 self.returncode = -os.WTERMSIG(status)

Callers 3

startMethod · 0.85
startMethod · 0.85
_handle_bsf_errorMethod · 0.85

Calls 2

_ProcClass · 0.85
closeMethod · 0.45

Tested by

no test coverage detected