Skip to content

Commit e1c63bb

Browse files
authored
[libc] implement sys/uio/readv (llvm#124718)
Closes llvm#124694. This patch adds the `sys/uio/readv` function. ref: https://pubs.opengroup.org/onlinepubs/009696699/functions/readv.html
1 parent 6e14d75 commit e1c63bb

File tree

12 files changed

+161
-3
lines changed

12 files changed

+161
-3
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ set(TARGET_LIBC_ENTRYPOINTS
359359

360360
# sys/uio.h entrypoints
361361
libc.src.sys.uio.writev
362+
libc.src.sys.uio.readv
362363
)
363364

364365
if(LLVM_LIBC_INCLUDE_SCUDO)

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ set(TARGET_LIBC_ENTRYPOINTS
359359

360360
# sys/uio.h entrypoints
361361
libc.src.sys.uio.writev
362+
libc.src.sys.uio.readv
362363
)
363364

364365
if(LLVM_LIBC_INCLUDE_SCUDO)

libc/include/llvm-libc-macros/limits-macros.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,8 @@
239239
#define _POSIX_ARG_MAX 4096
240240
#endif
241241

242+
#ifndef IOV_MAX
243+
#define IOV_MAX 1024
244+
#endif // IOV_MAX
245+
242246
#endif // LLVM_LIBC_MACROS_LIMITS_MACROS_H

libc/include/sys/uio.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,11 @@ functions:
1515
- type: int
1616
- type: const struct iovec *
1717
- type: int
18+
- name: readv
19+
standards:
20+
- POSIX
21+
return_type: ssize_t
22+
arguments:
23+
- type: int
24+
- type: const struct iovec *
25+
- type: int

libc/src/sys/uio/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@ add_entrypoint_object(
88
DEPENDS
99
.${LIBC_TARGET_OS}.writev
1010
)
11+
12+
add_entrypoint_object(
13+
readv
14+
ALIAS
15+
DEPENDS
16+
.${LIBC_TARGET_OS}.readv
17+
)

libc/src/sys/uio/linux/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,25 @@ add_entrypoint_object(
55
HDRS
66
../writev.h
77
DEPENDS
8+
libc.hdr.types.ssize_t
9+
libc.hdr.types.struct_iovec
810
libc.include.sys_syscall
911
libc.src.__support.OSUtil.osutil
1012
libc.src.__support.common
1113
libc.src.errno.errno
14+
)
15+
16+
add_entrypoint_object(
17+
readv
18+
SRCS
19+
readv.cpp
20+
HDRS
21+
../readv.h
22+
DEPENDS
1223
libc.hdr.types.ssize_t
1324
libc.hdr.types.struct_iovec
25+
libc.include.sys_syscall
26+
libc.src.__support.OSUtil.osutil
27+
libc.src.__support.common
28+
libc.src.errno.errno
1429
)

libc/src/sys/uio/linux/readv.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===-- Implementation file for readv -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "src/sys/uio/readv.h"
9+
#include "hdr/types/ssize_t.h"
10+
#include "hdr/types/struct_iovec.h"
11+
#include "src/__support/OSUtil/syscall.h"
12+
#include "src/__support/common.h"
13+
#include "src/errno/libc_errno.h"
14+
#include <sys/syscall.h>
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
LLVM_LIBC_FUNCTION(ssize_t, readv, (int fd, const iovec *iov, int iovcnt)) {
19+
long ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_readv, fd, iov, iovcnt);
20+
// On failure, return -1 and set errno.
21+
if (ret < 0) {
22+
libc_errno = static_cast<int>(-ret);
23+
return -1;
24+
}
25+
// On success, return number of bytes read.
26+
return static_cast<ssize_t>(ret);
27+
}
28+
29+
} // namespace LIBC_NAMESPACE_DECL

libc/src/sys/uio/linux/writev.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88
#include "src/sys/uio/writev.h"
9+
#include "hdr/types/ssize_t.h"
10+
#include "hdr/types/struct_iovec.h"
911
#include "src/__support/OSUtil/syscall.h"
1012
#include "src/__support/common.h"
1113
#include "src/errno/libc_errno.h"

libc/src/sys/uio/readv.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Implementation header for readv -----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SYS_UIO_READV_H
10+
#define LLVM_LIBC_SRC_SYS_UIO_READV_H
11+
12+
#include "hdr/types/ssize_t.h"
13+
#include "hdr/types/struct_iovec.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
ssize_t readv(int fd, const iovec *iov, int iovcnt);
19+
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SRC_SYS_UIO_READV_H

