From 34e161c73820630ca8bc60836f17cc71a56475ed Mon Sep 17 00:00:00 2001 From: c8ef Date: Tue, 28 Jan 2025 08:03:38 +0000 Subject: [PATCH 1/4] impl readv --- libc/config/linux/aarch64/entrypoints.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 1 + libc/include/sys/uio.yaml | 8 ++++++ libc/src/sys/uio/CMakeLists.txt | 7 ++++++ libc/src/sys/uio/linux/CMakeLists.txt | 15 ++++++++++++ libc/src/sys/uio/linux/readv.cpp | 27 ++++++++++++++++++++ libc/src/sys/uio/readv.h | 22 +++++++++++++++++ libc/test/src/sys/uio/CMakeLists.txt | 18 +++++++++++++- libc/test/src/sys/uio/readv_test.cpp | 30 +++++++++++++++++++++++ 9 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 libc/src/sys/uio/linux/readv.cpp create mode 100644 libc/src/sys/uio/readv.h create mode 100644 libc/test/src/sys/uio/readv_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 09eb51a3f8fc6..99b1187b43e11 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -355,6 +355,7 @@ set(TARGET_LIBC_ENTRYPOINTS # sys/uio.h entrypoints libc.src.sys.uio.writev + libc.src.sys.uio.readv ) if(LLVM_LIBC_INCLUDE_SCUDO) diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 366e4d34294d1..df85f87140b88 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -355,6 +355,7 @@ set(TARGET_LIBC_ENTRYPOINTS # sys/uio.h entrypoints libc.src.sys.uio.writev + libc.src.sys.uio.readv ) if(LLVM_LIBC_INCLUDE_SCUDO) diff --git a/libc/include/sys/uio.yaml b/libc/include/sys/uio.yaml index 87c5bdff48245..6d3f336b2b520 100644 --- a/libc/include/sys/uio.yaml +++ b/libc/include/sys/uio.yaml @@ -15,3 +15,11 @@ functions: - type: int - type: const struct iovec * - type: int + - name: readv + standards: + - POSIX + return_type: ssize_t + arguments: + - type: int + - type: const struct iovec * + - type: int diff --git a/libc/src/sys/uio/CMakeLists.txt b/libc/src/sys/uio/CMakeLists.txt index 6298f86cd937d..c6a6429790410 100644 --- a/libc/src/sys/uio/CMakeLists.txt +++ b/libc/src/sys/uio/CMakeLists.txt @@ -8,3 +8,10 @@ add_entrypoint_object( DEPENDS .${LIBC_TARGET_OS}.writev ) + +add_entrypoint_object( + readv + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.readv +) diff --git a/libc/src/sys/uio/linux/CMakeLists.txt b/libc/src/sys/uio/linux/CMakeLists.txt index 85a7a3ae4d5c2..7901c741f69a5 100644 --- a/libc/src/sys/uio/linux/CMakeLists.txt +++ b/libc/src/sys/uio/linux/CMakeLists.txt @@ -12,3 +12,18 @@ add_entrypoint_object( libc.hdr.types.ssize_t libc.hdr.types.struct_iovec ) + +add_entrypoint_object( + readv + SRCS + readv.cpp + HDRS + ../readv.h + DEPENDS + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.errno.errno + libc.hdr.types.ssize_t + libc.hdr.types.struct_iovec +) diff --git a/libc/src/sys/uio/linux/readv.cpp b/libc/src/sys/uio/linux/readv.cpp new file mode 100644 index 0000000000000..3812f4dec150b --- /dev/null +++ b/libc/src/sys/uio/linux/readv.cpp @@ -0,0 +1,27 @@ +//===-- Implementation file for readv -------------------------------------===// +// +// 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/sys/uio/readv.h" +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" +#include "src/errno/libc_errno.h" +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(ssize_t, readv, (int fd, const iovec *iov, int iovcnt)) { + long ret = LIBC_NAMESPACE::syscall_impl(SYS_readv, fd, iov, iovcnt); + // On failure, return -1 and set errno. + if (ret < 0) { + libc_errno = static_cast(-ret); + return -1; + } + // On success, return number of bytes read. + return static_cast(ret); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/uio/readv.h b/libc/src/sys/uio/readv.h new file mode 100644 index 0000000000000..135b1e6fd1b5a --- /dev/null +++ b/libc/src/sys/uio/readv.h @@ -0,0 +1,22 @@ +//===-- Implementation header for readv -----------------------------------===// +// +// 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_SYS_UIO_READV_H +#define LLVM_LIBC_SRC_SYS_UIO_READV_H + +#include "hdr/types/ssize_t.h" +#include "hdr/types/struct_iovec.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +ssize_t readv(int fd, const iovec *iov, int iovcnt); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_UIO_READV_H diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt index 45f8d14c16179..a58337ec5f01a 100644 --- a/libc/test/src/sys/uio/CMakeLists.txt +++ b/libc/test/src/sys/uio/CMakeLists.txt @@ -1,8 +1,9 @@ add_custom_target(libc_sys_uio_unittests) + add_libc_unittest( writev_test SUITE - libc_sys_uio_unittests + libc_sys_uio_unittests SRCS writev_test.cpp DEPENDS @@ -13,3 +14,18 @@ add_libc_unittest( libc.src.fcntl.open libc.test.UnitTest.ErrnoSetterMatcher ) + +add_libc_unittest( + readv_test + SUITE + libc_sys_uio_unittests + SRCS + readv_test.cpp + DEPENDS + libc.src.errno.errno + libc.src.__support.common + libc.src.sys.uio.readv + libc.src.unistd.close + libc.src.fcntl.open + libc.test.UnitTest.ErrnoSetterMatcher +) diff --git a/libc/test/src/sys/uio/readv_test.cpp b/libc/test/src/sys/uio/readv_test.cpp new file mode 100644 index 0000000000000..cf551d364653b --- /dev/null +++ b/libc/test/src/sys/uio/readv_test.cpp @@ -0,0 +1,30 @@ +//===-- Unittests for readv -----------------------------------------------===// +// +// 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/fcntl/open.h" +#include "src/sys/uio/readv.h" +#include "src/unistd/close.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" +#include "test/UnitTest/Test.h" + +using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; + +TEST(LlvmLibcSysUioReadvTest, SmokeTest) { + int fd = LIBC_NAMESPACE::open("/dev/urandom", O_RDONLY); + ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0))); + char buf0[2]; + char buf1[3]; + struct iovec iov[2]; + iov[0].iov_base = buf0; + iov[0].iov_len = 1; + iov[1].iov_base = buf1; + iov[1].iov_len = 2; + ASSERT_THAT(LIBC_NAMESPACE::readv(fd, iov, 2), + returns(EQ(3)).with_errno(EQ(0))); + ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); +} From b42222be21be61321ce3d75d380ee020940352f4 Mon Sep 17 00:00:00 2001 From: c8ef Date: Wed, 29 Jan 2025 02:31:32 +0000 Subject: [PATCH 2/4] Add IOV_MAX. --- libc/include/llvm-libc-macros/limits-macros.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libc/include/llvm-libc-macros/limits-macros.h b/libc/include/llvm-libc-macros/limits-macros.h index d4aa7ae539e8a..1bdfa5333df0a 100644 --- a/libc/include/llvm-libc-macros/limits-macros.h +++ b/libc/include/llvm-libc-macros/limits-macros.h @@ -235,4 +235,8 @@ #define _POSIX_PATH_MAX 256 #endif +#ifndef IOV_MAX +#define IOV_MAX 1024 +#endif // IOV_MAX + #endif // LLVM_LIBC_MACROS_LIMITS_MACROS_H From f8356d3cf53d127b0cec68556e42eccd710d8028 Mon Sep 17 00:00:00 2001 From: c8ef Date: Wed, 29 Jan 2025 02:39:09 +0000 Subject: [PATCH 3/4] address review comments --- libc/src/sys/uio/linux/CMakeLists.txt | 8 ++++---- libc/src/sys/uio/linux/readv.cpp | 2 ++ libc/src/sys/uio/linux/writev.cpp | 2 ++ libc/test/src/sys/uio/CMakeLists.txt | 10 ++++++---- libc/test/src/sys/uio/readv_test.cpp | 1 + libc/test/src/sys/uio/writev_test.cpp | 1 + 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libc/src/sys/uio/linux/CMakeLists.txt b/libc/src/sys/uio/linux/CMakeLists.txt index 7901c741f69a5..db4fe68e4ca9c 100644 --- a/libc/src/sys/uio/linux/CMakeLists.txt +++ b/libc/src/sys/uio/linux/CMakeLists.txt @@ -5,12 +5,12 @@ add_entrypoint_object( HDRS ../writev.h DEPENDS + libc.hdr.types.ssize_t + libc.hdr.types.struct_iovec libc.include.sys_syscall libc.src.__support.OSUtil.osutil libc.src.__support.common libc.src.errno.errno - libc.hdr.types.ssize_t - libc.hdr.types.struct_iovec ) add_entrypoint_object( @@ -20,10 +20,10 @@ add_entrypoint_object( HDRS ../readv.h DEPENDS + libc.hdr.types.ssize_t + libc.hdr.types.struct_iovec libc.include.sys_syscall libc.src.__support.OSUtil.osutil libc.src.__support.common libc.src.errno.errno - libc.hdr.types.ssize_t - libc.hdr.types.struct_iovec ) diff --git a/libc/src/sys/uio/linux/readv.cpp b/libc/src/sys/uio/linux/readv.cpp index 3812f4dec150b..f1393a9749be9 100644 --- a/libc/src/sys/uio/linux/readv.cpp +++ b/libc/src/sys/uio/linux/readv.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// #include "src/sys/uio/readv.h" +#include "hdr/types/ssize_t.h" +#include "hdr/types/struct_iovec.h" #include "src/__support/OSUtil/syscall.h" #include "src/__support/common.h" #include "src/errno/libc_errno.h" diff --git a/libc/src/sys/uio/linux/writev.cpp b/libc/src/sys/uio/linux/writev.cpp index a3bb8986d522e..8992bed95c982 100644 --- a/libc/src/sys/uio/linux/writev.cpp +++ b/libc/src/sys/uio/linux/writev.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// #include "src/sys/uio/writev.h" +#include "hdr/types/ssize_t.h" +#include "hdr/types/struct_iovec.h" #include "src/__support/OSUtil/syscall.h" #include "src/__support/common.h" #include "src/errno/libc_errno.h" diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt index a58337ec5f01a..cff6bbe3e7857 100644 --- a/libc/test/src/sys/uio/CMakeLists.txt +++ b/libc/test/src/sys/uio/CMakeLists.txt @@ -7,11 +7,12 @@ add_libc_unittest( SRCS writev_test.cpp DEPENDS - libc.src.errno.errno + 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.fcntl.open libc.test.UnitTest.ErrnoSetterMatcher ) @@ -22,10 +23,11 @@ add_libc_unittest( SRCS readv_test.cpp DEPENDS - libc.src.errno.errno + 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.fcntl.open 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 cf551d364653b..3acf2c151826d 100644 --- a/libc/test/src/sys/uio/readv_test.cpp +++ b/libc/test/src/sys/uio/readv_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/types/struct_iovec.h" #include "src/fcntl/open.h" #include "src/sys/uio/readv.h" #include "src/unistd/close.h" diff --git a/libc/test/src/sys/uio/writev_test.cpp b/libc/test/src/sys/uio/writev_test.cpp index a9a314813182d..1a559db0e5b89 100644 --- a/libc/test/src/sys/uio/writev_test.cpp +++ b/libc/test/src/sys/uio/writev_test.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/types/struct_iovec.h" #include "src/fcntl/open.h" #include "src/sys/uio/writev.h" #include "src/unistd/close.h" From b0f64ad7efbf3970397d506b5fb7a4b4ee01aa45 Mon Sep 17 00:00:00 2001 From: c8ef Date: Wed, 5 Feb 2025 14:34:02 +0000 Subject: [PATCH 4/4] get rid of linux specific file in test. --- libc/test/src/sys/uio/CMakeLists.txt | 3 +++ libc/test/src/sys/uio/readv_test.cpp | 14 +++++++++++++- libc/test/src/sys/uio/writev_test.cpp | 6 +++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libc/test/src/sys/uio/CMakeLists.txt b/libc/test/src/sys/uio/CMakeLists.txt index cff6bbe3e7857..7ba02be5d1cc4 100644 --- a/libc/test/src/sys/uio/CMakeLists.txt +++ b/libc/test/src/sys/uio/CMakeLists.txt @@ -13,6 +13,7 @@ add_libc_unittest( libc.src.fcntl.open libc.src.sys.uio.writev libc.src.unistd.close + libc.src.unistd.unlink libc.test.UnitTest.ErrnoSetterMatcher ) @@ -29,5 +30,7 @@ add_libc_unittest( libc.src.fcntl.open libc.src.sys.uio.readv libc.src.unistd.close + libc.src.unistd.unlink + 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 3acf2c151826d..7852b8a4b136d 100644 --- a/libc/test/src/sys/uio/readv_test.cpp +++ b/libc/test/src/sys/uio/readv_test.cpp @@ -10,13 +10,23 @@ #include "src/fcntl/open.h" #include "src/sys/uio/readv.h" #include "src/unistd/close.h" +#include "src/unistd/unlink.h" +#include "src/unistd/write.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; TEST(LlvmLibcSysUioReadvTest, SmokeTest) { - int fd = LIBC_NAMESPACE::open("/dev/urandom", O_RDONLY); + 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))); + const char data[] = "Hello, World!\n"; + ASSERT_THAT(LIBC_NAMESPACE::write(fd, data, sizeof(data)), + returns(EQ(sizeof(data))).with_errno(EQ(0))); + ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); + + fd = LIBC_NAMESPACE::open(filename, O_RDONLY); ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0))); char buf0[2]; char buf1[3]; @@ -28,4 +38,6 @@ TEST(LlvmLibcSysUioReadvTest, SmokeTest) { ASSERT_THAT(LIBC_NAMESPACE::readv(fd, iov, 2), returns(EQ(3)).with_errno(EQ(0))); ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); + ASSERT_THAT(LIBC_NAMESPACE::unlink(filename), + returns(EQ(0)).with_errno(EQ(0))); } diff --git a/libc/test/src/sys/uio/writev_test.cpp b/libc/test/src/sys/uio/writev_test.cpp index 1a559db0e5b89..2c1c445cc7868 100644 --- a/libc/test/src/sys/uio/writev_test.cpp +++ b/libc/test/src/sys/uio/writev_test.cpp @@ -10,13 +10,15 @@ #include "src/fcntl/open.h" #include "src/sys/uio/writev.h" #include "src/unistd/close.h" +#include "src/unistd/unlink.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; TEST(LlvmLibcSysUioWritevTest, SmokeTest) { - int fd = LIBC_NAMESPACE::open("/dev/null", O_WRONLY); + 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))); const char *data = "Hello, World!\n"; struct iovec iov[2]; @@ -27,4 +29,6 @@ TEST(LlvmLibcSysUioWritevTest, SmokeTest) { ASSERT_THAT(LIBC_NAMESPACE::writev(fd, iov, 2), returns(EQ(15)).with_errno(EQ(0))); ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); + ASSERT_THAT(LIBC_NAMESPACE::unlink(filename), + returns(EQ(0)).with_errno(EQ(0))); }