[libc-commits] [libc] [libc] Implement sigtimedwait and sigwaitinfo in signal (PR #238000)

via libc-commits libc-commits at lists.llvm.org
Mon Nov 2 06:48:53 PST 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Leo Garcia (leogarci42)

<details>
<summary>Changes</summary>

Add the standard POSIX function sigtimedwait and sigwaitinfo to <signal.h>:

- Add low-level rt_sigtimedwait system call wrapper in libc/src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.h.
- Add public header declaration in libc/src/signal/sigtimedwait.h.
- Implement sigtimedwait entrypoint in libc/src/signal/linux/sigtimedwait.cpp.
- Add public header declaration in libc/src/signal/sigwaitinfo.h.
- Implement sigwaitinfo entrypoint in libc/src/signal/linux/sigwaitinfo.cpp using rt_sigtimedwait with a null timeout.
- Declare sigtimedwait and sigwaitinfo in libc/include/signal.yaml.
- Register both entrypoints for Linux (x86_64, aarch64, riscv) in architecture config files.
- Update CMakeLists.txt files across syscall wrappers, signal sources, and tests.
- Add unit tests in libc/test/src/signal/sigtimedwait_test.cpp and libc/test/src/signal/sigwaitinfo_test.cpp.

Part of #<!-- -->236167


---

Patch is 22.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/238000.diff


16 Files Affected:

- (modified) libc/config/linux/aarch64/entrypoints.txt (+2) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+2) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+2) 
- (modified) libc/include/signal.yaml (+16) 
- (modified) libc/include/sys/syscall.h.def (+4) 
- (modified) libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt (+15) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.h (+54) 
- (modified) libc/src/signal/CMakeLists.txt (+14) 
- (modified) libc/src/signal/linux/CMakeLists.txt (+27) 
- (added) libc/src/signal/linux/sigtimedwait.cpp (+37) 
- (added) libc/src/signal/linux/sigwaitinfo.cpp (+36) 
- (added) libc/src/signal/sigtimedwait.h (+29) 
- (added) libc/src/signal/sigwaitinfo.h (+27) 
- (modified) libc/test/src/signal/CMakeLists.txt (+45) 
- (added) libc/test/src/signal/sigtimedwait_test.cpp (+126) 
- (added) libc/test/src/signal/sigwaitinfo_test.cpp (+91) 


``````````diff
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b45313f5068bd0..55713606b198dd 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1402,6 +1402,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.signal.sigismember
     libc.src.signal.signal
     libc.src.signal.sigprocmask
+    libc.src.signal.sigtimedwait
+    libc.src.signal.sigwaitinfo
 
     # spawn.h entrypoints
     libc.src.spawn.posix_spawn
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 3b42f020cf750e..51803a59abdc97 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1588,6 +1588,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.signal.sigismember
     libc.src.signal.signal
     libc.src.signal.sigprocmask
+    libc.src.signal.sigtimedwait
+    libc.src.signal.sigwaitinfo
 
     # spawn.h entrypoints
     libc.src.spawn.posix_spawn
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0ec5d8f73a8a4d..b14d6369e1d4e7 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1614,6 +1614,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.signal.sigismember
     libc.src.signal.signal
     libc.src.signal.sigprocmask
+    libc.src.signal.sigtimedwait
+    libc.src.signal.sigwaitinfo
 
     # spawn.h entrypoints
     libc.src.spawn.posix_spawn
diff --git a/libc/include/signal.yaml b/libc/include/signal.yaml
index b763da7eeb6025..76b36808979b27 100644
--- a/libc/include/signal.yaml
+++ b/libc/include/signal.yaml
@@ -43,6 +43,7 @@ types:
   - type_name: stack_t
   - type_name: struct_sigaction
   - type_name: struct_sigevent
+  - type_name: struct_timespec
   - type_name: union_sigval
   - type_name: pthread_t
     standards:
@@ -127,6 +128,21 @@ functions:
       - type: int
       - type: const sigset_t *__restrict
       - type: sigset_t *__restrict
+  - name: sigtimedwait
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: const sigset_t *__restrict
+      - type: siginfo_t *__restrict
+      - type: const struct timespec *__restrict
+  - name: sigwaitinfo
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: const sigset_t *__restrict
+      - type: siginfo_t *__restrict
   - name: pthread_sigmask
     standards:
       - posix
