diff --git a/Sources/NIOFileSystem/Internal/System Calls/Errno.swift b/Sources/NIOFileSystem/Internal/System Calls/Errno.swift index 7ae8059879..cfb7f458e6 100644 --- a/Sources/NIOFileSystem/Internal/System Calls/Errno.swift +++ b/Sources/NIOFileSystem/Internal/System Calls/Errno.swift @@ -146,3 +146,24 @@ public func valueOrErrno( } } } + +/// As `valueOrErrno` but returns `Errno` if result is nil. +@_spi(Testing) +public func unwrapValueOrErrno( + retryOnInterrupt: Bool = true, + _ fn: () -> R? +) -> Result { + while true { + Errno.clear() + if let result = fn() { + return .success(result) + } else { + let errno = Errno._current + if errno == .interrupted, retryOnInterrupt { + continue + } else { + return .failure(errno) + } + } + } +} diff --git a/Sources/NIOFileSystem/Internal/System Calls/FileDescriptor+Syscalls.swift b/Sources/NIOFileSystem/Internal/System Calls/FileDescriptor+Syscalls.swift index 2941243999..e59d01dea2 100644 --- a/Sources/NIOFileSystem/Internal/System Calls/FileDescriptor+Syscalls.swift +++ b/Sources/NIOFileSystem/Internal/System Calls/FileDescriptor+Syscalls.swift @@ -191,7 +191,7 @@ extension FileDescriptor { /// caller should not modify the descriptor or close the descriptor via `close()`. Once /// directory iteration has been completed then `Libc.closdir(_:)` must be called. internal func opendir() -> Result { - valueOrErrno(retryOnInterrupt: false) { + unwrapValueOrErrno(retryOnInterrupt: false) { libc_fdopendir(self.rawValue) } } diff --git a/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift b/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift index a871876025..f75a5a01e7 100644 --- a/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift +++ b/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift @@ -368,8 +368,8 @@ internal func system_futimens( /// fdopendir(3): Opens a directory stream for the file descriptor internal func libc_fdopendir( _ fd: FileDescriptor.RawValue -) -> CInterop.DirPointer { - fdopendir(fd)! +) -> CInterop.DirPointer? { + fdopendir(fd) } /// readdir(3): Returns a pointer to the next directory entry