[libc-commits] [libc] [libc] Add <unistd.h> functions for managing foreground process group IDs (PR #220121)

Alexey Samsonov via libc-commits libc-commits at lists.llvm.org
Tue Sep 1 10:49:25 PDT 2026


https://github.com/vonosmas updated https://github.com/llvm/llvm-project/pull/220121

>From 9e7ad8ad7f0e0271469a380b4a262edc1afdb230 Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Mon, 31 Aug 2026 22:07:59 +0000
Subject: [PATCH 1/2] [libc] Add <unistd.h> functions for foreground process
 group IDs associated with termimals>

---
 libc/config/linux/aarch64/entrypoints.txt |  2 +
 libc/config/linux/arm/entrypoints.txt     |  2 +
 libc/config/linux/riscv/entrypoints.txt   |  2 +
 libc/config/linux/x86_64/entrypoints.txt  |  2 +
 libc/include/unistd.yaml                  | 13 +++++++
 libc/src/unistd/CMakeLists.txt            | 14 +++++++
 libc/src/unistd/linux/CMakeLists.txt      | 26 +++++++++++++
 libc/src/unistd/linux/tcgetpgrp.cpp       | 35 ++++++++++++++++++
 libc/src/unistd/linux/tcsetpgrp.cpp       | 34 +++++++++++++++++
 libc/src/unistd/tcgetpgrp.h               | 26 +++++++++++++
 libc/src/unistd/tcsetpgrp.h               | 26 +++++++++++++
 libc/test/src/unistd/CMakeLists.txt       | 34 +++++++++++++++++
 libc/test/src/unistd/tcgetpgrp_test.cpp   | 45 +++++++++++++++++++++++
 libc/test/src/unistd/tcsetpgrp_test.cpp   | 45 +++++++++++++++++++++++
 14 files changed, 306 insertions(+)
 create mode 100644 libc/src/unistd/linux/tcgetpgrp.cpp
 create mode 100644 libc/src/unistd/linux/tcsetpgrp.cpp
 create mode 100644 libc/src/unistd/tcgetpgrp.h
 create mode 100644 libc/src/unistd/tcsetpgrp.h
 create mode 100644 libc/test/src/unistd/tcgetpgrp_test.cpp
 create mode 100644 libc/test/src/unistd/tcsetpgrp_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 0c810752c06d7..13ccaac2d7ecd 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -435,6 +435,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.symlink
     libc.src.unistd.symlinkat
     libc.src.unistd.sysconf
+    libc.src.unistd.tcgetpgrp
+    libc.src.unistd.tcsetpgrp
     libc.src.unistd.truncate
     libc.src.unistd.unlink
     libc.src.unistd.unlinkat
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index d853ec0f13678..e18f18e141d23 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -264,6 +264,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.symlink
     libc.src.unistd.symlinkat
     libc.src.unistd.sysconf
+    libc.src.unistd.tcgetpgrp
+    libc.src.unistd.tcsetpgrp
     libc.src.unistd.truncate
     libc.src.unistd.unlink
     libc.src.unistd.unlinkat
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 842dc0e48cf23..19f63740bd3ff 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -465,6 +465,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.symlink
     libc.src.unistd.symlinkat
     libc.src.unistd.sysconf
+    libc.src.unistd.tcgetpgrp
+    libc.src.unistd.tcsetpgrp
     libc.src.unistd.truncate
     libc.src.unistd.unlink
     libc.src.unistd.unlinkat
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 7a2dc6a4283b0..11c15c88482dc 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -474,6 +474,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.symlink
     libc.src.unistd.symlinkat
     libc.src.unistd.sysconf
+    libc.src.unistd.tcgetpgrp
+    libc.src.unistd.tcsetpgrp
     libc.src.unistd.truncate
     libc.src.unistd.unlink
     libc.src.unistd.unlinkat
diff --git a/libc/include/unistd.yaml b/libc/include/unistd.yaml
index d6c0235dd830f..b243e1e935fe0 100644
--- a/libc/include/unistd.yaml
+++ b/libc/include/unistd.yaml
@@ -430,6 +430,19 @@ functions:
     return_type: long
     arguments:
       - type: int
+  - name: tcgetpgrp
+    standards:
+      - posix
+    return_type: pid_t
+    arguments:
+      - type: int
+  - name: tcsetpgrp
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: int
+      - type: pid_t
   - name: truncate
     standards:
       - posix
diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 1bcc0f58892bb..ef9554470ab14 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -357,6 +357,20 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.sysconf
 )
 