libc/test/src/sys/uio/CMakeLists.txt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
11
add_custom_target(libc_sys_uio_unittests)
2+
23
add_libc_unittest(
34
writev_test
45
SUITE
5-
libc_sys_uio_unittests
6+
libc_sys_uio_unittests
67
SRCS
78
writev_test.cpp
89
DEPENDS
9-
libc.src.errno.errno
10+
libc.hdr.types.struct_iovec
1011
libc.src.__support.common
12+
libc.src.errno.errno
13+
libc.src.fcntl.open
1114
libc.src.sys.uio.writev
1215
libc.src.unistd.close
16+
libc.src.unistd.unlink
17+
libc.test.UnitTest.ErrnoSetterMatcher
18+
)
19+
20+
add_libc_unittest(
21+
readv_test
22+
SUITE
23+
libc_sys_uio_unittests
24+
SRCS
25+
readv_test.cpp
26+
DEPENDS
27+
libc.hdr.types.struct_iovec
28+
libc.src.__support.common
29+
libc.src.errno.errno
1330
libc.src.fcntl.open
31+
libc.src.sys.uio.readv
32+
libc.src.unistd.close
33+
libc.src.unistd.unlink
34+
libc.src.unistd.write
1435
libc.test.UnitTest.ErrnoSetterMatcher
1536
)

libc/test/src/sys/uio/readv_test.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===-- Unittests for readv -----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "hdr/types/struct_iovec.h"
10+
#include "src/fcntl/open.h"
11+
#include "src/sys/uio/readv.h"
12+
#include "src/unistd/close.h"
13+
#include "src/unistd/unlink.h"
14+
#include "src/unistd/write.h"
15+
#include "test/UnitTest/ErrnoSetterMatcher.h"
16+
#include "test/UnitTest/Test.h"
17+
18+
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
19+
20+
TEST(LlvmLibcSysUioReadvTest, SmokeTest) {
21+
const char *filename = "./LlvmLibcSysUioReadvTest";
22+
int fd = LIBC_NAMESPACE::open(filename, O_WRONLY | O_CREAT, 0644);
23+
ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
24+
const char data[] = "Hello, World!\n";
25+
ASSERT_THAT(LIBC_NAMESPACE::write(fd, data, sizeof(data)),
26+
returns(EQ(sizeof(data))).with_errno(EQ(0)));
27+
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
28+
29+
fd = LIBC_NAMESPACE::open(filename, O_RDONLY);
30+
ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
31+
char buf0[2];
32+
char buf1[3];
33+
struct iovec iov[2];
34+
iov[0].iov_base = buf0;
35+
iov[0].iov_len = 1;
36+
iov[1].iov_base = buf1;
37+
iov[1].iov_len = 2;
38+
ASSERT_THAT(LIBC_NAMESPACE::readv(fd, iov, 2),
39+
returns(EQ(3)).with_errno(EQ(0)));
40+
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
41+
ASSERT_THAT(LIBC_NAMESPACE::unlink(filename),
42+
returns(EQ(0)).with_errno(EQ(0)));
43+
}

libc/test/src/sys/uio/writev_test.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "hdr/types/struct_iovec.h"
910
#include "src/fcntl/open.h"
1011
#include "src/sys/uio/writev.h"
1112
#include "src/unistd/close.h"
13+
#include "src/unistd/unlink.h"
1214
#include "test/UnitTest/ErrnoSetterMatcher.h"
1315
#include "test/UnitTest/Test.h"
1416

1517
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
1618

1719
TEST(LlvmLibcSysUioWritevTest, SmokeTest) {
18-
int fd = LIBC_NAMESPACE::open("/dev/null", O_WRONLY);
20+
const char *filename = "./LlvmLibcSysUioWritevTest";
21+
int fd = LIBC_NAMESPACE::open(filename, O_WRONLY | O_CREAT, 0644);
1922
ASSERT_THAT(fd, returns(GT(0)).with_errno(EQ(0)));
2023
const char *data = "Hello, World!\n";
2124
struct iovec iov[2];
@@ -26,4 +29,6 @@ TEST(LlvmLibcSysUioWritevTest, SmokeTest) {
2629
ASSERT_THAT(LIBC_NAMESPACE::writev(fd, iov, 2),
2730
returns(EQ(15)).with_errno(EQ(0)));
2831
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
32+
ASSERT_THAT(LIBC_NAMESPACE::unlink(filename),
33+
returns(EQ(0)).with_errno(EQ(0)));
2934
}

0 commit comments

Comments
 (0)