"""
+import ctypes
import os
import sys
import warnings # noqa: F401 (loaded lazily by os.execvp() which happens too late)
ENOENT = 2
ENOSYS = 38
F_DUPFD = 0
+F_GETFD = 1
FS_IOC_GETFLAGS = 0x80086601
FS_IOC_SETFLAGS = 0x40086602
FS_NOCOW_FL = 0x00800000
SIGSTOP = 19
-def is_valid_fd(fd: int) -> bool:
- try:
- os.close(os.dup(fd))
- except OSError as e:
- if e.errno != EBADF:
- raise
-
- return False
-
- return True
-
-
-def open_file_descriptors() -> list[int]:
- fds = []
-
- with os.scandir("/proc/self/fd") as it:
- for e in it:
- if not e.is_symlink() and (e.is_file() or e.is_dir()):
- continue
-
- try:
- fd = int(e.name)
- except ValueError:
- continue
-
- fds.append(fd)
-
- # os.scandir() either opens a file descriptor to the given path or dups the given file descriptor. Either
- # way, there will be an extra file descriptor in the fds array that's not valid anymore now, so find out
- # which one and drop it.
- return sorted(fd for fd in fds if is_valid_fd(fd))
-
-
-class CloseNewFileDescriptors:
- def __enter__(self) -> None:
- self.fds = set(open_file_descriptors())
-
- def __exit__(self, *args: object, **kwargs: object) -> None:
- for fd in open_file_descriptors():
- if fd not in self.fds:
- os.close(fd)
-
-
-# Since python 3.14, importing ctypes opens an extra file descriptor which is used to allocate libffi
-# closures which are in turn used by ctypes to pass python functions as C callback function pointers. We
-# don't use this functionality, yet the file descriptor is still opened and messes with the file descriptor
-# packing logic since the file descriptor to libffi will be passed as a packed file descriptor to the
-# executable we're invoking. To avoid that from happening, we close libffi's file descriptor after importing
-# ctypes. See https://github.com/python/cpython/issues/135893.
-with CloseNewFileDescriptors():
- import ctypes
-
-
class mount_attr(ctypes.Structure):
_fields_ = [
("attr_set", ctypes.c_uint64),
def pack_file_descriptors() -> int:
- fds = [fd for fd in open_file_descriptors() if fd >= SD_LISTEN_FDS_START]
+ fds = []
+
+ with os.scandir("/proc/self/fd") as it:
+ for e in it:
+ if not e.is_symlink() and (e.is_file() or e.is_dir()):
+ continue
+
+ try:
+ fd = int(e.name)
+ except ValueError:
+ continue
+
+ if fd < SD_LISTEN_FDS_START:
+ continue
+
+ fds.append(fd)
+
+ # os.scandir() either opens a file descriptor to the given path or dups the given file descriptor. Either
+ # way, there will be an extra file descriptor in the fds array that's not valid anymore now, so find out
+ # which one and drop it.
+ fds = sorted(fd for fd in fds if libc.fcntl(fd, F_GETFD, 0) >= 0)
# The following is a reimplementation of pack_fds() in systemd.