[libc-commits] [libc] [libc] pipe(2) linux syscall wrapper and unittest (PR #85514)
via libc-commits
libc-commits at lists.llvm.org
Sat Mar 16 03:59:06 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 1/4] 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 2/4] 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 3/4] 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 4/4] 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));
}
More information about the libc-commits
mailing list