From 30a111639ce6a7ad54f77a091451bd5354afaae9 Mon Sep 17 00:00:00 2001
From: Helmut Grohne <helmut@subdivi.de>
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/__init__.py | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

(limited to 'linuxnamespaces/__init__.py')

diff --git a/linuxnamespaces/__init__.py b/linuxnamespaces/__init__.py
index cd30498..ce37150 100644
--- a/linuxnamespaces/__init__.py
+++ b/linuxnamespaces/__init__.py
@@ -645,7 +645,12 @@ def unshare_user_idmap_nohelper(
 class _AsyncFilesender:
     bs = 65536
 
-    def __init__(self, from_fd: int, to_fd: int, count: int | None = None):
+    def __init__(
+        self,
+        from_fd: FileDescriptor,
+        to_fd: FileDescriptor,
+        count: int | None = None,
+    ):
         self.from_fd = from_fd
         self.to_fd = to_fd
         self.copied = 0
@@ -678,7 +683,12 @@ class _AsyncFilesender:
 class _AsyncSplicer:
     bs = 65536
 
-    def __init__(self, from_fd: int, to_fd: int, count: int | None = None):
+    def __init__(
+        self,
+        from_fd: FileDescriptor,
+        to_fd: FileDescriptor,
+        count: int | None = None,
+    ):
         self.from_fd = from_fd
         self.to_fd = to_fd
         self.copied = 0
@@ -722,7 +732,12 @@ class _AsyncSplicer:
 class _AsyncCopier:
     bs = 65536
 
-    def __init__(self, from_fd: int, to_fd: int, count: int | None = None):
+    def __init__(
+        self,
+        from_fd: FileDescriptor,
+        to_fd: FileDescriptor,
+        count: int | None = None,
+    ):
         self.from_fd = from_fd
         self.to_fd = to_fd
         self.buffer = b""
@@ -786,13 +801,15 @@ class _AsyncCopier:
 
 
 def async_copyfd(
-    from_fd: int, to_fd: int, count: int | None = None
+    from_fd: FileDescriptor, to_fd: FileDescriptor, count: int | None = None
 ) -> asyncio.Future[int]:
     """Copy the given number of bytes from the first file descriptor to the
     second file descriptor in an asyncio context. Both copies are performed
     binary. An efficient implementation is chosen depending on the file type
     of file descriptors.
     """
+    from_fd = FileDescriptor(from_fd)
+    to_fd = FileDescriptor(to_fd)
     from_mode = os.fstat(from_fd).st_mode
     if stat.S_ISREG(from_mode):
         return _AsyncFilesender(from_fd, to_fd, count).fut
@@ -802,7 +819,7 @@ def async_copyfd(
 
 
 class _AsyncPidfdWaiter:
-    def __init__(self, pidfd: int, flags: int):
+    def __init__(self, pidfd: FileDescriptor, flags: int):
         self.pidfd = pidfd
         self.flags = flags
         self.loop = asyncio.get_running_loop()
@@ -827,12 +844,12 @@ class _AsyncPidfdWaiter:
 
 
 def async_waitpidfd(
-    pidfd: int, flags: int
+    pidfd: FileDescriptorLike, flags: int
 ) -> asyncio.Future[os.waitid_result | None]:
     """Asynchronously wait for a process represented as a pidfd. This is an
     async variant of waitid(P_PIDFD, pidfd, flags).
     """
-    return _AsyncPidfdWaiter(pidfd, flags).fut
+    return _AsyncPidfdWaiter(FileDescriptor(pidfd), flags).fut
 
 
 def enable_loopback_if() -> None:
-- 
cgit v1.2.3