[libc-commits] [libc] [libc] Implement killpg (Part of #236167) (PR #237561)

Anshitha Yeruva via libc-commits libc-commits at lists.llvm.org
Sat Oct 31 06:06:36 PDT 2026


https://github.com/anshithayeruva created https://github.com/llvm/llvm-project/pull/237561

This patch implements the POSIX `killpg` signal function in LLVM libc, along with unit tests.

Part of #236167.

>From 2ec131f7f769d35af9eec49dcfd6b9abcd17e9a4 Mon Sep 17 00:00:00 2001
From: anshithayeruva <anshithayeruva18 at gmail.com>
Date: Sat, 31 Oct 2026 18:32:49 +0530
Subject: [PATCH] [libc] Implement killpg (Part of #236167)

---
 libc/config/linux/aarch64/entrypoints.txt |  1 +
 libc/config/linux/riscv/entrypoints.txt   |  1 +
 libc/config/linux/x86_64/entrypoints.txt  |  1 +
 libc/include/signal.yaml                  |  7 +++++
 libc/src/signal/CMakeLists.txt            |  8 ++++--
 libc/src/signal/killpg.h                  | 21 ++++++++++++++
 libc/src/signal/linux/CMakeLists.txt      | 13 ++++++++-
 libc/src/signal/linux/killpg.cpp          | 25 +++++++++++++++++
 libc/test/src/signal/CMakeLists.txt       | 15 +++++++++-
 libc/test/src/signal/killpg_test.cpp      | 34 +++++++++++++++++++++++
 10 files changed, 122 insertions(+), 4 deletions(-)
 create mode 100644 libc/src/signal/killpg.h
 create mode 100644 libc/src/signal/linux/killpg.cpp
 create mode 100644 libc/test/src/signal/killpg_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 09b1b9080e0874..c2eace9c4d1b9a 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1383,6 +1383,7 @@ if(LLVM_LIBC_FULL_BUILD)
 
     # signal.h entrypoints
     libc.src.signal.kill
+    libc.src.signal.killpg
     libc.src.signal.pthread_kill
     libc.src.signal.pthread_sigmask
     libc.src.signal.raise
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 69189b37ddddd4..4effdc6eca3a1c 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1569,6 +1569,7 @@ if(LLVM_LIBC_FULL_BUILD)
 
     # signal.h entrypoints
     libc.src.signal.kill
+    libc.src.signal.killpg
     libc.src.signal.pthread_kill
     libc.src.signal.pthread_sigmask
     libc.src.signal.raise
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 746e712ec160e6..e31335cf0fe230 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1595,6 +1595,7 @@ if(LLVM_LIBC_FULL_BUILD)
 
     # signal.h entrypoints
     libc.src.signal.kill
+    libc.src.signal.killpg
     libc.src.signal.pthread_kill
     libc.src.signal.pthread_sigmask
     libc.src.signal.raise
diff --git a/libc/include/signal.yaml b/libc/include/signal.yaml
index b763da7eeb6025..1ec7c244c2dadf 100644
--- a/libc/include/signal.yaml
+++ b/libc/include/signal.yaml
@@ -57,6 +57,13 @@ functions:
     arguments:
       - type: pid_t
       - type: int
+  - name: killpg 
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: pid_t
+      - type: int 
   - name: raise
     standards:
       - stdc
diff --git a/libc/src/signal/CMakeLists.txt b/libc/src/signal/CMakeLists.txt
index 8da94d1eea85fd..fd375468f039ab 100644
--- a/libc/src/signal/CMakeLists.txt
+++ b/libc/src/signal/CMakeLists.txt
@@ -15,14 +15,18 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.kill
 )
-
+add_entrypoint_object(
+  killpg
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.killpg
+)
 add_entrypoint_object(
   sigaction
   ALIAS
   DEPENDS
     .${LIBC_TARGET_OS}.sigaction
 )
-
 add_entrypoint_object(
   sigaltstack
   ALIAS
diff --git a/libc/src/signal/killpg.h b/libc/src/signal/killpg.h
new file mode 100644
index 00000000000000..36ca6265bb3322
--- /dev/null
+++ b/libc/src/signal/killpg.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for killpg function ---------------*- 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_SIGNAL_KILLPG_H
+#define LLVM_LIBC_SRC_SIGNAL_KILLPG_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int killpg(pid_t pgrp, int sig);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SIGNAL_KILLPG_H
\ No newline at end of file
diff --git a/libc/src/signal/linux/CMakeLists.txt b/libc/src/signal/linux/CMakeLists.txt
index 77898cf9aab636..aafd15f897a921 100644
--- a/libc/src/signal/linux/CMakeLists.txt
+++ b/libc/src/signal/linux/CMakeLists.txt
@@ -27,7 +27,18 @@ add_entrypoint_object(
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
 )
-
+add_entrypoint_object(
+  killpg 
+  SRCS 
+    killpg.cpp
+  HDRS
+    ../killpg.h
+  DEPENDS 
+    libc.hdr.errno_macros
+    libc.hdr.types.pid_t
+    libc.src.errno.errno
+    libc.src.signal.kill
+)
 add_entrypoint_object(
   raise
   SRCS
diff --git a/libc/src/signal/linux/killpg.cpp b/libc/src/signal/linux/killpg.cpp
new file mode 100644
index 00000000000000..e2bcae56d26f7e
--- /dev/null
+++ b/libc/src/signal/linux/killpg.cpp
@@ -0,0 +1,25 @@
+//===-- Linux implementation of killpg ------------------------------------===//
+//
+// 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/signal/killpg.h"
+
+#include "hdr/errno_macros.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/signal/kill.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(int, killpg, (pid_t pgrp, int sig)) {
+    if(pgrp < 0) {
+        libc_errno = EINVAL;
+        return -1;
+    }
+    return LIBC_NAMESPACE::kill(-pgrp, sig);
+ } 
+} //namespace LIBC_NAMESPACE_DECL
\ No newline at end of file
diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt
index 287977e2762236..2b3cb8fd4eb9b4 100644
--- a/libc/test/src/signal/CMakeLists.txt
+++ b/libc/test/src/signal/CMakeLists.txt
@@ -24,7 +24,20 @@ add_libc_test(
     libc.src.__support.OSUtil.osutil
     libc.test.UnitTest.ErrnoSetterMatcher
 )
-
+add_libc_test(
+  killpg_test
+  SUITE 
+    libc-signal-tests
+  SRCS 
+    killpg_test.cpp
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.signal_macros
+    libc.src.signal.killpg
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
 add_libc_test(
   sigaction_test
   SUITE
diff --git a/libc/test/src/signal/killpg_test.cpp b/libc/test/src/signal/killpg_test.cpp
new file mode 100644
index 00000000000000..61535f81c45890
--- /dev/null
+++ b/libc/test/src/signal/killpg_test.cpp
@@ -0,0 +1,34 @@
+//===-- Unittests for killpg ----------------------------------------------===//
+//
+// 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/signal/killpg.h"
+
+#include "hdr/errno_macros.h"
+#include "hdr/signal_macros.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <sys/syscall.h>
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+TEST(LlvmLibcKillpgTest, InvalidPgrp) {
+  // Negative process group ID must fail with EINVAL.
+  ASSERT_THAT(LIBC_NAMESPACE::killpg(-1, 0), Fails(EINVAL));
+}
+
+TEST(LlvmLibcKillpgTest, TargetSelf) {
+  // pgrp = 0 represents the caller's process group.
+  ASSERT_THAT(LIBC_NAMESPACE::killpg(0, 0), Succeeds(0));
+
+  // Sending signal 0 to our own process group should succeed.
+  pid_t pgrp = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_getpgrp);
+  ASSERT_THAT(LIBC_NAMESPACE::killpg(pgrp, 0), Succeeds(0));
+}
\ No newline at end of file



More information about the libc-commits mailing list