[libc-commits] [libc] [libc] pipe(2) linux syscall wrapper and unittest (PR #85514)

via libc-commits libc-commits at lists.llvm.org
Tue Mar 19 04:08:39 PDT 2024


https://github.com/muffpy updated https://github.com/llvm/llvm-project/pull/85514

>From 6a75de83af26c9d1dd157e584ce44d9f62992c54 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 10:36:51 +0000
Subject: [PATCH 01/11] pipe(2) linux syscall wrapper and unittest

---
 libc/config/linux/x86_64/entrypoints.txt |  1 +
 libc/spec/linux.td                       | 17 +++++++
 libc/src/unistd/CMakeLists.txt           |  7 +++
 libc/src/unistd/linux/CMakeLists.txt     | 13 +++++
 libc/src/unistd/linux/pipe2.cpp          | 35 +++++++++++++
 libc/src/unistd/pipe2.h                  | 20 ++++++++
 libc/test/src/unistd/CMakeLists.txt      | 19 +++++++
 libc/test/src/unistd/pipe2_test.cpp      | 64 ++++++++++++++++++++++++
 8 files changed, 176 insertions(+)
 create mode 100644 libc/src/unistd/linux/pipe2.cpp
 create mode 100644 libc/src/unistd/pipe2.h
 create mode 100644 libc/test/src/unistd/pipe2_test.cpp

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 4fb31c593b9dc7..702894b8a21d26 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -297,6 +297,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.link
     libc.src.unistd.linkat
     libc.src.unistd.lseek
+    libc.src.unistd.pipe2
     libc.src.unistd.pread
     libc.src.unistd.pwrite
     libc.src.unistd.read
diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index f91f55ddac7846..80d3e860ed6c46 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -3,6 +3,8 @@ def StructEpollEventPtr : PtrType<StructEpollEvent>;
 
 def StructEpollData : NamedType<"struct epoll_data">;
 
+def Pipe2fdArrayT : NamedType<"__pipe2fd_array_t">;
+
 def Linux : StandardSpec<"Linux"> {
   HeaderSpec Errno = HeaderSpec<
       "errno.h",
@@ -264,6 +266,20 @@ def Linux : StandardSpec<"Linux"> {
       ]
   >;
 
+  HeaderSpec UniStd = HeaderSpec<
+    "unistd.h",
+    [], // Macros
+    [Pipe2fdArrayT], // Types
+    [], // Enumerations
+    [
+        FunctionSpec<
+          "pipe2",
+          RetValSpec<IntType>,
+          [ArgSpec<Pipe2fdArrayT>, ArgSpec<IntType>]
+        >,
+    ]
+  >;
+
   let Headers = [
     Errno,
     SysEpoll,
@@ -272,5 +288,6 @@ def Linux : StandardSpec<"Linux"> {
     SysRandom,
     SysTime,
     Signal,
+    UniStd
   ];
 }
diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index e22b0e1872caa1..c63f170df29b96 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -149,6 +149,13 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.lseek
 )
 
+add_entrypoint_object(
+  pipe2
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.pipe2
+)
+
 add_entrypoint_object(
   pread
   ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index df85d44e9e9edc..3496d32a18f2e4 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -273,6 +273,19 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  pipe2
+  SRCS
+    pipe2.cpp
+  HDRS
+    ../pipe2.h
+  DEPENDS
+    libc.include.unistd
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   pread
   SRCS
diff --git a/libc/src/unistd/linux/pipe2.cpp b/libc/src/unistd/linux/pipe2.cpp
new file mode 100644
index 00000000000000..9f2e5390104703
--- /dev/null
+++ b/libc/src/unistd/linux/pipe2.cpp
@@ -0,0 +1,35 @@
+//===-- Linux implementation of pipe2 ---------------------------------------===//
+//
+// 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/unistd/pipe2.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, pipe2, (int pipefd[2], int flags)) {
+    int ret;
+#ifdef SYS_pipe2
+  ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pipe2, pipefd, flags);
+#elif defined (SYS_pipe)
+  ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pipe, pipefd);
+#else 
+#error "pipe and pipe2 not available."
+#endif
+  if (ret == -1) {
+    libc_errno = -ret;
+    return -1;
+  }
+  return ret;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/unistd/pipe2.h b/libc/src/unistd/pipe2.h
new file mode 100644
index 00000000000000..3cf5d81f1f280e
--- /dev/null
+++ b/libc/src/unistd/pipe2.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pipe2 ---------------------------*- 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_UNISTD_PIPE2_H
+#define LLVM_LIBC_SRC_UNISTD_PIPE2_H
+
+#include <unistd.h>
+
+namespace LIBC_NAMESPACE {
+
+int pipe2(int pipefd[2], int flags);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_UNISTD_PIPE2_H
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 3a7fe6f45c0911..76212a38467586 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -444,3 +444,22 @@ add_libc_test(
     libc.src.stdio.fopencookie
     libc.src.stdio.fflush
 )
+
+add_libc_unittest(
+  pipe2_test
+  SUITE
+    libc_unistd_unittests
+  SRCS
+    pipe2_test.cpp
+  DEPENDS
+    libc.include.errno
+    libc.include.unistd
+    libc.src.errno.errno
+    libc.src.fcntl.open
+    libc.src.unistd.close
+    libc.src.unistd.pipe2
+    libc.src.unistd.read
+    libc.src.unistd.unlink
+    libc.src.unistd.write
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
\ No newline at end of file
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
new file mode 100644
index 00000000000000..8c91078df466c3
--- /dev/null
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -0,0 +1,64 @@
+//===-- Unittests for pipe2 -------------------------------------------------===//
+//
+// 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/errno/libc_errno.h"
+#include "src/fcntl/open.h"
+#include "src/unistd/close.h"
+#include "src/unistd/pipe2.h"
+#include "src/unistd/read.h"
+#include "src/unistd/unlink.h"
+#include "src/unistd/write.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <sys/stat.h>
+
+TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
+  int pipefd[2];
+  int flags;
+
+  LIBC_NAMESPACE::libc_errno = 0;
+  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+  // Create pipe(2) with flags set to 0
+  flags = 0;
+  ASSERT_NE(LIBC_NAMESPACE::pipe2(pipefd, flags), -1);
+  ASSERT_ERRNO_SUCCESS();
+
+  // Write something via the pipe and read from other end
+  constexpr char MESSAGE[] = "Hello from the write end!";
+  constexpr size_t MESSAGE_SIZE = sizeof(MESSAGE);
+  char buf[MESSAGE_SIZE];
+  ASSERT_EQ(ssize_t(MESSAGE_SIZE),
+            LIBC_NAMESPACE::write(pipefd[1], MESSAGE, MESSAGE_SIZE));
+  ASSERT_EQ(ssize_t(MESSAGE_SIZE),
+            LIBC_NAMESPACE::read(pipefd[0], buf, MESSAGE_SIZE));
+  ASSERT_STREQ(buf, MESSAGE);
+
+  // Close the pipe file descriptors
+  ASSERT_NE(LIBC_NAMESPACE::close(pipefd[0]), -1);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_NE(LIBC_NAMESPACE::close(pipefd[1]), -1);
+  ASSERT_ERRNO_SUCCESS();
+}
+
+TEST(LlvmLibcPipe2Test, Pipe2BadFlags) {
+  int badflags = -1;
+  int pipefd[2];
+
+  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+  ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, badflag), Fails(EBADF));
+}
+
+TEST(LlvmLibcPipe2Test, Pipe2BadFD) {
+  int flags = 0;
+  int badpipefd[1];
+
+  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+  ASSERT_THAT(LIBC_NAMESPACE::pipe2(badpipefd, flags), Fails(EBADF));
+}

