diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@
 
 This project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## 0.7.3.0 -- 2025-05-28
+
+- Add support for `openat`
+
 ## 0.7.2.0 -- 2024-02-28
 
 - Add `socket` as alias for `uninterruptibleSocket`.
diff --git a/posix-api.cabal b/posix-api.cabal
--- a/posix-api.cabal
+++ b/posix-api.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               posix-api
-version:            0.7.2.0
+version:            0.7.3.0
 synopsis:           posix bindings
 description:
   This library provides a very thin wrapper around POSIX APIs. It can be
diff --git a/src/Posix/File.hs b/src/Posix/File.hs
--- a/src/Posix/File.hs
+++ b/src/Posix/File.hs
@@ -16,6 +16,7 @@
   , writeBytesCompletelyErrno
   , uninterruptibleOpen
   , uninterruptibleOpenMode
+  , uninterruptibleOpenAtMode
   , uninterruptibleOpenUntypedFlags
   , uninterruptibleOpenModeUntypedFlags
   , writeByteArray
@@ -102,6 +103,9 @@
 foreign import ccall unsafe "HaskellPosix.h open"
   c_unsafe_open_mode :: ByteArray# -> CInt -> CMode -> IO Fd
 
+foreign import ccall unsafe "HaskellPosix.h openat"
+  c_unsafe_openat_mode :: Fd -> ByteArray# -> CInt -> CMode -> IO Fd
+
 foreign import ccall unsafe "HaskellPosix.h unlink"
   c_unsafe_unlink :: ByteArray# -> IO CInt
 
@@ -167,6 +171,27 @@
   IO (Either Errno Fd)
 uninterruptibleOpenMode (ManagedCString (ByteArray name)) (AccessMode x) (CreationFlags y) (StatusFlags z) !mode =
   c_unsafe_open_mode name (x .|. y .|. z) mode >>= errorsFromFd
+
+{- | Variant of 'uninterruptibleOpenMode' that lets the user specify a
+directory file descriptor instead of using the working directory as the
+base path.
+-}
+uninterruptibleOpenAtMode ::
+  -- | Base directory
+  Fd ->
+  -- | NULL-terminated file name
+  ManagedCString ->
+  -- | Access mode, should include @O_CREAT@
+  AccessMode ->
+  -- | Creation flags
+  CreationFlags ->
+  -- | Status flags
+  StatusFlags ->
+  -- | Permissions assigned to newly created file
+  CMode ->
+  IO (Either Errno Fd)
+uninterruptibleOpenAtMode !dirFd (ManagedCString (ByteArray name)) (AccessMode x) (CreationFlags y) (StatusFlags z) !mode =
+  c_unsafe_openat_mode dirFd name (x .|. y .|. z) mode >>= errorsFromFd
 
 errorsFromDescriptorFlags :: DescriptorFlags -> IO (Either Errno DescriptorFlags)
 errorsFromDescriptorFlags r@(DescriptorFlags x) =
