[libc-commits] [libc] [libc][sys] add header and functions for sys ipc (PR #182700)

Pengxiang Huang via libc-commits libc-commits at lists.llvm.org
Fri Feb 27 06:05:08 PST 2026


https://github.com/Pengxiang-Huang updated https://github.com/llvm/llvm-project/pull/182700

>From bb2e8283d3dded9d9001414667cb8f4d9f4d9728 Mon Sep 17 00:00:00 2001
From: Pengxiang Huang <huangpengxiang70 at gmail.com>
Date: Sat, 21 Feb 2026 14:52:40 -0500
Subject: [PATCH 1/3] add the feature libc sys/ipc, add macros, types,
 functions, implementation using stat syscall wrapper, target on x86_64 linux,
 add one test; used to implement sys/sem in the next pr

---
 libc/config/linux/x86_64/entrypoints.txt      |  3 +
 libc/config/linux/x86_64/headers.txt          |  1 +
 libc/include/CMakeLists.txt                   | 15 +++++
 libc/include/llvm-libc-macros/CMakeLists.txt  |  6 ++
 .../llvm-libc-macros/linux/CMakeLists.txt     |  6 ++
 .../llvm-libc-macros/linux/sys-ipc-macros.h   | 24 ++++++++
 .../include/llvm-libc-macros/sys-ipc-macros.h | 16 +++++
 libc/include/llvm-libc-types/CMakeLists.txt   |  9 +++
 libc/include/llvm-libc-types/key_t.h          | 14 +++++
 .../include/llvm-libc-types/struct_ipc_perm.h | 33 +++++++++++
 libc/include/sys/ipc.h.def                    | 18 ++++++
 libc/include/sys/ipc.yaml                     | 19 ++++++
 libc/include/sys/types.yaml                   |  1 +
 libc/src/sys/CMakeLists.txt                   |  1 +
 libc/src/sys/ipc/CMakeLists.txt               | 10 ++++
 libc/src/sys/ipc/ftok.h                       | 22 +++++++
 libc/src/sys/ipc/linux/CMakeLists.txt         | 10 ++++
 libc/src/sys/ipc/linux/ftok.cpp               | 28 +++++++++
 libc/test/src/sys/CMakeLists.txt              |  1 +
 libc/test/src/sys/ipc/CMakeLists.txt          |  3 +
 libc/test/src/sys/ipc/linux/CMakeLists.txt    | 19 ++++++
 libc/test/src/sys/ipc/linux/ftok_test.cpp     | 59 +++++++++++++++++++
 22 files changed, 318 insertions(+)
 create mode 100644 libc/include/llvm-libc-macros/linux/sys-ipc-macros.h
 create mode 100644 libc/include/llvm-libc-macros/sys-ipc-macros.h
 create mode 100644 libc/include/llvm-libc-types/key_t.h
 create mode 100644 libc/include/llvm-libc-types/struct_ipc_perm.h
 create mode 100644 libc/include/sys/ipc.h.def
 create mode 100644 libc/include/sys/ipc.yaml
 create mode 100644 libc/src/sys/ipc/CMakeLists.txt
 create mode 100644 libc/src/sys/ipc/ftok.h
 create mode 100644 libc/src/sys/ipc/linux/CMakeLists.txt
 create mode 100644 libc/src/sys/ipc/linux/ftok.cpp
 create mode 100644 libc/test/src/sys/ipc/CMakeLists.txt
 create mode 100644 libc/test/src/sys/ipc/linux/CMakeLists.txt
 create mode 100644 libc/test/src/sys/ipc/linux/ftok_test.cpp

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 6f0ecf0c6885d..3c5f1c7d55467 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -251,6 +251,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # sys/ioctl.h entrypoints
     libc.src.sys.ioctl.ioctl
 
+    # sys/ipc.h entrypoints
+    libc.src.sys.ipc.ftok
+
     # sys/mman.h entrypoints
     libc.src.sys.mman.madvise
     libc.src.sys.mman.mincore
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index d0f62eb104dcc..0669cc30aeadc 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -38,6 +38,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_auxv
     libc.include.sys_epoll
     libc.include.sys_ioctl
+    libc.include.sys_ipc
     libc.include.sys_mman
     libc.include.sys_prctl
     libc.include.sys_queue
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index c6254aafe3849..5ffee68b5feb3 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -557,6 +557,20 @@ add_header_macro(
     .llvm-libc-macros.sys_ioctl_macros
 )
 
+add_header_macro(
+  sys_ipc
+  ../libc/include/sys/ipc.yaml
+  sys/ipc.h
+  DEPENDS
+    .llvm_libc_common_h
+    .llvm-libc-macros.sys_ipc_macros
+    .llvm-libc-types.key_t
+    .llvm-libc-types.uid_t
+    .llvm-libc-types.gid_t
+    .llvm-libc-types.mode_t
+    .llvm-libc-types.struct_ipc_perm
+)
+
 add_header_macro(
   sys_mman
   ../libc/include/sys/mman.yaml
@@ -708,6 +722,7 @@ add_header_macro(
     .llvm-libc-types.dev_t
     .llvm-libc-types.gid_t
     .llvm-libc-types.ino_t
+    .llvm-libc-types.key_t
     .llvm-libc-types.mode_t
     .llvm-libc-types.nlink_t
     .llvm-libc-types.off_t
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index b16337cccd58b..553879e27d3d2 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -226,6 +226,12 @@ add_macro_header(
     sys-ioctl-macros.h
 )
 
+add_macro_header(
+  sys_ipc_macros
+  HDR
+    sys-ipc-macros.h
+)
+
 add_macro_header(
   sys_stat_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 61da55eabd40b..60376641b50f6 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -34,6 +34,12 @@ add_header(
     sys-ioctl-macros.h
 )
 
+add_header(
+  sys_ipc_macros
+  HDR
+    sys-ipc-macros.h
+)
+
 add_header(
   sys_random_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h b/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h
new file mode 100644
index 0000000000000..111f48542c518
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h
@@ -0,0 +1,24 @@
+//===-- Definition of macros from sys/ipc.h -------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_IPC_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_IPC_MACROS_H
+
+#define IPC_PRIVATE 0
+
+// Resource get request flags.
+#define IPC_CREAT 00001000
+#define IPC_EXCL 00002000
+#define IPC_NOWAIT 00004000
+
+// Control commands used with semctl, msgctl, and shmctl.
+#define IPC_RMID 0
+#define IPC_SET 1
+#define IPC_STAT 2
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_IPC_MACROS_H
diff --git a/libc/include/llvm-libc-macros/sys-ipc-macros.h b/libc/include/llvm-libc-macros/sys-ipc-macros.h
new file mode 100644
index 0000000000000..37e7e45456d2a
--- /dev/null
+++ b/libc/include/llvm-libc-macros/sys-ipc-macros.h
@@ -0,0 +1,16 @@
+//===-- Macros defined in sys/ipc.h header file ---------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYS_IPC_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_IPC_MACROS_H
+
+#ifdef __linux__
+#include "linux/sys-ipc-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_SYS_IPC_MACROS_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index dc36dfeadba57..52831bf440be7 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -44,6 +44,7 @@ add_header(in_addr HDR in_addr.h DEPENDS .in_addr_t)
 add_header(ino_t HDR ino_t.h)
 add_header(mbstate_t HDR mbstate_t.h)
 add_header(mode_t HDR mode_t.h)
+add_header(key_t HDR key_t.h)
 add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
 add_header(nfds_t HDR nfds_t.h)
 add_header(nl_catd HDR nl_catd.h)
@@ -79,6 +80,14 @@ add_header(dl_info HDR Dl_info.h)
 add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t)
 add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t)
 add_header(struct_flock64 HDR struct_flock64.h DEPENDS .off64_t .pid_t)
+add_header(
+  struct_ipc_perm
+  HDR struct_ipc_perm.h
+  DEPENDS
+    .key_t
+    .uid_t
+    .gid_t
+)
 add_header(struct_pollfd HDR struct_pollfd.h)
 add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
 add_header(struct_sched_param HDR struct_sched_param.h)
diff --git a/libc/include/llvm-libc-types/key_t.h b/libc/include/llvm-libc-types/key_t.h
new file mode 100644
index 0000000000000..1515469880862
--- /dev/null
+++ b/libc/include/llvm-libc-types/key_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of key_t type ------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_KEY_T_H
+#define LLVM_LIBC_TYPES_KEY_T_H
+
+typedef __INT32_TYPE__ key_t;
+
+#endif // LLVM_LIBC_TYPES_KEY_T_H
diff --git a/libc/include/llvm-libc-types/struct_ipc_perm.h b/libc/include/llvm-libc-types/struct_ipc_perm.h
new file mode 100644
index 0000000000000..60c021cd5a1cf
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_ipc_perm.h
@@ -0,0 +1,33 @@
+//===-- Definition of struct ipc_perm -------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_IPC_PERM_H
+#define LLVM_LIBC_TYPES_STRUCT_IPC_PERM_H
+
+#include "gid_t.h"
+#include "key_t.h"
+#include "uid_t.h"
+
+#ifdef __linux__
+struct ipc_perm {
+  key_t __key;
+  uid_t uid;
+  gid_t gid;
+  uid_t cuid;
+  gid_t cgid;
+  unsigned short mode;
+  unsigned short seq;
+  unsigned short padding;
+  unsigned long unused_0;
+  unsigned long unused_1;
+};
+#else
+#error "ipc_perm not defined for the target platform"
+#endif
+
+#endif // LLVM_LIBC_TYPES_STRUCT_IPC_PERM_H
diff --git a/libc/include/sys/ipc.h.def b/libc/include/sys/ipc.h.def
new file mode 100644
index 0000000000000..8688bad8a1159
--- /dev/null
+++ b/libc/include/sys/ipc.h.def
@@ -0,0 +1,18 @@
+//===-- Linux header sys/ipc.h --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SYS_IPC_H
+#define LLVM_LIBC_SYS_IPC_H
+
+#include "__llvm-libc-common.h"
+
+#include "../llvm-libc-macros/sys-ipc-macros.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_SYS_IPC_H
diff --git a/libc/include/sys/ipc.yaml b/libc/include/sys/ipc.yaml
new file mode 100644
index 0000000000000..172f5f64a3398
--- /dev/null
+++ b/libc/include/sys/ipc.yaml
@@ -0,0 +1,19 @@
+header: sys/ipc.h
+header_template: ipc.h.def
+standards:
+  - Linux
+types:
+  - type_name: key_t
+  - type_name: uid_t
+  - type_name: gid_t
+  - type_name: struct_ipc_perm
+functions:
+  - name: ftok
+    standards:
+      - Linux
+    return_type: key_t
+    arguments:
+      - type: const char *
+      - type: int
+enums: []
+objects: []
diff --git a/libc/include/sys/types.yaml b/libc/include/sys/types.yaml
index a00429d3817e1..126c597b30353 100644
--- a/libc/include/sys/types.yaml
+++ b/libc/include/sys/types.yaml
@@ -8,6 +8,7 @@ types:
   - type_name: dev_t
   - type_name: gid_t
   - type_name: ino_t
+  - type_name: key_t
   - type_name: mode_t
   - type_name: nlink_t
   - type_name: off_t
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index 0fa11e9eee696..1c17ec31a8592 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_subdirectory(auxv)
 add_subdirectory(epoll)
+add_subdirectory(ipc)
 add_subdirectory(mman)
 add_subdirectory(random)
 add_subdirectory(resource)
diff --git a/libc/src/sys/ipc/CMakeLists.txt b/libc/src/sys/ipc/CMakeLists.txt
new file mode 100644
index 0000000000000..e20ac7e3f964e
--- /dev/null
+++ b/libc/src/sys/ipc/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+  ftok
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.ftok
+)
diff --git a/libc/src/sys/ipc/ftok.h b/libc/src/sys/ipc/ftok.h
new file mode 100644
index 0000000000000..6b9d0fa40b028
--- /dev/null
+++ b/libc/src/sys/ipc/ftok.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for ftok ---------------------------*- C++
+//-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_IPC_FTOK_H
+#define LLVM_LIBC_SRC_SYS_IPC_FTOK_H
+
+#include "src/__support/macros/config.h"
+#include <sys/ipc.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+key_t ftok(const char *path, int id);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_IPC_FTOK_H
diff --git a/libc/src/sys/ipc/linux/CMakeLists.txt b/libc/src/sys/ipc/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..c2fdebcf989dc
--- /dev/null
+++ b/libc/src/sys/ipc/linux/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_entrypoint_object(
+  ftok
+  SRCS
+    ftok.cpp
+  HDRS
+    ../ftok.h
+  DEPENDS
+    libc.include.sys_ipc
+    libc.src.sys.stat.stat
+)
diff --git a/libc/src/sys/ipc/linux/ftok.cpp b/libc/src/sys/ipc/linux/ftok.cpp
new file mode 100644
index 0000000000000..6d0920c77ced3
--- /dev/null
+++ b/libc/src/sys/ipc/linux/ftok.cpp
@@ -0,0 +1,28 @@
+//===-- Linux implementation of ftok -------------------------------------===//
+//
+// 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 "src/sys/ipc/ftok.h"
+
+#include "src/__support/common.h"
+#include "src/sys/stat/stat.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(key_t, ftok, (const char *path, int id)) {
+
+  // ftok implements based on stat
+  struct stat st;
+  if (LIBC_NAMESPACE::stat(path, &st) < 0)
+    return -1;
+
+  return static_cast<key_t>(((id & 0xff) << 24) |
+                            ((static_cast<int>(st.st_dev) & 0xff) << 16) |
+                            (static_cast<int>(st.st_ino) & 0xffff));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 13bf91eef04be..3b5ea64fb1448 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -11,6 +11,7 @@ add_subdirectory(wait)
 add_subdirectory(prctl)
 add_subdirectory(auxv)
 add_subdirectory(epoll)
+add_subdirectory(ipc)
 add_subdirectory(uio)
 add_subdirectory(time)
 add_subdirectory(ioctl)
diff --git a/libc/test/src/sys/ipc/CMakeLists.txt b/libc/test/src/sys/ipc/CMakeLists.txt
new file mode 100644
index 0000000000000..b4bbe81c92ff2
--- /dev/null
+++ b/libc/test/src/sys/ipc/CMakeLists.txt
@@ -0,0 +1,3 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${LIBC_TARGET_OS})
+endif()
diff --git a/libc/test/src/sys/ipc/linux/CMakeLists.txt b/libc/test/src/sys/ipc/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..21d501a3029ef
--- /dev/null
+++ b/libc/test/src/sys/ipc/linux/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_custom_target(libc_sys_ipc_unittests)
+
+add_libc_unittest(
+  ftok_test
+  SUITE
+    libc_sys_ipc_unittests
+  SRCS
+    ftok_test.cpp
+  DEPENDS
+    libc.hdr.fcntl_macros
+    libc.include.sys_ipc
+    libc.src.errno.errno
+    libc.src.fcntl.open
+    libc.src.sys.ipc.ftok
+    libc.src.unistd.close
+    libc.src.unistd.unlink
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
diff --git a/libc/test/src/sys/ipc/linux/ftok_test.cpp b/libc/test/src/sys/ipc/linux/ftok_test.cpp
new file mode 100644
index 0000000000000..dd9a4702d439b
--- /dev/null
+++ b/libc/test/src/sys/ipc/linux/ftok_test.cpp
@@ -0,0 +1,59 @@
+//===-- Unittests for ftok ------------------------------------------------===//
+//
+// 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 "src/fcntl/open.h"
+#include "src/sys/ipc/ftok.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"
+
+#include "hdr/fcntl_macros.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcFtokTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcFtokTest, InvalidPath) {
+  ASSERT_THAT(LIBC_NAMESPACE::ftok("no/such/path", 1), Fails(ENOENT));
+}
+
+TEST_F(LlvmLibcFtokTest, DeterministicForPathAndId) {
+  // create a file
+  constexpr const char *TEST_FILE_NAME = "ftok.test";
+  auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
+
+  // we first ensure such file exist and set to readable, writable
+  int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_WRONLY, 0600);
+  ASSERT_GT(fd, -1);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+
+  // create keys based on file path and user specified int
+  key_t key1 = LIBC_NAMESPACE::ftok(TEST_FILE, 'A');
+  ASSERT_NE(key1, key_t(-1));
+  ASSERT_ERRNO_SUCCESS();
+
+  key_t key2 = LIBC_NAMESPACE::ftok(TEST_FILE, 'A');
+  ASSERT_NE(key2, key_t(-1));
+  ASSERT_ERRNO_SUCCESS();
+
+  // key should be identical if both inputs are the same
+  ASSERT_EQ(key1, key2);
+
+  // create another key
+  key_t key3 = LIBC_NAMESPACE::ftok(TEST_FILE, 'B');
+  ASSERT_NE(key3, key_t(-1));
+  ASSERT_ERRNO_SUCCESS();
+
+  // key should be different if any input is different
+  ASSERT_NE(key1, key3);
+
+  // delete the file
+  ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
+}

