@@ -188,10 +188,36 @@ async def connect_stdout():
188
188
189
189
@override
190
190
def _connect_child (self , argv : List [str ]) -> None :
191
- if os .name != 'nt' :
192
- # see #238, #241
193
- self ._child_watcher = asyncio .get_child_watcher ()
194
- self ._child_watcher .attach_loop (self ._loop )
191
+ def can_use_pidfd ():
192
+ # Unix system without pidfd_open?
193
+ if not hasattr (os , 'pidfd_open' ):
194
+ return False
195
+
196
+ # Check that we are not blocked by security policy like SECCOMP
197
+ try :
198
+ pid = os .getpid ()
199
+ fd = os .pidfd_open (pid , 0 )
200
+ os .close (fd )
201
+ except OSError :
202
+ return False
203
+
204
+ return True
205
+
206
+ def get_child_watcher ():
207
+ if can_use_pidfd ():
208
+ try :
209
+ from asyncio .unix_events import PidfdChildWatcher
210
+ return PidfdChildWatcher ()
211
+ except ImportError :
212
+ pass
213
+
214
+ try :
215
+ from asyncio .unix_events import ThreadedChildWatcher
216
+ return ThreadedChildWatcher ()
217
+ except ImportError :
218
+ pass
219
+
220
+ return asyncio .get_child_watcher ()
195
221
196
222
async def create_subprocess ():
197
223
transport : asyncio .SubprocessTransport # type: ignore
@@ -200,6 +226,12 @@ async def create_subprocess():
200
226
pid = transport .get_pid ()
201
227
debug ("child subprocess_exec successful, PID = %s" , pid )
202
228
229
+ if os .name != 'nt' :
230
+ watcher = get_child_watcher ()
231
+
232
+ watcher .attach_loop (self ._loop )
233
+ self ._child_watcher = watcher
234
+
203
235
self ._transport = cast (asyncio .WriteTransport ,
204
236
transport .get_pipe_transport (0 )) # stdin
205
237
self ._protocol = protocol
0 commit comments