[libc-commits] [libc] [llvm] [libc] Convert readv, writev, and read_write tests to use pipes (PR #210725)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Fri Jul 24 00:18:12 PDT 2026


https://github.com/labath updated https://github.com/llvm/llvm-project/pull/210725

>From 311c0d33276963be285fe4105c85135f80bb0a2c Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 20 Jul 2026 13:58:24 +0000
Subject: [PATCH 1/2] [libc] Convert readv, writev, and read_write tests to use
 pipes

Using a pipe avoids races between "hermetic" and "unit" versions of the same
test and avoids leaving filesystem artifacts around if the test fails.
If I'm successful, we won't have the worry about the first problem anymore, but
I think it's still a nice cleanup.

Assisted by Gemini.
---
 libc/test/src/sys/uio/CMakeLists.txt          |  7 +++--
 libc/test/src/sys/uio/readv_test.cpp          | 21 ++++++---------
 libc/test/src/sys/uio/writev_test.cpp         | 23 +++++++++-------
 libc/test/src/unistd/CMakeLists.txt           |  5 +---
 libc/test/src/unistd/read_write_test.cpp      | 26 +++++--------------
 .../libc/test/src/unistd/BUILD.bazel          |  5 +---
 6 files changed, 34 insertions(+), 53 deletions(-)

diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt
index 7ba02be5d1cc4..7ae4810e9aaae 100644
--- a/libc/test/src/sys/uio/CMakeLists.txt
+++ b/libc/test/src/sys/uio/CMakeLists.txt
@@ -10,10 +10,10 @@ add_libc_unittest(
     libc.hdr.types.struct_iovec
     libc.src.__support.common
     libc.src.errno.errno
-    libc.src.fcntl.open
     libc.src.sys.uio.writev
     libc.src.unistd.close
-    libc.src.unistd.unlink
+    libc.src.unistd.pipe
+    libc.src.unistd.read
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
@@ -27,10 +27,9 @@ add_libc_unittest(
     libc.hdr.types.struct_iovec
     libc.src.__support.common
     libc.src.errno.errno
-    libc.src.fcntl.open
     libc.src.sys.uio.readv
     libc.src.unistd.close
-    libc.src.unistd.unlink
+    libc.src.unistd.pipe
     libc.src.unistd.write
     libc.test.UnitTest.ErrnoSetterMatcher
 )
diff --git a/libc/test/src/sys/uio/readv_test.cpp b/libc/test/src/sys/uio/readv_test.cpp
index 7cbaa3397d887..b25afc9754688 100644
--- a/libc/test/src/sys/uio/readv_test.cpp
+++ b/libc/test/src/sys/uio/readv_test.cpp
@@ -7,10 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/types/struct_iovec.h"
-#include "src/fcntl/open.h"
 #include "src/sys/uio/readv.h"
 #include "src/unistd/close.h"
-#include "src/unistd/unlink.h"
+#include "src/unistd/pipe.h"
 #include "src/unistd/write.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
@@ -18,16 +17,14 @@
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
 
 TEST(LlvmLibcSysUioReadvTest, SmokeTest) {
-  const char *filename = "./LlvmLibcSysUioReadvTest";
-  int fd = LIBC_NAMESPACE::open(filename, O_WRONLY | O_CREAT, 0644);
-  ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
+  int pipefd[2];
+  ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds());
+
   const char data[] = "Hello, World!\n";
-  ASSERT_THAT(LIBC_NAMESPACE::write(fd, data, sizeof(data)),
+  ASSERT_THAT(LIBC_NAMESPACE::write(pipefd[1], data, sizeof(data)),
               returns(EQ(sizeof(data))).with_errno(EQ(0)));
-  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
+  ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds());
 
-  fd = LIBC_NAMESPACE::open(filename, O_RDONLY);
-  ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
   char buf0[2];
   char buf1[3];
   struct iovec iov[2];
@@ -35,9 +32,7 @@ TEST(LlvmLibcSysUioReadvTest, SmokeTest) {
   iov[0].iov_len = 1;
   iov[1].iov_base = buf1;
   iov[1].iov_len = 2;
-  ASSERT_THAT(LIBC_NAMESPACE::readv(fd, iov, 2),
+  ASSERT_THAT(LIBC_NAMESPACE::readv(pipefd[0], iov, 2),
               returns(EQ(ssize_t(3))).with_errno(EQ(0)));
-  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
-  ASSERT_THAT(LIBC_NAMESPACE::unlink(filename),
-              returns(EQ(ssize_t(0))).with_errno(EQ(0)));
+  ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds());
 }
diff --git a/libc/test/src/sys/uio/writev_test.cpp b/libc/test/src/sys/uio/writev_test.cpp
index 69db0de47141c..bf6b04fee0bda 100644
--- a/libc/test/src/sys/uio/writev_test.cpp
+++ b/libc/test/src/sys/uio/writev_test.cpp
@@ -7,28 +7,33 @@
 //===----------------------------------------------------------------------===//
 
 #include "hdr/types/struct_iovec.h"
-#include "src/fcntl/open.h"
 #include "src/sys/uio/writev.h"
 #include "src/unistd/close.h"
-#include "src/unistd/unlink.h"
+#include "src/unistd/pipe.h"
+#include "src/unistd/read.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
 using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
 
 TEST(LlvmLibcSysUioWritevTest, SmokeTest) {
-  const char *filename = "./LlvmLibcSysUioWritevTest";
-  int fd = LIBC_NAMESPACE::open(filename, O_WRONLY | O_CREAT, 0644);
-  ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
+  int pipefd[2];
+  ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds());
+
   const char *data = "Hello, World!\n";
   struct iovec iov[2];
   iov[0].iov_base = const_cast<char *>(data);
   iov[0].iov_len = 7;
   iov[1].iov_base = const_cast<char *>(data + 7);
   iov[1].iov_len = 8;
-  ASSERT_THAT(LIBC_NAMESPACE::writev(fd, iov, 2),
+  ASSERT_THAT(LIBC_NAMESPACE::writev(pipefd[1], iov, 2),
+              returns(EQ(ssize_t(15))).with_errno(EQ(0)));
+  ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds());
+
+  char buf[16];
+  ASSERT_THAT(LIBC_NAMESPACE::read(pipefd[0], buf, 15),
               returns(EQ(ssize_t(15))).with_errno(EQ(0)));
-  ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
-  ASSERT_THAT(LIBC_NAMESPACE::unlink(filename),
-              returns(EQ(ssize_t(0))).with_errno(EQ(0)));
+  buf[15] = '\0';
+  EXPECT_STREQ(buf, data);
+  ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds());
 }
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 070c25f24e61a..93f8888dee19b 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -237,15 +237,12 @@ add_libc_unittest(
   SRCS
     read_write_test.cpp
   DEPENDS
-    libc.hdr.sys_stat_macros
     libc.include.unistd
     libc.src.errno.errno
-    libc.src.fcntl.open
     libc.src.unistd.close
-    libc.src.unistd.fsync
+    libc.src.unistd.pipe
     libc.src.unistd.read
     libc.src.unistd.write
-    libc.src.stdio.remove
     libc.test.UnitTest.ErrnoCheckingTest
     libc.test.UnitTest.ErrnoSetterMatcher
 )