>From 9192546cf8f3bab9f806719c6b0e55841d243d8a Mon Sep 17 00:00:00 2001
From: Pengxiang Huang <huangpengxiang70 at gmail.com>
Date: Tue, 24 Feb 2026 15:59:03 -0500
Subject: [PATCH 2/3] [libc][sys] fix the issues reviewer points out

type mode change to mode_t; remove header templates for ipc.h, add the macros in the yaml; change the standards to posix

add the proxy type for key_t in hdr/, change the implementation of ftok, now it wraps the syscall of statx, implementation is basically the same as sys/stat
---
 libc/hdr/types/CMakeLists.txt                 |  9 +++
 libc/hdr/types/key_t.h                        | 22 +++++
 .../llvm-libc-macros/linux/sys-ipc-macros.h   |  6 +-
 libc/include/llvm-libc-types/CMakeLists.txt   |  2 +-
 .../include/llvm-libc-types/struct_ipc_perm.h |  3 +-
 libc/include/sys/ipc.h.def                    | 18 -----
 libc/include/sys/ipc.yaml                     | 42 ++++++++--
 libc/src/sys/ipc/ftok.h                       |  2 +-
 libc/src/sys/ipc/linux/CMakeLists.txt         | 18 ++++-
 libc/src/sys/ipc/linux/ftok.cpp               | 21 ++---
 libc/src/sys/ipc/linux/kernel_statx.h         | 80 +++++++++++++++++++
 11 files changed, 183 insertions(+), 40 deletions(-)
 create mode 100644 libc/hdr/types/key_t.h
 delete mode 100644 libc/include/sys/ipc.h.def
 create mode 100644 libc/src/sys/ipc/linux/kernel_statx.h

diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 3385fe81fe223..03e7066f83a03 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -233,6 +233,15 @@ add_proxy_header_library(
     libc.include.sys_time
 )
 
+add_proxy_header_library(
+  key_t
+  HDRS
+    key_t.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.key_t
+    libc.include.sys_ipc
+)
+
 add_proxy_header_library(
   pid_t
   HDRS
diff --git a/libc/hdr/types/key_t.h b/libc/hdr/types/key_t.h
new file mode 100644
index 0000000000000..478522a93a196
--- /dev/null
+++ b/libc/hdr/types/key_t.h
@@ -0,0 +1,22 @@
+//===-- Proxy for key_t ---------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_KEY_T_H
+#define LLVM_LIBC_HDR_TYPES_KEY_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/key_t.h"
+
+#else // Overlay mode
+
+#include <sys/ipc.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_KEY_T_H
diff --git a/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h b/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h
index 111f48542c518..87546ac314d83 100644
--- a/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h
+++ b/libc/include/llvm-libc-macros/linux/sys-ipc-macros.h
@@ -12,9 +12,9 @@
 #define IPC_PRIVATE 0
 
 // Resource get request flags.
-#define IPC_CREAT 00001000
-#define IPC_EXCL 00002000
-#define IPC_NOWAIT 00004000
+#define IPC_CREAT 01000
+#define IPC_EXCL 02000
+#define IPC_NOWAIT 04000
 
 // Control commands used with semctl, msgctl, and shmctl.
 #define IPC_RMID 0
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 52831bf440be7..18c43c6a4a366 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -42,9 +42,9 @@ add_header(imaxdiv_t HDR imaxdiv_t.h)
 add_header(in_addr_t HDR in_addr_t.h)
 add_header(in_addr HDR in_addr.h DEPENDS .in_addr_t)
 add_header(ino_t HDR ino_t.h)
+add_header(key_t HDR key_t.h)
 add_header(mbstate_t HDR mbstate_t.h)
 add_header(mode_t HDR mode_t.h)
-add_header(key_t HDR key_t.h)
 add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
 add_header(nfds_t HDR nfds_t.h)
 add_header(nl_catd HDR nl_catd.h)
diff --git a/libc/include/llvm-libc-types/struct_ipc_perm.h b/libc/include/llvm-libc-types/struct_ipc_perm.h
index 60c021cd5a1cf..e9f02da2585c9 100644
--- a/libc/include/llvm-libc-types/struct_ipc_perm.h
+++ b/libc/include/llvm-libc-types/struct_ipc_perm.h
@@ -11,6 +11,7 @@
 
 #include "gid_t.h"
 #include "key_t.h"
+#include "mode_t.h"
 #include "uid_t.h"
 
 #ifdef __linux__
@@ -20,7 +21,7 @@ struct ipc_perm {
   gid_t gid;
   uid_t cuid;
   gid_t cgid;
-  unsigned short mode;
+  mode_t mode;
   unsigned short seq;
   unsigned short padding;
   unsigned long unused_0;
diff --git a/libc/include/sys/ipc.h.def b/libc/include/sys/ipc.h.def
deleted file mode 100644
index 8688bad8a1159..0000000000000
--- a/libc/include/sys/ipc.h.def
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Linux header sys/ipc.h --------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIBC_SYS_IPC_H
-#define LLVM_LIBC_SYS_IPC_H
-
-#include "__llvm-libc-common.h"
-
-#include "../llvm-libc-macros/sys-ipc-macros.h"
-
-%%public_api()
-
-#endif // LLVM_LIBC_SYS_IPC_H
diff --git a/libc/include/sys/ipc.yaml b/libc/include/sys/ipc.yaml
index 172f5f64a3398..77593af1dc0a6 100644
--- a/libc/include/sys/ipc.yaml
+++ b/libc/include/sys/ipc.yaml
@@ -1,19 +1,51 @@
 header: sys/ipc.h
-header_template: ipc.h.def
 standards:
-  - Linux
+  - posix
+  - linux
+macros:
+  - macro_name: IPC_PRIVATE
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_CREAT
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_EXCL
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_NOWAIT
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_RMID
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_SET
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_STAT
+    macro_header: sys-ipc-macros.h
+    standards:
+      - posix
+  - macro_name: IPC_INFO
+    macro_header: sys-ipc-macros.h
+    standards:
+      - linux
 types:
   - type_name: key_t
   - type_name: uid_t
   - type_name: gid_t
+  - type_name: mode_t
   - type_name: struct_ipc_perm
 functions:
   - name: ftok
     standards:
-      - Linux
+      - posix
     return_type: key_t
     arguments:
       - type: const char *
       - type: int
-enums: []
-objects: []
diff --git a/libc/src/sys/ipc/ftok.h b/libc/src/sys/ipc/ftok.h
index 6b9d0fa40b028..91203c78610b9 100644
--- a/libc/src/sys/ipc/ftok.h
+++ b/libc/src/sys/ipc/ftok.h
@@ -10,8 +10,8 @@
 #ifndef LLVM_LIBC_SRC_SYS_IPC_FTOK_H
 #define LLVM_LIBC_SRC_SYS_IPC_FTOK_H
 
+#include "hdr/types/key_t.h"
 #include "src/__support/macros/config.h"
-#include <sys/ipc.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/sys/ipc/linux/CMakeLists.txt b/libc/src/sys/ipc/linux/CMakeLists.txt
index c2fdebcf989dc..526cdb7324e02 100644
--- a/libc/src/sys/ipc/linux/CMakeLists.txt
+++ b/libc/src/sys/ipc/linux/CMakeLists.txt
@@ -1,3 +1,15 @@
+add_header_library(
+  kernel_statx
+  HDRS
+    kernel_statx.h
+  DEPENDS
+    libc.hdr.fcntl_macros
+    libc.hdr.stdint_proxy
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+)
+
 add_entrypoint_object(
   ftok
   SRCS
@@ -5,6 +17,8 @@ add_entrypoint_object(
   HDRS
     ../ftok.h
   DEPENDS
-    libc.include.sys_ipc
-    libc.src.sys.stat.stat
+    .kernel_statx
+    libc.hdr.types.key_t
+    libc.src.__support.common
+    libc.src.errno.errno
 )
diff --git a/libc/src/sys/ipc/linux/ftok.cpp b/libc/src/sys/ipc/linux/ftok.cpp
index 6d0920c77ced3..5e2069a11f4d4 100644
--- a/libc/src/sys/ipc/linux/ftok.cpp
+++ b/libc/src/sys/ipc/linux/ftok.cpp
@@ -5,24 +5,27 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-
 #include "src/sys/ipc/ftok.h"
 
 #include "src/__support/common.h"
-#include "src/sys/stat/stat.h"
+#include "src/__support/libc_errno.h"
+
+#include "kernel_statx.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(key_t, ftok, (const char *path, int id)) {
-
-  // ftok implements based on stat
-  struct stat st;
-  if (LIBC_NAMESPACE::stat(path, &st) < 0)
+  ::statx_buf xbuf;
+  int err = statx_for_ftok(path, xbuf);
+  if (err != 0) {
+    libc_errno = err;
     return -1;
+  }
 
-  return static_cast<key_t>(((id & 0xff) << 24) |
-                            ((static_cast<int>(st.st_dev) & 0xff) << 16) |
-                            (static_cast<int>(st.st_ino) & 0xffff));
+  return static_cast<key_t>(
+      ((id & 0xff) << 24) |
+      ((static_cast<int>(xbuf.stx_dev_minor) & 0xff) << 16) |
+      (static_cast<int>(xbuf.stx_ino) & 0xffff));
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/ipc/linux/kernel_statx.h b/libc/src/sys/ipc/linux/kernel_statx.h
new file mode 100644
index 0000000000000..59346a307c8c2
--- /dev/null
+++ b/libc/src/sys/ipc/linux/kernel_statx.h
@@ -0,0 +1,80 @@
+//===-- Wrapper over SYS_statx syscall for ftok ---------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_IPC_LINUX_KERNEL_STATX_H
+#define LLVM_LIBC_SRC_SYS_IPC_LINUX_KERNEL_STATX_H
+
+#include "hdr/fcntl_macros.h"
+#include "hdr/stdint_proxy.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/common.h"
+#include "sys/syscall.h"
+
+// this namespace is copied from the sys/stat/linux/kernel_statx.cpp
+namespace {
+
+// The type definitions in the internal namespace match kernel's definition of
+// the statx_timestamp and statx types in linux/stat.h. We define equivalent
+// types here instead of including that header file to avoid name mixup between
+// linux/stat.h and the libc's stat.h.
+struct statx_timestamp {
+  int64_t tv_sec;
+  uint32_t tv_nsec;
+  int32_t __reserved;
+};
+
+struct statx_buf {
+  uint32_t stx_mask;       // What results were written
+  uint32_t stx_blksize;    // Preferred general I/O size
+  uint64_t stx_attributes; // Flags conveying information about the file
+  uint32_t stx_nlink;      // Number of hard links
+  uint32_t stx_uid;        // User ID of owner
+  uint32_t stx_gid;        // Group ID of owner
+  uint16_t stx_mode;       // File mode
+  uint16_t __spare0[1];
+  uint64_t stx_ino;                 // Inode number
+  uint64_t stx_size;                // File size
+  uint64_t stx_blocks;              // Number of 512-byte blocks allocated
+  uint64_t stx_attributes_mask;     // Mask to show what's supported in
+                                    // stx_attributes
+  struct statx_timestamp stx_atime; // Last access time
+  struct statx_timestamp stx_btime; // File creation time
+  struct statx_timestamp stx_ctime; // Last attribute change time
+  struct statx_timestamp stx_mtime; // Last data modification time
+  uint32_t stx_rdev_major;          // Device ID of special file
+  uint32_t stx_rdev_minor;
+  uint32_t stx_dev_major; // ID of device containing file
+  uint32_t stx_dev_minor;
+  uint64_t stx_mnt_id;
+  uint64_t __spare2;
+  uint64_t __spare3[12]; // Spare space for future expansion
+};
+
+// The below mask value is based on the definition of a similarly
+// named macro in linux/stat.h. When this flag is passed for the
+// mask argument to the statx syscall, all fields except the
+// stx_btime field will be filled in.
+constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF;
+
+} // Anonymous namespace
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE int statx_for_ftok(const char *path, ::statx_buf &xbuf) {
+
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_statx, AT_FDCWD, path, 0,
+                                              ::STATX_BASIC_STATS_MASK, &xbuf);
+
+  if (ret < 0)
+    return -ret;
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_IPC_LINUX_KERNEL_STATX_H

>From 63cb343c09b38be0f1da10ba0f5a45f530da0259 Mon Sep 17 00:00:00 2001
From: Pengxiang Huang <huangpengxiang70 at gmail.com>
Date: Fri, 27 Feb 2026 09:04:52 -0500
Subject: [PATCH 3/3] resolve reviewers comments

remove the statx required data structures; directly use those in linux uapi.

add comments for returned key_t layouts in ftok
---
 libc/src/sys/ipc/linux/CMakeLists.txt |  2 -
 libc/src/sys/ipc/linux/ftok.cpp       |  8 +++-
 libc/src/sys/ipc/linux/kernel_statx.h | 55 ++-------------------------
 3 files changed, 11 insertions(+), 54 deletions(-)

diff --git a/libc/src/sys/ipc/linux/CMakeLists.txt b/libc/src/sys/ipc/linux/CMakeLists.txt
index 526cdb7324e02..0a27e9b4665f8 100644
--- a/libc/src/sys/ipc/linux/CMakeLists.txt
+++ b/libc/src/sys/ipc/linux/CMakeLists.txt
@@ -4,10 +4,8 @@ add_header_library(
     kernel_statx.h
   DEPENDS
     libc.hdr.fcntl_macros
-    libc.hdr.stdint_proxy
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
-    libc.src.__support.common
 )
 
 add_entrypoint_object(
diff --git a/libc/src/sys/ipc/linux/ftok.cpp b/libc/src/sys/ipc/linux/ftok.cpp
index 5e2069a11f4d4..41c5aad0314d5 100644
--- a/libc/src/sys/ipc/linux/ftok.cpp
+++ b/libc/src/sys/ipc/linux/ftok.cpp
@@ -15,13 +15,19 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(key_t, ftok, (const char *path, int id)) {
-  ::statx_buf xbuf;
+  struct statx xbuf;
+
   int err = statx_for_ftok(path, xbuf);
+
   if (err != 0) {
     libc_errno = err;
     return -1;
   }
 
+  // key layout based on user input and file stats metadata
+  // 31            24              16             0
+  // +-------------+---------------+--------------+
+  // user input id + minor dev num + file inode num
   return static_cast<key_t>(
       ((id & 0xff) << 24) |
       ((static_cast<int>(xbuf.stx_dev_minor) & 0xff) << 16) |
diff --git a/libc/src/sys/ipc/linux/kernel_statx.h b/libc/src/sys/ipc/linux/kernel_statx.h
index 59346a307c8c2..3d6847a7b2e67 100644
--- a/libc/src/sys/ipc/linux/kernel_statx.h
+++ b/libc/src/sys/ipc/linux/kernel_statx.h
@@ -10,65 +10,18 @@
 #define LLVM_LIBC_SRC_SYS_IPC_LINUX_KERNEL_STATX_H
 
 #include "hdr/fcntl_macros.h"
-#include "hdr/stdint_proxy.h"
 #include "src/__support/OSUtil/syscall.h"
-#include "src/__support/common.h"
 #include "sys/syscall.h"
 
-// this namespace is copied from the sys/stat/linux/kernel_statx.cpp
-namespace {
-
-// The type definitions in the internal namespace match kernel's definition of
-// the statx_timestamp and statx types in linux/stat.h. We define equivalent
-// types here instead of including that header file to avoid name mixup between
-// linux/stat.h and the libc's stat.h.
-struct statx_timestamp {
-  int64_t tv_sec;
-  uint32_t tv_nsec;
-  int32_t __reserved;
-};
-
-struct statx_buf {
-  uint32_t stx_mask;       // What results were written
-  uint32_t stx_blksize;    // Preferred general I/O size
-  uint64_t stx_attributes; // Flags conveying information about the file
-  uint32_t stx_nlink;      // Number of hard links
-  uint32_t stx_uid;        // User ID of owner
-  uint32_t stx_gid;        // Group ID of owner
-  uint16_t stx_mode;       // File mode
-  uint16_t __spare0[1];
-  uint64_t stx_ino;                 // Inode number
-  uint64_t stx_size;                // File size
-  uint64_t stx_blocks;              // Number of 512-byte blocks allocated
-  uint64_t stx_attributes_mask;     // Mask to show what's supported in
-                                    // stx_attributes
-  struct statx_timestamp stx_atime; // Last access time
-  struct statx_timestamp stx_btime; // File creation time
-  struct statx_timestamp stx_ctime; // Last attribute change time
-  struct statx_timestamp stx_mtime; // Last data modification time
-  uint32_t stx_rdev_major;          // Device ID of special file
-  uint32_t stx_rdev_minor;
-  uint32_t stx_dev_major; // ID of device containing file
-  uint32_t stx_dev_minor;
-  uint64_t stx_mnt_id;
-  uint64_t __spare2;
-  uint64_t __spare3[12]; // Spare space for future expansion
-};
-
-// The below mask value is based on the definition of a similarly
-// named macro in linux/stat.h. When this flag is passed for the
-// mask argument to the statx syscall, all fields except the
-// stx_btime field will be filled in.
-constexpr unsigned int STATX_BASIC_STATS_MASK = 0x7FF;
-
-} // Anonymous namespace
+#include <linux/stat.h>
 
 namespace LIBC_NAMESPACE_DECL {
 
-LIBC_INLINE int statx_for_ftok(const char *path, ::statx_buf &xbuf) {
+LIBC_INLINE int statx_for_ftok(const char *path, struct statx &xbuf) {
 
+  // store the file stats metadata into xbuf
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_statx, AT_FDCWD, path, 0,
-                                              ::STATX_BASIC_STATS_MASK, &xbuf);
+                                              STATX_BASIC_STATS, &xbuf);
 
   if (ret < 0)
     return -ret;



More information about the libc-commits mailing list