[libc-commits] [libc] [libc] Implement mkfifoat in sys/stat (PR #224628)

Aman Maurya via libc-commits libc-commits at lists.llvm.org
Fri Sep 18 06:10:24 PDT 2026


https://github.com/amanmaurya92 created https://github.com/llvm/llvm-project/pull/224628

### Summary
Implement the standard POSIX.1-2008 function `mkfifoat` in `<sys/stat.h>`.

Fixes #224587

### Changes
- Added `mkfifoat` function specification to `libc/include/sys/stat.yaml`.
- Added internal header `libc/src/sys/stat/mkfifoat.h`.
- Implemented `mkfifoat` in `libc/src/sys/stat/linux/mkfifoat.cpp` using the existing `linux_syscalls::mknodat`.
- Registered `mkfifoat` entrypoint in `libc/src/sys/stat/CMakeLists.txt` and `libc/src/sys/stat/linux/CMakeLists.txt`.
- Added entrypoint across Linux targets (`x86_64`, `aarch64`, `riscv`).
- Added hermetic unit tests in `libc/test/src/sys/stat/mkfifoat_test.cpp` using `cpp::scope_exit` cleanup and C++ `static_cast<mode_t>`.

### Testing
- Built and passed hermetic unit test `libc.test.src.sys.stat.mkfifoat_test` (4/4 tests passed).
- Verified sibling tests (`mkfifo_test`, `fstat_test`).
- Ran `generate-libc-headers` and verified generated `sys/stat.h`.
- Verified `docgen.py sys/stat.h` output marks `mkfifoat` as implemented.
- Ran `clang-format` on all touched C++ files.

>From 42d04e8354d8418d4a3e059e210c287709b631e5 Mon Sep 17 00:00:00 2001
From: amanmaurya92 <amanmaurya9209 at gmail.com>
Date: Fri, 18 Sep 2026 16:13:15 +0530
Subject: [PATCH] [libc] Implement mkfifoat in sys/stat

Implement the standard POSIX.1-2008 function mkfifoat in <sys/stat.h>.

Fixes #224587

Assisted by Antigravity and Gemini, reviewed by amanmaurya92.
---
 libc/config/linux/aarch64/entrypoints.txt |  1 +
 libc/config/linux/riscv/entrypoints.txt   |  1 +
 libc/config/linux/x86_64/entrypoints.txt  |  1 +
 libc/include/sys/stat.yaml                |  6 ++
 libc/src/sys/stat/CMakeLists.txt          |  7 ++
 libc/src/sys/stat/linux/CMakeLists.txt    | 14 ++++
 libc/src/sys/stat/linux/mkfifoat.cpp      | 35 ++++++++++
 libc/src/sys/stat/mkfifoat.h              | 26 +++++++
 libc/test/src/sys/stat/CMakeLists.txt     | 24 +++++++
 libc/test/src/sys/stat/mkfifoat_test.cpp  | 83 +++++++++++++++++++++++
 10 files changed, 198 insertions(+)
 create mode 100644 libc/src/sys/stat/linux/mkfifoat.cpp
 create mode 100644 libc/src/sys/stat/mkfifoat.h
 create mode 100644 libc/test/src/sys/stat/mkfifoat_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 1a05ed55365b4..9c26f852c176a 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -355,6 +355,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.mkdir
     libc.src.sys.stat.mkdirat
     libc.src.sys.stat.mkfifo
+    libc.src.sys.stat.mkfifoat
     libc.src.sys.stat.stat
     libc.src.sys.stat.umask
     libc.src.sys.stat.utimensat
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index ba3600966fabf..949d253ca210b 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -386,6 +386,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.mkdir
     libc.src.sys.stat.mkdirat
     libc.src.sys.stat.mkfifo
+    libc.src.sys.stat.mkfifoat
     libc.src.sys.stat.stat
     libc.src.sys.stat.umask
     libc.src.sys.stat.utimensat
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index a32e83236e277..9eae3cd1dd7cc 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -391,6 +391,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.mkdir
     libc.src.sys.stat.mkdirat
     libc.src.sys.stat.mkfifo
+    libc.src.sys.stat.mkfifoat
     libc.src.sys.stat.stat
     libc.src.sys.stat.umask
     libc.src.sys.stat.utimensat
diff --git a/libc/include/sys/stat.yaml b/libc/include/sys/stat.yaml
index 3c75ce3d796cb..2c85429cfef17 100644
--- a/libc/include/sys/stat.yaml
+++ b/libc/include/sys/stat.yaml
@@ -63,6 +63,12 @@ functions:
     arguments:
       - type: const char *
       - type: mode_t
+  - name: mkfifoat
+    return_type: int
+    arguments:
+      - type: int
+      - type: const char *
+      - type: mode_t
   - name: stat
     return_type: int
     arguments:
diff --git a/libc/src/sys/stat/CMakeLists.txt b/libc/src/sys/stat/CMakeLists.txt
index ae1a3f76078f1..8481434bc2847 100644
--- a/libc/src/sys/stat/CMakeLists.txt
+++ b/libc/src/sys/stat/CMakeLists.txt
@@ -58,6 +58,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.mkfifo
 )
 