diff --git a/libc/test/src/unistd/read_write_test.cpp b/libc/test/src/unistd/read_write_test.cpp
index 17cd4f6ce8b44..7b700154d2f30 100644
--- a/libc/test/src/unistd/read_write_test.cpp
+++ b/libc/test/src/unistd/read_write_test.cpp
@@ -6,11 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "hdr/sys_stat_macros.h"
-#include "src/fcntl/open.h"
-#include "src/stdio/remove.h"
 #include "src/unistd/close.h"
-#include "src/unistd/fsync.h"
+#include "src/unistd/pipe.h"
 #include "src/unistd/read.h"
 #include "src/unistd/write.h"
 #include "test/UnitTest/ErrnoCheckingTest.h"
@@ -21,29 +18,20 @@ using LlvmLibcUniStd = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
 
 TEST_F(LlvmLibcUniStd, WriteAndReadBackTest) {
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
-  constexpr const char *FILENAME = "__unistd_read_write.test";
-  auto TEST_FILE = libc_make_test_file_path(FILENAME);
+  int pipefd[2];
+  ASSERT_THAT(LIBC_NAMESPACE::pipe(pipefd), Succeeds(0));
 
-  int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_GT(write_fd, 0);
   constexpr const char HELLO[] = "hello";
   constexpr ssize_t HELLO_SIZE = sizeof(HELLO);
-  ASSERT_THAT(LIBC_NAMESPACE::write(write_fd, HELLO, HELLO_SIZE),
+  ASSERT_THAT(LIBC_NAMESPACE::write(pipefd[1], HELLO, HELLO_SIZE),
               Succeeds(HELLO_SIZE));
-  ASSERT_THAT(LIBC_NAMESPACE::fsync(write_fd), Succeeds(0));
-  ASSERT_THAT(LIBC_NAMESPACE::close(write_fd), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[1]), Succeeds(0));
 
-  int read_fd = LIBC_NAMESPACE::open(TEST_FILE, O_RDONLY);
-  ASSERT_ERRNO_SUCCESS();
-  ASSERT_GT(read_fd, 0);
   char read_buf[10];
-  ASSERT_THAT(LIBC_NAMESPACE::read(read_fd, read_buf, HELLO_SIZE),
+  ASSERT_THAT(LIBC_NAMESPACE::read(pipefd[0], read_buf, HELLO_SIZE),
               Succeeds(HELLO_SIZE));
   EXPECT_STREQ(read_buf, HELLO);
-  ASSERT_THAT(LIBC_NAMESPACE::close(read_fd), Succeeds(0));
-
-  ASSERT_THAT(LIBC_NAMESPACE::remove(TEST_FILE), Succeeds(0));
+  ASSERT_THAT(LIBC_NAMESPACE::close(pipefd[0]), Succeeds(0));
 }
 
 TEST_F(LlvmLibcUniStd, WriteFails) {
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel
index 54006159cee10..6507820ea5679 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/unistd/BUILD.bazel
@@ -107,11 +107,8 @@ libc_test(
     srcs = ["read_write_test.cpp"],
     deps = [
         "//libc:close",
-        "//libc:fsync",
-        "//libc:hdr_sys_stat_macros",
-        "//libc:open",
+        "//libc:pipe",
         "//libc:read",
-        "//libc:remove",
         "//libc:write",
     ],
 )

>From 2876ea9e5b4be3352f318ccd2108448fa449dcd4 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 20 Jul 2026 14:12:46 +0000
Subject: [PATCH 2/2] also make them hermetic

---
 libc/test/src/sys/uio/CMakeLists.txt | 4 ++--
 libc/test/src/unistd/CMakeLists.txt  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt
index 7ae4810e9aaae..9d8beec1fe5be 100644
--- a/libc/test/src/sys/uio/CMakeLists.txt
+++ b/libc/test/src/sys/uio/CMakeLists.txt
@@ -1,6 +1,6 @@
 add_custom_target(libc_sys_uio_unittests)
 
-add_libc_unittest(
+add_libc_test(
   writev_test
   SUITE
     libc_sys_uio_unittests
@@ -17,7 +17,7 @@ add_libc_unittest(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
-add_libc_unittest(
+add_libc_test(
   readv_test
   SUITE
     libc_sys_uio_unittests
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 93f8888dee19b..a25e3a29af95c 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -230,7 +230,7 @@ add_libc_unittest(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
-add_libc_unittest(
+add_libc_test(
   read_write_test
   SUITE
     libc_unistd_unittests



More information about the libc-commits mailing list