>From a8afc5c3ecf50305a41031f8d360cd01c3c53aa4 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 10:44:21 +0000
Subject: [PATCH 02/11] Format patch using git-clang-format

---
 libc/src/unistd/linux/pipe2.cpp     | 9 +++++----
 libc/src/unistd/pipe2.h             | 3 ++-
 libc/test/src/unistd/pipe2_test.cpp | 3 ++-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/libc/src/unistd/linux/pipe2.cpp b/libc/src/unistd/linux/pipe2.cpp
index 9f2e5390104703..52997e3ca10c91 100644
--- a/libc/src/unistd/linux/pipe2.cpp
+++ b/libc/src/unistd/linux/pipe2.cpp
@@ -1,4 +1,5 @@
-//===-- Linux implementation of pipe2 ---------------------------------------===//
+//===-- Linux implementation of pipe2
+//---------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -17,12 +18,12 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, pipe2, (int pipefd[2], int flags)) {
-    int ret;
+  int ret;
 #ifdef SYS_pipe2
   ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pipe2, pipefd, flags);
-#elif defined (SYS_pipe)
+#elif defined(SYS_pipe)
   ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pipe, pipefd);
-#else 
+#else
 #error "pipe and pipe2 not available."
 #endif
   if (ret == -1) {
diff --git a/libc/src/unistd/pipe2.h b/libc/src/unistd/pipe2.h
index 3cf5d81f1f280e..06a55857a56efb 100644
--- a/libc/src/unistd/pipe2.h
+++ b/libc/src/unistd/pipe2.h
@@ -1,4 +1,5 @@
-//===-- Implementation header for pipe2 ---------------------------*- C++ -*-===//
+//===-- Implementation header for pipe2 ---------------------------*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 8c91078df466c3..217df2d47702ba 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -1,4 +1,5 @@
-//===-- Unittests for pipe2 -------------------------------------------------===//
+//===-- Unittests for pipe2
+//-------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.

>From 174676f544535a6f3b4282f7aadfcb88b2cba717 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 10:49:59 +0000
Subject: [PATCH 03/11] Fix typo in Pipe2BadFlags test

---
 libc/test/src/unistd/pipe2_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 217df2d47702ba..f5ecd9494be4ba 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -53,7 +53,7 @@ TEST(LlvmLibcPipe2Test, Pipe2BadFlags) {
   int pipefd[2];
 
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
-  ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, badflag), Fails(EBADF));
+  ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, badflags), Fails(EBADF));
 }
 
 TEST(LlvmLibcPipe2Test, Pipe2BadFD) {

>From c6fab70012b5aedf652aaed6b43eedd50b20c35b Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 10:58:54 +0000
Subject: [PATCH 04/11] Set correct errors and test titles based on Linux
 standard

---
 libc/test/src/unistd/pipe2_test.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index f5ecd9494be4ba..7969724e5117c8 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -48,18 +48,18 @@ TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
   ASSERT_ERRNO_SUCCESS();
 }
 