diff --git a/libc/include/sys/syscall.h.def b/libc/include/sys/syscall.h.def
index f3670a234c638f..5dce9077ddd6f4 100644
--- a/libc/include/sys/syscall.h.def
+++ b/libc/include/sys/syscall.h.def
@@ -1717,6 +1717,10 @@
 #define SYS_rt_sigtimedwait __NR_rt_sigtimedwait
 #endif
 
+#ifdef __NR_rt_sigtimedwait_time64
+#define SYS_rt_sigtimedwait_time64 __NR_rt_sigtimedwait_time64
+#endif
+
 #ifdef __NR_rt_tgsigqueueinfo
 #define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
 #endif
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 117191eecb042f..bf2bb39de5637c 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -648,6 +648,21 @@ add_header_library(
     libc.include.sys_syscall
 )
 
+add_header_library(
+  rt_sigtimedwait
+  HDRS
+    rt_sigtimedwait.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.siginfo_t
+    libc.hdr.types.sigset_t
+    libc.hdr.types.struct_timespec
+    libc.include.sys_syscall
+)
+
 add_header_library(
   raise
   HDRS
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.h
new file mode 100644
index 00000000000000..c5a45571d50d91
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.h
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 rt_sigtimedwait.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RT_SIGTIMEDWAIT_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RT_SIGTIMEDWAIT_H
+
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> rt_sigtimedwait(const sigset_t *set, siginfo_t *info,
+                                         const struct timespec *timeout) {
+#if defined(SYS_rt_sigtimedwait_time64)
+  static_assert(
+      sizeof(time_t) == sizeof(int64_t),
+      "SYS_rt_sigtimedwait_time64 requires struct timespec with 64-bit "
+      "members.");
+  return syscall_checked<int>(SYS_rt_sigtimedwait_time64, set, info, timeout,
+                              sizeof(sigset_t));
+#elif defined(SYS_rt_sigtimedwait)
+  static_assert(
+      sizeof(timespec::tv_nsec) == sizeof(long),
+      "This legacy syscall fallback is only safe on platforms where tv_nsec "
+      "matches the register size (long). It is unsafe on 32-bit platforms "
+      "with 64-bit tv_nsec.");
+  return syscall_checked<int>(SYS_rt_sigtimedwait, set, info, timeout,
+                              sizeof(sigset_t));
+#else
+#error "rt_sigtimedwait and rt_sigtimedwait_time64 syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RT_SIGTIMEDWAIT_H
diff --git a/libc/src/signal/CMakeLists.txt b/libc/src/signal/CMakeLists.txt
index 8da94d1eea85fd..db22d042551bfa 100644
--- a/libc/src/signal/CMakeLists.txt
+++ b/libc/src/signal/CMakeLists.txt
@@ -37,6 +37,20 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.sigprocmask
 )
 
+add_entrypoint_object(
+  sigtimedwait
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.sigtimedwait
+)
+
+add_entrypoint_object(
+  sigwaitinfo
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.sigwaitinfo
+)
+
 add_entrypoint_object(
   pthread_sigmask
   ALIAS
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index 77898cf9aab636..17a1bda355c61b 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -95,6 +95,33 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  sigtimedwait
+  SRCS
+    sigtimedwait.cpp
+  HDRS
+    ../sigtimedwait.h
+  DEPENDS
+    libc.hdr.types.siginfo_t
+    libc.hdr.types.sigset_t
+    libc.hdr.types.struct_timespec
+    libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigtimedwait
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  sigwaitinfo
+  SRCS
+    sigwaitinfo.cpp
+  HDRS
+    ../sigwaitinfo.h
+  DEPENDS
+    libc.hdr.types.siginfo_t
+    libc.hdr.types.sigset_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.rt_sigtimedwait
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   pthread_sigmask
   SRCS
diff --git a/libc/src/signal/linux/sigtimedwait.cpp b/libc/src/signal/linux/sigtimedwait.cpp
new file mode 100644
index 00000000000000..bb48cf75632567
--- /dev/null
+++ b/libc/src/signal/linux/sigtimedwait.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sigtimedwait.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/signal/sigtimedwait.h"
+
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.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, sigtimedwait,
+                   (const sigset_t *__restrict set, siginfo_t *__restrict info,
+                    const struct timespec *__restrict timeout)) {
+  auto result = linux_syscalls::rt_sigtimedwait(set, info, timeout);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/linux/sigwaitinfo.cpp b/libc/src/signal/linux/sigwaitinfo.cpp
new file mode 100644
index 00000000000000..11b14170f348ad
--- /dev/null
+++ b/libc/src/signal/linux/sigwaitinfo.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sigwaitinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/signal/sigwaitinfo.h"
+
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/rt_sigtimedwait.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, sigwaitinfo,
+                   (const sigset_t *__restrict set,
+                    siginfo_t *__restrict info)) {
+  auto result = linux_syscalls::rt_sigtimedwait(set, info, nullptr);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/sigtimedwait.h b/libc/src/signal/sigtimedwait.h
new file mode 100644
index 00000000000000..d926b044c084ba
--- /dev/null
+++ b/libc/src/signal/sigtimedwait.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sigtimedwait.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SIGNAL_SIGTIMEDWAIT_H
+#define LLVM_LIBC_SRC_SIGNAL_SIGTIMEDWAIT_H
+
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int sigtimedwait(const sigset_t *__restrict set, siginfo_t *__restrict info,
+                 const struct timespec *__restrict timeout);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SIGNAL_SIGTIMEDWAIT_H
diff --git a/libc/src/signal/sigwaitinfo.h b/libc/src/signal/sigwaitinfo.h
new file mode 100644
index 00000000000000..585f81190a77a4
--- /dev/null
+++ b/libc/src/signal/sigwaitinfo.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sigwaitinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SIGNAL_SIGWAITINFO_H
+#define LLVM_LIBC_SRC_SIGNAL_SIGWAITINFO_H
+
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int sigwaitinfo(const sigset_t *__restrict set, siginfo_t *__restrict info);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SIGNAL_SIGWAITINFO_H
diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt
index 287977e2762236..4ebdeccad83b1a 100644
--- a/libc/test/src/signal/CMakeLists.txt
+++ b/libc/test/src/signal/CMakeLists.txt
@@ -54,6 +54,51 @@ add_libc_test(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
+add_libc_test(
+  sigtimedwait_test
+  SUITE
+    libc-signal-tests
+  SRCS
+    sigtimedwait_test.cpp
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.signal_macros
+    libc.hdr.types.siginfo_t
+    libc.hdr.types.sigset_t
+    libc.hdr.types.struct_sigaction
+    libc.hdr.types.struct_timespec
+    libc.src.signal.raise
+    libc.src.signal.sigaction
+    libc.src.signal.sigaddset
+    libc.src.signal.sigemptyset
+    libc.src.signal.sigprocmask
+    libc.src.signal.sigtimedwait
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
+add_libc_test(
+  sigwaitinfo_test
+  SUITE
+    libc-signal-tests
+  SRCS
+    sigwaitinfo_test.cpp
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.signal_macros
+    libc.hdr.types.siginfo_t
+    libc.hdr.types.sigset_t
+    libc.hdr.types.struct_sigaction
+    libc.src.signal.raise
+    libc.src.signal.sigaction
+    libc.src.signal.sigaddset
+    libc.src.signal.sigemptyset
+    libc.src.signal.sigprocmask
+    libc.src.signal.sigwaitinfo
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
 add_libc_test(
   pthread_sigmask_test
   SUITE
diff --git a/libc/test/src/signal/sigtimedwait_test.cpp b/libc/test/src/signal/sigtimedwait_test.cpp
new file mode 100644
index 00000000000000..9375582a65bc81
--- /dev/null
+++ b/libc/test/src/signal/sigtimedwait_test.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sigtimedwait.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/signal_macros.h"
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "hdr/types/struct_sigaction.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/signal/raise.h"
+#include "src/signal/sigaction.h"
+#include "src/signal/sigaddset.h"
+#include "src/signal/sigemptyset.h"
+#include "src/signal/sigprocmask.h"
+#include "src/signal/sigtimedwait.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+static void test_sig_handler(int) {}
+
+class LlvmLibcSigtimedwaitTest
+    : public LIBC_NAMESPACE::testing::ErrnoCheckingTest {
+  struct sigaction old_action{};
+  sigset_t old_mask{};
+
+public:
+  void SetUp() override {
+    ErrnoCheckingTest::SetUp();
+    ASSERT_THAT(LIBC_NAMESPACE::sigprocmask(0, nullptr, &old_mask), Succeeds());
+
+    struct sigaction sa{};
+    sa.sa_handler = test_sig_handler;
+    ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&sa.sa_mask), Succeeds());
+    sa.sa_flags = 0;
+    ASSERT_THAT(LIBC_NAMESPACE::sigaction(SIGUSR1, &sa, &old_action),
+                Succeeds());
+
+    sigset_t blocked;
+    ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&blocked), Succeeds());
+    ASSERT_THAT(LIBC_NAMESPACE::sigaddset(&blocked, SIGUSR1), Succeeds());
+    ASSERT_THAT(LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &blocked, nullptr),
+                Succeeds());
+  }
+
+  void TearDown() override {
+    LIBC_NAMESPACE::sigprocmask(SIG_SETMASK, &old_mask, nullptr);
+    LIBC_NAMESPACE::sigaction(SIGUSR1, &old_action, nullptr);
+    ErrnoCheckingTest::TearDown();
+  }
+};
+
+// This tests that a pending signal is returned along with its info.
+TEST_F(LlvmLibcSigtimedwaitTest, PendingSignalReturnsSignalAndInfo) {
+  sigset_t set;
+  ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&set), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::sigaddset(&set, SIGUSR1), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::raise(SIGUSR1), Succeeds());
+
+  struct timespec timeout{0, 0};
+  siginfo_t info{};
+  ASSERT_THAT(LIBC_NAMESPACE::sigtimedwait(&set, &info, &timeout),
+              Succeeds(SIGUSR1));
+  EXPECT_EQ(info.si_signo, SIGUSR1);
+
+  EXPECT_THAT(LIBC_NAMESPACE::sigtimedwait(&set, nullptr, &timeout),
+              Fails(EAGAIN));
+}
+
+// This tests that a null info pointer is allowed.
+TEST_F(LlvmLibcSigtimedwaitTest, NullInfo) {
+  sigset_t set;
+  ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&set), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::sigaddset(&set, SIGUSR1), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::raise(SIGUSR1), Succeeds());
+
+  struct timespec timeout{0, 0};
+  ASSERT_THAT(LIBC_NAMESPACE::sigtimedwait(&set, nullptr, &timeout),
+              Succeeds(SIGUSR1));
+}
+
+// This tests that a null timeout waits until a pending signal arrives.
+TEST_F(LlvmLibcSigtimedwaitTest, NullTimeoutWithPendingSignal) {
+  sigset_t set;
+  ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&set), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::sigaddset(&set, SIGUSR1), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::raise(SIGUSR1), Succeeds());
+
+  siginfo_t info{};
+  ASSERT_THAT(LIBC_NAMESPACE::sigtimedwait(&set, &info, nullptr),
+              Succeeds(SIGUSR1));
+  EXPECT_EQ(info.si_signo, SIGUSR1);
+}
+
+// This tests that no pending signal with a zero timeout returns EAGAIN.
+TEST_F(LlvmLibcSigtimedwaitTest, NoPendingSignalTimesOut) {
+  sigset_t set;
+  ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&set), Succeeds());
+
+  struct timespec timeout{0, 0};
+  EXPECT_THAT(LIBC_NAMESPACE::sigtimedwait(&set, nullptr, &timeout),
+              Fails(EAGAIN));
+}
+
+// This tests that an invalid timeout returns EINVAL.
+TEST_F(LlvmLibcSigtimedwaitTest, InvalidTimeout) {
+  sigset_t set;
+  ASSERT_THAT(LIBC_NAMESPACE::sigemptyset(&set), Succeeds());
+
+  struct timespec timeout{0, 1000000000L};
+  EXPECT_THAT(LIBC_NAMESPACE::sigtimedwait(&set, nullptr, &timeout),
+              Fails(EINVAL));
+}
diff --git a/libc/test/src/signal/sigwaitinfo_test.cpp b/libc/test/src/signal/sigwaitinfo_test.cpp
new file mode 100644
index 00000000000000..86be0da3d9fe49
--- /dev/null
+++ b/libc/test/src/signal/sigwaitinfo_test.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sigwaitinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/signal_macros.h"
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/sigset_t.h"
+#include "hdr/types/struct_sigaction.h"
+#include "src/signal/raise.h"
+#include "src/signal/sigaction.h"
+#include "src/signal/sigaddset.h"
+#include "src/signal/sigemptyset.h"
+#include "src/signal/sigprocmask.h"
+#include "src/signal/s...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/238000


More information about the libc-commits mailing list