+add_entrypoint_object(
+  mkfifoat
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.mkfifoat
+)
+
 add_entrypoint_object(
   stat
   ALIAS
diff --git a/libc/src/sys/stat/linux/CMakeLists.txt b/libc/src/sys/stat/linux/CMakeLists.txt
index b087fc927459c..f53189bb0c5cc 100644
--- a/libc/src/sys/stat/linux/CMakeLists.txt
+++ b/libc/src/sys/stat/linux/CMakeLists.txt
@@ -74,6 +74,20 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  mkfifoat
+  SRCS
+    mkfifoat.cpp
+  HDRS
+    ../mkfifoat.h
+  DEPENDS
+    libc.hdr.fcntl_macros
+    libc.hdr.sys_stat_macros
+    libc.hdr.types.mode_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.mknodat
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   stat
   SRCS
diff --git a/libc/src/sys/stat/linux/mkfifoat.cpp b/libc/src/sys/stat/linux/mkfifoat.cpp
new file mode 100644
index 0000000000000..68363c177169f
--- /dev/null
+++ b/libc/src/sys/stat/linux/mkfifoat.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of mkfifoat.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/stat/mkfifoat.h"
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/mknodat.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, mkfifoat, (int dirfd, const char *path, mode_t mode)) {
+  auto result = linux_syscalls::mknodat(dirfd, path, mode | S_IFIFO, 0);
+  if (!result) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/stat/mkfifoat.h b/libc/src/sys/stat/mkfifoat.h
new file mode 100644
index 0000000000000..f1f2f57e6b8a8
--- /dev/null
+++ b/libc/src/sys/stat/mkfifoat.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for mkfifoat.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_STAT_MKFIFOAT_H
+#define LLVM_LIBC_SRC_SYS_STAT_MKFIFOAT_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int mkfifoat(int dirfd, const char *path, mode_t mode);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_STAT_MKFIFOAT_H
diff --git a/libc/test/src/sys/stat/CMakeLists.txt b/libc/test/src/sys/stat/CMakeLists.txt
index 775348f8c18fa..3c9842d0f7f5a 100644
--- a/libc/test/src/sys/stat/CMakeLists.txt
+++ b/libc/test/src/sys/stat/CMakeLists.txt
@@ -96,6 +96,30 @@ add_libc_test(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
+add_libc_test(
+  mkfifoat_test
+  SUITE
+    libc_sys_stat_unittests
+  SRCS
+    mkfifoat_test.cpp
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.fcntl_macros
+    libc.hdr.sys_stat_macros
+    libc.hdr.types.mode_t
+    libc.hdr.types.struct_stat
+    libc.src.__support.CPP.scope
+    libc.src.errno.errno
+    libc.src.fcntl.open
+    libc.src.sys.stat.mkfifoat
+    libc.src.sys.stat.stat
+    libc.src.sys.stat.umask
+    libc.src.unistd.close
+    libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
 add_libc_test(
   stat_test
   SUITE
diff --git a/libc/test/src/sys/stat/mkfifoat_test.cpp b/libc/test/src/sys/stat/mkfifoat_test.cpp
new file mode 100644
index 0000000000000..bacfc842d0df0
--- /dev/null
+++ b/libc/test/src/sys/stat/mkfifoat_test.cpp
@@ -0,0 +1,83 @@
+//===-- Unittests for mkfifoat --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "hdr/types/mode_t.h"
+#include "hdr/types/struct_stat.h"
+#include "src/__support/CPP/scope.h"
+#include "src/fcntl/open.h"
+#include "src/sys/stat/mkfifoat.h"
+#include "src/sys/stat/stat.h"
+#include "src/sys/stat/umask.h"
+#include "src/unistd/close.h"
+#include "src/unistd/unlink.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcMkfifoatTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcMkfifoatTest, CreateAndRemoveWithAtFdcwd) {
+  constexpr const char *TEST_FIFO = "testdata/mkfifoat.testfifo";
+  constexpr mode_t FIFO_MODE = S_IRUSR | S_IWUSR;
+
+  mode_t old_mask = LIBC_NAMESPACE::umask(0);
+  ASSERT_THAT(LIBC_NAMESPACE::mkfifoat(AT_FDCWD, TEST_FIFO, FIFO_MODE),
+              Succeeds(0));
+  LIBC_NAMESPACE::umask(old_mask);
+
+  LIBC_NAMESPACE::cpp::scope_exit cleanup(
+      [&] { EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FIFO), Succeeds(0)); });
+
+  struct stat statbuf;
+  ASSERT_THAT(LIBC_NAMESPACE::stat(TEST_FIFO, &statbuf), Succeeds(0));
+  ASSERT_TRUE(S_ISFIFO(statbuf.st_mode));
+  ASSERT_EQ(statbuf.st_mode & 07777, static_cast<mode_t>(FIFO_MODE));
+}
+
+TEST_F(LlvmLibcMkfifoatTest, CreateAndRemoveWithDirFd) {
+  constexpr const char *TEST_DIR = "testdata";
+  constexpr const char *TEST_FIFO_BASENAME = "mkfifoat_dir.testfifo";
+  constexpr const char *TEST_FIFO_PATH = "testdata/mkfifoat_dir.testfifo";
+  constexpr mode_t FIFO_MODE = S_IRUSR | S_IWUSR;
+
+  int dirfd = LIBC_NAMESPACE::open(TEST_DIR, O_DIRECTORY);
+  ASSERT_GT(dirfd, 0);
+  ASSERT_ERRNO_SUCCESS();
+  LIBC_NAMESPACE::cpp::scope_exit cleanup_dir(
+      [&] { EXPECT_THAT(LIBC_NAMESPACE::close(dirfd), Succeeds(0)); });
+
+  mode_t old_mask = LIBC_NAMESPACE::umask(0);
+  ASSERT_THAT(LIBC_NAMESPACE::mkfifoat(dirfd, TEST_FIFO_BASENAME, FIFO_MODE),
+              Succeeds(0));
+  LIBC_NAMESPACE::umask(old_mask);
+
+  LIBC_NAMESPACE::cpp::scope_exit cleanup_fifo([&] {
+    EXPECT_THAT(LIBC_NAMESPACE::unlink(TEST_FIFO_PATH), Succeeds(0));
+  });
+
+  struct stat statbuf;
+  ASSERT_THAT(LIBC_NAMESPACE::stat(TEST_FIFO_PATH, &statbuf), Succeeds(0));
+  ASSERT_TRUE(S_ISFIFO(statbuf.st_mode));
+  ASSERT_EQ(statbuf.st_mode & 07777, static_cast<mode_t>(FIFO_MODE));
+}
+
+TEST_F(LlvmLibcMkfifoatTest, BadDirFd) {
+  ASSERT_THAT(LIBC_NAMESPACE::mkfifoat(-1, "some-file", S_IRUSR | S_IWUSR),
+              Fails(EBADF));
+}
+
+TEST_F(LlvmLibcMkfifoatTest, NonExistentPath) {
+  ASSERT_THAT(LIBC_NAMESPACE::mkfifoat(
+                  AT_FDCWD, "testdata/non-existent-dir/mkfifoat.testfifo",
+                  S_IRUSR | S_IWUSR),
+              Fails(ENOENT));
+}



More information about the libc-commits mailing list