-TEST(LlvmLibcPipe2Test, Pipe2BadFlags) {
-  int badflags = -1;
+TEST(LlvmLibcPipe2Test, Pipe2InvalidFlags) {
+  int invalidflags = -1;
   int pipefd[2];
 
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
-  ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, badflags), Fails(EBADF));
+  ASSERT_THAT(LIBC_NAMESPACE::pipe2(pipefd, invalidflags), Fails(EINVAL));
 }
 
-TEST(LlvmLibcPipe2Test, Pipe2BadFD) {
+TEST(LlvmLibcPipe2Test, Pipe2InvalidPipeFD) {
   int flags = 0;
-  int badpipefd[1];
+  int invalidpipefd[1];
 
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
-  ASSERT_THAT(LIBC_NAMESPACE::pipe2(badpipefd, flags), Fails(EBADF));
+  ASSERT_THAT(LIBC_NAMESPACE::pipe2(invalidpipefd, flags), Fails(EFAULT));
 }

>From 30d2385f0f05f834b2d41c89f87e42e24ab046eb Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 11:55:36 +0000
Subject: [PATCH 05/11] Remove unwanted headers from pipe2_test and fix
 Pipe2InvalidFlags test

---
 libc/test/src/unistd/CMakeLists.txt | 2 --
 libc/test/src/unistd/pipe2_test.cpp | 6 +-----
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 76212a38467586..e4d163f4e882f5 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -455,11 +455,9 @@ add_libc_unittest(
     libc.include.errno
     libc.include.unistd
     libc.src.errno.errno
-    libc.src.fcntl.open
     libc.src.unistd.close
     libc.src.unistd.pipe2
     libc.src.unistd.read
-    libc.src.unistd.unlink
     libc.src.unistd.write
     libc.test.UnitTest.ErrnoSetterMatcher
 )
\ No newline at end of file
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 7969724e5117c8..ee82abf1bb0b3b 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -8,17 +8,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/errno/libc_errno.h"
-#include "src/fcntl/open.h"
 #include "src/unistd/close.h"
 #include "src/unistd/pipe2.h"
 #include "src/unistd/read.h"
-#include "src/unistd/unlink.h"
 #include "src/unistd/write.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
-#include <sys/stat.h>
-
 TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
   int pipefd[2];
   int flags;
@@ -49,7 +45,7 @@ TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
 }
 
 TEST(LlvmLibcPipe2Test, Pipe2InvalidFlags) {
-  int invalidflags = -1;
+  char invalidflags = '-1';
   int pipefd[2];
 
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;

>From 53c43e3e5613253911fefc328b691975c01da632 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 12:03:39 +0000
Subject: [PATCH 06/11] Pass unsupported flags to pipe(2) in Pipe2InvalidFlags
 test

---
 libc/test/src/unistd/pipe2_test.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index ee82abf1bb0b3b..94217005913eb1 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -45,7 +45,7 @@ TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
 }
 
 TEST(LlvmLibcPipe2Test, Pipe2InvalidFlags) {
-  char invalidflags = '-1';
+  int invalidflags = O_CREAT | O_PATH | O_SYNC;
   int pipefd[2];
 
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;

>From 6100033a402a0af781c29ccaa58cc42494f9dfc4 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Sat, 16 Mar 2024 12:15:53 +0000
Subject: [PATCH 07/11] Add fcntl.h to access file control flags for
 Pipe2InvalidFlags test

---
 libc/test/src/unistd/pipe2_test.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 94217005913eb1..93d5ea1b8064c8 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -15,6 +15,8 @@
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/Test.h"
 
+#include <fcntl.h>
+
 TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
   int pipefd[2];
   int flags;

>From 7b87696a08f64d8ec208590648892ecef3386aa8 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Mon, 18 Mar 2024 19:58:21 +0000
Subject: [PATCH 08/11] Fix header ordering and pipe(2) failure convention

---
 libc/src/unistd/linux/pipe2.cpp     | 4 ++--
 libc/src/unistd/pipe2.h             | 2 --
 libc/test/src/unistd/pipe2_test.cpp | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/libc/src/unistd/linux/pipe2.cpp b/libc/src/unistd/linux/pipe2.cpp
index 52997e3ca10c91..6db83a0303a211 100644
--- a/libc/src/unistd/linux/pipe2.cpp
+++ b/libc/src/unistd/linux/pipe2.cpp
@@ -11,8 +11,8 @@
 
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
-
 #include "src/errno/libc_errno.h"
+
 #include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE {
@@ -26,7 +26,7 @@ LLVM_LIBC_FUNCTION(int, pipe2, (int pipefd[2], int flags)) {
 #else
 #error "pipe and pipe2 not available."
 #endif
-  if (ret == -1) {
+  if (ret < 0) {
     libc_errno = -ret;
     return -1;
   }
diff --git a/libc/src/unistd/pipe2.h b/libc/src/unistd/pipe2.h
index 06a55857a56efb..32e4c7a1b269ae 100644
--- a/libc/src/unistd/pipe2.h
+++ b/libc/src/unistd/pipe2.h
@@ -10,8 +10,6 @@
 #ifndef LLVM_LIBC_SRC_UNISTD_PIPE2_H
 #define LLVM_LIBC_SRC_UNISTD_PIPE2_H
 
-#include <unistd.h>
-
 namespace LIBC_NAMESPACE {
 
 int pipe2(int pipefd[2], int flags);
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 93d5ea1b8064c8..4fd16fbd16cf92 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -46,7 +46,7 @@ TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
   ASSERT_ERRNO_SUCCESS();
 }
 
-TEST(LlvmLibcPipe2Test, Pipe2InvalidFlags) {
+TEST(LlvmLibcPipe2Test,Pipe2InvalidFlags) {
   int invalidflags = O_CREAT | O_PATH | O_SYNC;
   int pipefd[2];
 

>From 863c2ab8fbc31c643fea421b150be4e04ada8a2b Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Tue, 19 Mar 2024 10:52:18 +0000
Subject: [PATCH 09/11] pipe(2) functionality and error handling tests + watch
 queue uapi macros

---
 libc/config/linux/aarch64/entrypoints.txt     |  1 +
 .../llvm-libc-macros/linux/fcntl-macros.h     |  6 +++
 .../linux/watch-queue-macros.h                | 19 ++++++++
 libc/test/src/unistd/pipe2_test.cpp           | 43 ++++++++++++++++---
 4 files changed, 63 insertions(+), 6 deletions(-)
 create mode 100644 libc/include/llvm-libc-macros/linux/watch-queue-macros.h

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 7d69099e3cb9db..de3b7bcbae23a8 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -290,6 +290,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.link
     libc.src.unistd.linkat
     libc.src.unistd.lseek
+    libc.src.unistd.pipe2
     libc.src.unistd.pread
     libc.src.unistd.pwrite
     libc.src.unistd.read
diff --git a/libc/include/llvm-libc-macros/linux/fcntl-macros.h b/libc/include/llvm-libc-macros/linux/fcntl-macros.h
index 1d4e5bbbdc770a..a86e51f89fb955 100644
--- a/libc/include/llvm-libc-macros/linux/fcntl-macros.h
+++ b/libc/include/llvm-libc-macros/linux/fcntl-macros.h
@@ -29,6 +29,12 @@
 #define O_NOFOLLOW 00400000
 #endif
 
+#ifdef __aarch64__
+#define O_DIRECT 0200000
+#else
+#define O_DIRECT 00040000
+#endif
+
 #define O_TRUNC 00001000
 #define O_TMPFILE (020000000 | O_DIRECTORY)
 
diff --git a/libc/include/llvm-libc-macros/linux/watch-queue-macros.h b/libc/include/llvm-libc-macros/linux/watch-queue-macros.h
new file mode 100644
index 00000000000000..0410dfa7bec2f1
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/watch-queue-macros.h
@@ -0,0 +1,19 @@
+//===-- Definition of macros from watch-queue.h ---------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// References
+// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/watch_queue.h
+// https://kernelnewbies.org/Linux_5.8#Core_.28various.29
+// https://docs.kernel.org/core-api/watch_queue.html
+
+#ifndef LLVM_LIBC_MACROS_LINUX_WATCH_QUEUE_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_WATCH_QUEUE_MACROS_H
+
+#define O_NOTIFICATION_PIPE	O_EXCL	/* Parameter to pipe2() selecting notification pipe */
+
+#endif // LLVM_LIBC_MACROS_LINUX_WATCH_QUEUE_MACROS_H
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 4fd16fbd16cf92..7f08dcf1d25bd0 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "include/llvm-libc-macros/linux/fcntl-macros.h"
+#include "include/llvm-libc-macros/linux/watch-queue-macros.h"
 #include "src/errno/libc_errno.h"
 #include "src/unistd/close.h"
 #include "src/unistd/pipe2.h"
@@ -17,6 +19,38 @@
 
 #include <fcntl.h>
 
+TEST(LlvmLibcPipe2Test, Pipe2CreationTest) {
+  int pipefd[2];
+  int flags;
+
+  LIBC_NAMESPACE::libc_errno = 0;
+  using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+  // Create pipe(2) with all valid flags set
+  #ifdef CONFIG_WATCH_QUEUE
+  flags = O_CLOEXEC | O_NONBLOCK | O_DIRECT | O_NOTIFICATION_PIPE;
+  #else
+  flags = O_CLOEXEC | O_NONBLOCK | O_DIRECT;
+  #endif
+  ASSERT_NE(LIBC_NAMESPACE::pipe2(pipefd, flags), -1);
+  ASSERT_ERRNO_SUCCESS();
+
+  // Check if file descriptors are distinct and valid
+  ASSERT_GE(pipefd[0], 0);
+  ASSERT_GE(pipefd[1], 0);
+  ASSERT_NE(pipefd[0], pipefd[1]);
+
+  // Check file status flags associated with pipe file descriptors
+  ASSERT_TRUE((fcntl(pipefd[0], F_GETFL) & flags) != 0);
+  ASSERT_TRUE((fcntl(pipefd[1], F_GETFL) & flags) != 0);
+
+  // Close the pipe file descriptors
+  ASSERT_NE(LIBC_NAMESPACE::close(pipefd[0]), -1);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_NE(LIBC_NAMESPACE::close(pipefd[1]), -1);
+  ASSERT_ERRNO_SUCCESS();
+}
+
 TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
   int pipefd[2];
   int flags;
@@ -46,8 +80,8 @@ TEST(LlvmLibcPipe2Test, ReadAndWriteViaPipe2) {
   ASSERT_ERRNO_SUCCESS();
 }
 
-TEST(LlvmLibcPipe2Test,Pipe2InvalidFlags) {
-  int invalidflags = O_CREAT | O_PATH | O_SYNC;
+TEST(LlvmLibcPipe2Test, Pipe2InvalidFlags) {
+  int invalidflags = 0xDEADBEEF;
   int pipefd[2];
 
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
@@ -55,9 +89,6 @@ TEST(LlvmLibcPipe2Test,Pipe2InvalidFlags) {
 }
 
 TEST(LlvmLibcPipe2Test, Pipe2InvalidPipeFD) {
-  int flags = 0;
-  int invalidpipefd[1];
-
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
-  ASSERT_THAT(LIBC_NAMESPACE::pipe2(invalidpipefd, flags), Fails(EFAULT));
+  ASSERT_THAT(LIBC_NAMESPACE::pipe2(NULL, 0), Fails(EFAULT));
 }

>From 63d99553d912b562f143408c2e09010913b8ba31 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Tue, 19 Mar 2024 10:53:07 +0000
Subject: [PATCH 10/11] Clang formatting

---
 libc/include/llvm-libc-macros/linux/watch-queue-macros.h | 6 ++++--
 libc/test/src/unistd/pipe2_test.cpp                      | 8 ++++----
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/libc/include/llvm-libc-macros/linux/watch-queue-macros.h b/libc/include/llvm-libc-macros/linux/watch-queue-macros.h
index 0410dfa7bec2f1..55410f7613c252 100644
--- a/libc/include/llvm-libc-macros/linux/watch-queue-macros.h
+++ b/libc/include/llvm-libc-macros/linux/watch-queue-macros.h
@@ -1,4 +1,5 @@
-//===-- Definition of macros from watch-queue.h ---------------------------------===//
+//===-- Definition of macros from watch-queue.h
+//---------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -14,6 +15,7 @@
 #ifndef LLVM_LIBC_MACROS_LINUX_WATCH_QUEUE_MACROS_H
 #define LLVM_LIBC_MACROS_LINUX_WATCH_QUEUE_MACROS_H
 
-#define O_NOTIFICATION_PIPE	O_EXCL	/* Parameter to pipe2() selecting notification pipe */
+#define O_NOTIFICATION_PIPE                                                    \
+  O_EXCL /* Parameter to pipe2() selecting notification pipe */
 
 #endif // LLVM_LIBC_MACROS_LINUX_WATCH_QUEUE_MACROS_H
diff --git a/libc/test/src/unistd/pipe2_test.cpp b/libc/test/src/unistd/pipe2_test.cpp
index 7f08dcf1d25bd0..6f985d867b5b4b 100644
--- a/libc/test/src/unistd/pipe2_test.cpp
+++ b/libc/test/src/unistd/pipe2_test.cpp
@@ -26,12 +26,12 @@ TEST(LlvmLibcPipe2Test, Pipe2CreationTest) {
   LIBC_NAMESPACE::libc_errno = 0;
   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
 
-  // Create pipe(2) with all valid flags set
-  #ifdef CONFIG_WATCH_QUEUE
+// Create pipe(2) with all valid flags set
+#ifdef CONFIG_WATCH_QUEUE
   flags = O_CLOEXEC | O_NONBLOCK | O_DIRECT | O_NOTIFICATION_PIPE;
-  #else
+#else
   flags = O_CLOEXEC | O_NONBLOCK | O_DIRECT;
-  #endif
+#endif
   ASSERT_NE(LIBC_NAMESPACE::pipe2(pipefd, flags), -1);
   ASSERT_ERRNO_SUCCESS();
 

>From 4cf1101dcfebc4abb25db986e98f86f6e513cbd5 Mon Sep 17 00:00:00 2001
From: muffpy <rahulathreya at yahoo.com>
Date: Tue, 19 Mar 2024 11:08:11 +0000
Subject: [PATCH 11/11] Fix pipe(2) function spec + remove fallback to pipe()

---
 libc/spec/linux.td                  | 6 ++----
 libc/src/unistd/linux/pipe2.cpp     | 4 +---
 libc/test/src/unistd/CMakeLists.txt | 2 +-
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index 80d3e860ed6c46..4cc5955f6c17eb 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -3,8 +3,6 @@ def StructEpollEventPtr : PtrType<StructEpollEvent>;
 
 def StructEpollData : NamedType<"struct epoll_data">;
 
-def Pipe2fdArrayT : NamedType<"__pipe2fd_array_t">;
-
 def Linux : StandardSpec<"Linux"> {
   HeaderSpec Errno = HeaderSpec<
       "errno.h",
@@ -269,13 +267,13 @@ def Linux : StandardSpec<"Linux"> {
   HeaderSpec UniStd = HeaderSpec<
     "unistd.h",
     [], // Macros
-    [Pipe2fdArrayT], // Types
+    [], // Types
     [], // Enumerations
     [
         FunctionSpec<
           "pipe2",
           RetValSpec<IntType>,
-          [ArgSpec<Pipe2fdArrayT>, ArgSpec<IntType>]
+          [ArgSpec<IntPtr>, ArgSpec<IntType>]
         >,
     ]
   >;
diff --git a/libc/src/unistd/linux/pipe2.cpp b/libc/src/unistd/linux/pipe2.cpp
index 6db83a0303a211..b0e705373d9c28 100644
--- a/libc/src/unistd/linux/pipe2.cpp
+++ b/libc/src/unistd/linux/pipe2.cpp
@@ -21,10 +21,8 @@ LLVM_LIBC_FUNCTION(int, pipe2, (int pipefd[2], int flags)) {
   int ret;
 #ifdef SYS_pipe2
   ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pipe2, pipefd, flags);
-#elif defined(SYS_pipe)
-  ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_pipe, pipefd);
 #else
-#error "pipe and pipe2 not available."
+#error "pipe2 not available."
 #endif
   if (ret < 0) {
     libc_errno = -ret;
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index e4d163f4e882f5..8734216756e302 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -460,4 +460,4 @@ add_libc_unittest(
     libc.src.unistd.read
     libc.src.unistd.write
     libc.test.UnitTest.ErrnoSetterMatcher
-)
\ No newline at end of file
+)



More information about the libc-commits mailing list