+add_entrypoint_object(
+  tcgetpgrp
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.tcgetpgrp
+)
+
+add_entrypoint_object(
+  tcsetpgrp
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.tcsetpgrp
+)
+
 add_entrypoint_object(
   truncate
   ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 80c4b6e8fd1c8..e671ebfd69200 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -627,6 +627,32 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.linux.syscall_wrappers.sysinfo
 )
 
+add_entrypoint_object(
+  tcgetpgrp
+  SRCS
+    tcgetpgrp.cpp
+  HDRS
+    ../tcgetpgrp.h
+  DEPENDS
+    libc.hdr.sys_ioctl_macros
+    libc.hdr.types.pid_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  tcsetpgrp
+  SRCS
+    tcsetpgrp.cpp
+  HDRS
+    ../tcsetpgrp.h
+  DEPENDS
+    libc.hdr.sys_ioctl_macros
+    libc.hdr.types.pid_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   truncate
   SRCS
diff --git a/libc/src/unistd/linux/tcgetpgrp.cpp b/libc/src/unistd/linux/tcgetpgrp.cpp
new file mode 100644
index 0000000000000..b637d5ccdd440
--- /dev/null
+++ b/libc/src/unistd/linux/tcgetpgrp.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 tcgetpgrp.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/tcgetpgrp.h"
+
+#include "hdr/sys_ioctl_macros.h"
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.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(pid_t, tcgetpgrp, (int fd)) {
+  pid_t pgid = 0;
+  auto result = linux_syscalls::ioctl(fd, TIOCGPGRP, &pgid);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return pgid;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/linux/tcsetpgrp.cpp b/libc/src/unistd/linux/tcsetpgrp.cpp
new file mode 100644
index 0000000000000..b6310972cd8f0
--- /dev/null
+++ b/libc/src/unistd/linux/tcsetpgrp.cpp
@@ -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
+/// Linux implementation of tcsetpgrp.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/tcsetpgrp.h"
+
+#include "hdr/sys_ioctl_macros.h"
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.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, tcsetpgrp, (int fd, pid_t pgid)) {
+  auto result = linux_syscalls::ioctl(fd, TIOCSPGRP, &pgid);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/tcgetpgrp.h b/libc/src/unistd/tcgetpgrp.h
new file mode 100644
index 0000000000000..057e3549b31e3
--- /dev/null
+++ b/libc/src/unistd/tcgetpgrp.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 tcgetpgrp.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_TCGETPGRP_H
+#define LLVM_LIBC_SRC_UNISTD_TCGETPGRP_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+pid_t tcgetpgrp(int fd);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_UNISTD_TCGETPGRP_H
diff --git a/libc/src/unistd/tcsetpgrp.h b/libc/src/unistd/tcsetpgrp.h
new file mode 100644
index 0000000000000..3d183e327ec85
--- /dev/null
+++ b/libc/src/unistd/tcsetpgrp.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 tcsetpgrp.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_TCSETPGRP_H
+#define LLVM_LIBC_SRC_UNISTD_TCSETPGRP_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int tcsetpgrp(int fd, pid_t pgid);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_UNISTD_TCSETPGRP_H
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index d33476a1fec58..fd398dbb0932a 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -452,6 +452,40 @@ add_libc_test(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
+add_libc_test(
+  tcgetpgrp_test
+  SUITE
+    libc_unistd_unittests
+  SRCS
+    tcgetpgrp_test.cpp
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.fcntl_macros
+    libc.hdr.sys_stat_macros
+    libc.src.fcntl.open
+    libc.src.unistd.close
+    libc.src.unistd.tcgetpgrp
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
+add_libc_test(
+  tcsetpgrp_test
+  SUITE
+    libc_unistd_unittests
+  SRCS
+    tcsetpgrp_test.cpp
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.fcntl_macros
+    libc.hdr.sys_stat_macros
+    libc.src.fcntl.open
+    libc.src.unistd.close
+    libc.src.unistd.tcsetpgrp
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
 add_libc_test(
   truncate_test
   SUITE
diff --git a/libc/test/src/unistd/tcgetpgrp_test.cpp b/libc/test/src/unistd/tcgetpgrp_test.cpp
new file mode 100644
index 0000000000000..e996d3cecc0ab
--- /dev/null
+++ b/libc/test/src/unistd/tcgetpgrp_test.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 tcgetpgrp.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "src/fcntl/open.h"
+#include "src/unistd/close.h"
+#include "src/unistd/tcgetpgrp.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcTcGetPgrpTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+// It's hard to test tcgetpgrp in unit tests, as the test process
+// is not typically associated with a terminal. We can probably achieve
+// this with fork()-ing a child process and creating the pseudo-terminal
+// fixture, but given that tcgetpgrp is a simple ioctl() wrapper (on Linux),
+// this complexity is likely not justified.
+
+TEST_F(LlvmLibcTcGetPgrpTest, BadFd) {
+  ASSERT_THAT(LIBC_NAMESPACE::tcgetpgrp(-1), Fails<pid_t>(EBADF));
+}
+
+TEST_F(LlvmLibcTcGetPgrpTest, NonTerminalFd) {
+  constexpr const char *FILENAME = "tcgetpgrp.test";
+  auto test_file = libc_make_test_file_path(FILENAME);
+  int fd = LIBC_NAMESPACE::open(test_file, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+  ASSERT_THAT(LIBC_NAMESPACE::tcgetpgrp(fd), Fails<pid_t>(ENOTTY));
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}
diff --git a/libc/test/src/unistd/tcsetpgrp_test.cpp b/libc/test/src/unistd/tcsetpgrp_test.cpp
new file mode 100644
index 0000000000000..2142f26ce6c1b
--- /dev/null
+++ b/libc/test/src/unistd/tcsetpgrp_test.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 tcsetpgrp.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/fcntl_macros.h"
+#include "hdr/sys_stat_macros.h"
+#include "src/fcntl/open.h"
+#include "src/unistd/close.h"
+#include "src/unistd/tcsetpgrp.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+using LlvmLibcTcSetPgrpTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+// It's hard to test tcsetpgrp in unit tests, as the test process
+// is not typically associated with a terminal. We can probably achieve
+// this with fork()-ing a child process and creating the pseudo-terminal
+// fixture, but given that tcsetpgrp is a simple ioctl() wrapper (on Linux),
+// this complexity is likely not justified.
+
+TEST_F(LlvmLibcTcSetPgrpTest, BadFd) {
+  ASSERT_THAT(LIBC_NAMESPACE::tcsetpgrp(-1, 0), Fails(EBADF));
+}
+
+TEST_F(LlvmLibcTcSetPgrpTest, NonTerminalFd) {
+  constexpr const char *FILENAME = "tcsetpgrp.test";
+  auto test_file = libc_make_test_file_path(FILENAME);
+  int fd = LIBC_NAMESPACE::open(test_file, O_WRONLY | O_CREAT, S_IRWXU);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GT(fd, 0);
+  ASSERT_THAT(LIBC_NAMESPACE::tcsetpgrp(fd, 0), Fails(ENOTTY));
+  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+}

>From 98919af669968f8a11585cbe394d0f927f7bbbca Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Tue, 1 Sep 2026 17:49:09 +0000
Subject: [PATCH 2/2] tests: update comments and unlink temp files.

---
 libc/test/src/unistd/CMakeLists.txt     |  2 ++
 libc/test/src/unistd/tcgetpgrp_test.cpp | 14 +++++++++-----
 libc/test/src/unistd/tcsetpgrp_test.cpp | 14 +++++++++-----
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index fd398dbb0932a..d41eff9fb3954 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -465,6 +465,7 @@ add_libc_test(
     libc.src.fcntl.open
     libc.src.unistd.close
     libc.src.unistd.tcgetpgrp
+    libc.src.unistd.unlink
     libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
@@ -482,6 +483,7 @@ add_libc_test(
     libc.src.fcntl.open
     libc.src.unistd.close
     libc.src.unistd.tcsetpgrp
+    libc.src.unistd.unlink
     libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
diff --git a/libc/test/src/unistd/tcgetpgrp_test.cpp b/libc/test/src/unistd/tcgetpgrp_test.cpp
index e996d3cecc0ab..deefb95103889 100644
--- a/libc/test/src/unistd/tcgetpgrp_test.cpp
+++ b/libc/test/src/unistd/tcgetpgrp_test.cpp
@@ -17,6 +17,7 @@
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/tcgetpgrp.h"
+#include "src/unistd/unlink.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
@@ -24,11 +25,13 @@
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
 using LlvmLibcTcGetPgrpTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-// It's hard to test tcgetpgrp in unit tests, as the test process
-// is not typically associated with a terminal. We can probably achieve
-// this with fork()-ing a child process and creating the pseudo-terminal
-// fixture, but given that tcgetpgrp is a simple ioctl() wrapper (on Linux),
-// this complexity is likely not justified.
+// NOTE: We are not testing the kernel behavior, only how we wire up
+// and wrap kernel syscalls in libc interface (on Linux we wrap ioctl)
+// and propagate errors. It's hard to get good coverage of tcgetpgrp
+// in unit tests, as the test process is not typically associated with
+// a terminal. We can achieve this with fork()-ing a child process
+// and creating the pseudo-terminal fixture, but this complexity is
+// not justified.
 
 TEST_F(LlvmLibcTcGetPgrpTest, BadFd) {
   ASSERT_THAT(LIBC_NAMESPACE::tcgetpgrp(-1), Fails<pid_t>(EBADF));
@@ -42,4 +45,5 @@ TEST_F(LlvmLibcTcGetPgrpTest, NonTerminalFd) {
   ASSERT_GT(fd, 0);
   ASSERT_THAT(LIBC_NAMESPACE::tcgetpgrp(fd), Fails<pid_t>(ENOTTY));
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::unlink(test_file), Succeeds(0));
 }
diff --git a/libc/test/src/unistd/tcsetpgrp_test.cpp b/libc/test/src/unistd/tcsetpgrp_test.cpp
index 2142f26ce6c1b..6aa02baad7337 100644
--- a/libc/test/src/unistd/tcsetpgrp_test.cpp
+++ b/libc/test/src/unistd/tcsetpgrp_test.cpp
@@ -17,6 +17,7 @@
 #include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/tcsetpgrp.h"
+#include "src/unistd/unlink.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
@@ -24,11 +25,13 @@
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
 using LlvmLibcTcSetPgrpTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
-// It's hard to test tcsetpgrp in unit tests, as the test process
-// is not typically associated with a terminal. We can probably achieve
-// this with fork()-ing a child process and creating the pseudo-terminal
-// fixture, but given that tcsetpgrp is a simple ioctl() wrapper (on Linux),
-// this complexity is likely not justified.
+// NOTE: We are not testing the kernel behavior, only how we wire up
+// and wrap kernel syscalls in libc interface (on Linux we wrap ioctl)
+// and propagate errors. It's hard to get good coverage of tcgetpgrp
+// in unit tests, as the test process is not typically associated with
+// a terminal. We can achieve this with fork()-ing a child process
+// and creating the pseudo-terminal fixture, but this complexity is
+// not justified.
 
 TEST_F(LlvmLibcTcSetPgrpTest, BadFd) {
   ASSERT_THAT(LIBC_NAMESPACE::tcsetpgrp(-1, 0), Fails(EBADF));
@@ -42,4 +45,5 @@ TEST_F(LlvmLibcTcSetPgrpTest, NonTerminalFd) {
   ASSERT_GT(fd, 0);
   ASSERT_THAT(LIBC_NAMESPACE::tcsetpgrp(fd, 0), Fails(ENOTTY));
   ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::unlink(test_file), Succeeds(0));
 }



More information about the libc-commits mailing list