From 30a111639ce6a7ad54f77a091451bd5354afaae9 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Wed, 21 May 2025 21:24:28 +0200 Subject: expand use of FileDescriptor and add FileDescriptorLike type alias When accepting file descriptors, non-int objects with a fileno method are now generally accepted. When returning a file descriptor, a FileDescriptor instance is now returned. --- linuxnamespaces/syscalls.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'linuxnamespaces/syscalls.py') diff --git a/linuxnamespaces/syscalls.py b/linuxnamespaces/syscalls.py index f6af348..be0a5f7 100644 --- a/linuxnamespaces/syscalls.py +++ b/linuxnamespaces/syscalls.py @@ -15,6 +15,7 @@ import os import signal import typing +from .filedescriptor import FileDescriptor, FileDescriptorLike from .atlocation import AtFlags, AtLocation, AtLocationLike, PathConvertible @@ -498,7 +499,7 @@ class EventFD: ) -> None: if flags & ~EventFDFlags.ALL_FLAGS: raise ValueError("invalid flags for eventfd") - self.fd = os.eventfd(initval, int(flags)) + self.fd = FileDescriptor(os.eventfd(initval, int(flags))) def read(self) -> int: """Decrease the value of the eventfd using eventfd_read.""" @@ -541,7 +542,7 @@ class EventFD: raise ValueError("attempt to read from closed eventfd") os.eventfd_write(self.fd, value) - def fileno(self) -> int: + def fileno(self) -> FileDescriptor: """Return the underlying file descriptor.""" return self.fd @@ -551,7 +552,7 @@ class EventFD: try: os.close(self.fd) finally: - self.fd = -1 + self.fd = FileDescriptor(-1) __del__ = close @@ -610,7 +611,7 @@ def mount_setattr( attr_set: MountAttrFlags = MountAttrFlags.NONE, attr_clr: MountAttrFlags = MountAttrFlags.NONE, propagation: int = 0, - userns_fd: int = -1, + userns_fd: FileDescriptorLike = -1, ) -> None: """Python wrapper for mount_setattr(2).""" filesystem = AtLocation(filesystem) @@ -619,6 +620,8 @@ def mount_setattr( flags |= MountSetattrFlags.AT_RECURSIVE if attr_clr & MountAttrFlags.IDMAP: raise ValueError("cannot clear the MOUNT_ATTR_IDMAP flag") + if not isinstance(userns_fd, int): + userns_fd = userns_fd.fileno() attr = MountAttr(attr_set, attr_clr, propagation, userns_fd) call_libc( "mount_setattr", @@ -764,12 +767,14 @@ class SignalFD: sigmask: typing.Iterable[signal.Signals], flags: SignalFDFlags = SignalFDFlags.NONE, ): - self.fd = SignalFD.__signalfd(-1, sigmask, flags) + self.fd = SignalFD.__signalfd(FileDescriptor(-1), sigmask, flags) @staticmethod def __signalfd( - fd: int, sigmask: typing.Iterable[signal.Signals], flags: SignalFDFlags - ) -> int: + fd: FileDescriptor, + sigmask: typing.Iterable[signal.Signals], + flags: SignalFDFlags, + ) -> FileDescriptor: """Python wrapper for signalfd(2).""" bitsperlong = 8 * ctypes.sizeof(ctypes.c_ulong) nval = 64 // bitsperlong @@ -778,7 +783,7 @@ class SignalFD: sigval = int(sig) - 1 mask[sigval // bitsperlong] |= 1 << (sigval % bitsperlong) csigmask = (ctypes.c_ulong * nval)(*mask) - return call_libc("signalfd", fd, csigmask, int(flags)) + return FileDescriptor(call_libc("signalfd", fd, csigmask, int(flags))) def readv(self, count: int) -> list[SignalFDSigInfo]: """Read up to count signals from the signalfd.""" @@ -824,7 +829,7 @@ class SignalFD: loop.add_reader(self.fd, self.__handle_readable, self.fd, fut) return fut - def fileno(self) -> int: + def fileno(self) -> FileDescriptor: """Return the underlying file descriptor.""" return self.fd @@ -834,7 +839,7 @@ class SignalFD: try: os.close(self.fd) finally: - self.fd = -1 + self.fd = FileDescriptor(-1) __del__ = close -- cgit v1.2.3