[libc-commits] [libc] db5421a - [libc] Implement umask (#222499)

via libc-commits libc-commits at lists.llvm.org
Thu Sep 10 12:51:57 PDT 2026


Author: ThePo1es
Date: 2026-09-10T12:51:51-07:00
New Revision: db5421adfa1d8984bf0015ded33d12f9bbfbe80f

URL: https://github.com/llvm/llvm-project/commit/db5421adfa1d8984bf0015ded33d12f9bbfbe80f
DIFF: https://github.com/llvm/llvm-project/commit/db5421adfa1d8984bf0015ded33d12f9bbfbe80f.diff

LOG: [libc] Implement umask (#222499)

Implement the POSIX umask() entrypoint for Linux and register it for
aarch64, riscv and x86_64. umask cannot fail, so the syscall wrapper
returns mode_t directly and the entrypoint does not touch errno.

Fixes #220759

Assisted-by: Claude Code

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply at anthropic.com>

Added: 
    libc/src/__support/OSUtil/linux/syscall_wrappers/umask.h
    libc/src/sys/stat/linux/umask.cpp
    libc/src/sys/stat/umask.h
    libc/test/src/sys/stat/umask_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/riscv/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/sys/stat.yaml
    libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
    libc/src/sys/stat/CMakeLists.txt
    libc/src/sys/stat/linux/CMakeLists.txt
    libc/test/src/sys/stat/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 77610d6d06057..57210e3c79208 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -350,6 +350,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.mkdir
     libc.src.sys.stat.mkdirat
     libc.src.sys.stat.stat
+    libc.src.sys.stat.umask
     libc.src.sys.stat.utimensat
 
     # sys/statfs.h entrypoints

diff  --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 71a4d4f5ec5c4..ff3500e272d82 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -381,6 +381,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.mkdir
     libc.src.sys.stat.mkdirat
     libc.src.sys.stat.stat
+    libc.src.sys.stat.umask
     libc.src.sys.stat.utimensat
 
     # sys/statfs.h entrypoints

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 65b820e551be6..0175b97b326d4 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -386,6 +386,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.stat.mkdir
     libc.src.sys.stat.mkdirat
     libc.src.sys.stat.stat
+    libc.src.sys.stat.umask
     libc.src.sys.stat.utimensat
 
     # sys/statfs.h entrypoints

diff  --git a/libc/include/sys/stat.yaml b/libc/include/sys/stat.yaml
index 6c4fc8c5d93e0..b12e2ac620a4f 100644
--- a/libc/include/sys/stat.yaml
+++ b/libc/include/sys/stat.yaml
@@ -63,6 +63,10 @@ functions:
     arguments:
       - type: const char *__restrict
       - type: struct stat *__restrict
+  - name: umask
+    return_type: mode_t
+    arguments:
+      - type: mode_t
   - name: utimensat
     return_type: int
     arguments:

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 9512528e9e5e2..9c1690f7a27cf 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -1251,3 +1251,15 @@ add_header_library(
     libc.src.__support.macros.config
     libc.include.sys_syscall
 )
+
+add_header_library(
+  umask
+  HDRS
+    umask.h
+  DEPENDS
+    libc.hdr.types.mode_t
+    libc.include.sys_syscall
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.OSUtil.osutil
+)

diff  --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/umask.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/umask.h
new file mode 100644
index 0000000000000..9544d5b340a52
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/umask.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Syscall wrapper for umask.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UMASK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UMASK_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE mode_t umask(mode_t cmask) {
+  // umask is expected to always succeed, thus no error checking here.
+  return syscall_impl<mode_t>(SYS_umask, cmask);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_UMASK_H

diff  --git a/libc/src/sys/stat/CMakeLists.txt b/libc/src/sys/stat/CMakeLists.txt
index c873814a6f9f0..7338fac02bc29 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}.stat
 )
 
+add_entrypoint_object(
+  umask
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.umask
+)
+
 add_entrypoint_object(
   utimensat
   ALIAS

diff  --git a/libc/src/sys/stat/linux/CMakeLists.txt b/libc/src/sys/stat/linux/CMakeLists.txt
index 152a34946ae4f..52ae4566a2b87 100644
--- a/libc/src/sys/stat/linux/CMakeLists.txt
+++ b/libc/src/sys/stat/linux/CMakeLists.txt
@@ -127,3 +127,15 @@ add_entrypoint_object(
     libc.src.__support.common
     libc.src.errno.errno
 )
+
+add_entrypoint_object(
+  umask
+  SRCS
+    umask.cpp
+  HDRS
+    ../umask.h
+  DEPENDS
+    libc.hdr.types.mode_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.umask
+    libc.src.__support.common
+)

diff  --git a/libc/src/sys/stat/linux/umask.cpp b/libc/src/sys/stat/linux/umask.cpp
new file mode 100644
index 0000000000000..c68a745fb9da9
--- /dev/null
+++ b/libc/src/sys/stat/linux/umask.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// ile
+/// Linux implementation of umask.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/stat/umask.h"
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/umask.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(mode_t, umask, (mode_t cmask)) {
+  return linux_syscalls::umask(cmask);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/sys/stat/umask.h b/libc/src/sys/stat/umask.h
new file mode 100644
index 0000000000000..4d32d23d24400
--- /dev/null
+++ b/libc/src/sys/stat/umask.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
+//
+//===----------------------------------------------------------------------===//
+///
+/// ile
+/// Implementation header for umask.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_STAT_UMASK_H
+#define LLVM_LIBC_SRC_SYS_STAT_UMASK_H
+
+#include "hdr/types/mode_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+mode_t umask(mode_t cmask);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_STAT_UMASK_H

diff  --git a/libc/test/src/sys/stat/CMakeLists.txt b/libc/test/src/sys/stat/CMakeLists.txt
index 85568f4b8d049..3e87a11b05e6e 100644
--- a/libc/test/src/sys/stat/CMakeLists.txt
+++ b/libc/test/src/sys/stat/CMakeLists.txt
@@ -176,3 +176,17 @@ add_libc_test(
     libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
+
+add_libc_test(
+  umask_test
+  SUITE
+    libc_sys_stat_unittests
+  SRCS
+    umask_test.cpp
+  DEPENDS
+    libc.hdr.sys_stat_macros
+    libc.hdr.types.mode_t
+    libc.src.errno.errno
+    libc.src.sys.stat.umask
+    libc.test.UnitTest.ErrnoCheckingTest
+)

diff  --git a/libc/test/src/sys/stat/umask_test.cpp b/libc/test/src/sys/stat/umask_test.cpp
new file mode 100644
index 0000000000000..c7145689203d8
--- /dev/null
+++ b/libc/test/src/sys/stat/umask_test.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Unittests for umask.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/sys_stat_macros.h"
+#include "hdr/types/mode_t.h"
+#include "src/sys/stat/umask.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcUmaskTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcUmaskTest, SmokeTest) {
+  // umask() always succeeds and returns the previous mask. Set a mask, then
+  // restore the original one and check that the mask we set is handed back.
+  mode_t old_mask = LIBC_NAMESPACE::umask(S_IRWXG | S_IRWXO);
+  EXPECT_EQ(LIBC_NAMESPACE::umask(old_mask),
+            static_cast<mode_t>(S_IRWXG | S_IRWXO));
+}


        


More information about the libc-commits mailing list