3333from ._chroot import setup_chroot
3434from .policy import Policy
3535
36+
37+ def _waitstatus_to_exitcode (status : int ) -> int :
38+ """Convert a waitpid status to an exit code (compat for Python <3.9)."""
39+ if hasattr (os , "waitstatus_to_exitcode" ):
40+ return os .waitstatus_to_exitcode (status )
41+ if os .WIFEXITED (status ):
42+ return os .WEXITSTATUS (status )
43+ if os .WIFSIGNALED (status ):
44+ return - os .WTERMSIG (status )
45+ return - 1
46+
3647# Set after seccomp confinement in the child. Any subsequent
3748# SandboxContext in this process is nested and must skip the
3849# notif filter (can't install two).
@@ -263,7 +274,7 @@ def _wait_raw(self, timeout: Optional[float] = None) -> int:
263274 # Blocking wait — pidfd not needed
264275 _ , status = os .waitpid (self ._pid , 0 )
265276 self ._exited = True
266- return os . waitstatus_to_exitcode (status )
277+ return _waitstatus_to_exitcode (status )
267278
268279 # Event-driven: pidfd becomes readable when child exits
269280 if not _pidfd_poll (self ._pidfd , timeout ):
@@ -274,7 +285,7 @@ def _wait_raw(self, timeout: Optional[float] = None) -> int:
274285 try :
275286 _ , status = os .waitpid (self ._pid , os .WNOHANG )
276287 self ._exited = True
277- return os . waitstatus_to_exitcode (status )
288+ return _waitstatus_to_exitcode (status )
278289 except ChildProcessError :
279290 self ._exited = True
280291 return - 1
0 commit comments