diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -62,6 +62,10 @@ def CTypeAPI : PublicAPI<"ctype.h"> { } +def FCntlAPI : PublicAPI<"fcntl.h"> { + let Types = ["mode_t"]; +} + def IntTypesAPI : PublicAPI<"inttypes.h"> { let Types = ["imaxdiv_t"]; } diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -20,6 +20,9 @@ # errno.h entrypoints libc.src.errno.__errno_location + # fcntl.h entrypoints + libc.src.fcntl.open + # string.h entrypoints libc.src.string.bcmp libc.src.string.bzero @@ -81,6 +84,9 @@ libc.src.sys.mman.munmap # unistd.h entrypoints + libc.src.unistd.close + libc.src.unistd.fsync + libc.src.unistd.read libc.src.unistd.write ) diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(llvm-libc-macros) add_subdirectory(llvm-libc-types) add_header( @@ -14,6 +15,16 @@ .llvm_libc_common_h ) +add_gen_header( + fcntl + DEF_FILE fcntl.h.def + GEN_HDR fcntl.h + DEPENDS + .llvm_libc_common_h + .llvm-libc-macros.fcntl_macros + .llvm-libc-types.mode_t +) + add_gen_header( fenv DEF_FILE fenv.h.def diff --git a/libc/include/fcntl.h.def b/libc/include/fcntl.h.def new file mode 100644 --- /dev/null +++ b/libc/include/fcntl.h.def @@ -0,0 +1,17 @@ +//===-- C standard library header fcntl.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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_FCNTL_H +#define LLVM_LIBC_FCNTL_H + +#include <__llvm-libc-common.h> +#include + +%%public_api() + +#endif // LLVM_LIBC_FCNTL_H diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -0,0 +1,9 @@ +add_subdirectory(linux) + +add_header( + fcntl_macros + HDR + fcntl-macros.h + DEPENDS + .linux.fcntl_macros +) diff --git a/libc/include/llvm-libc-macros/fcntl-macros.h b/libc/include/llvm-libc-macros/fcntl-macros.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-macros/fcntl-macros.h @@ -0,0 +1,8 @@ +#ifndef __LLVM_LIBC_MACROS_FCNTL_MACROS_H +#define __LLVM_LIBC_MACROS_FCNTL_MACROS_H + +#ifdef __unix__ +#include "linux/fcntl-macros.h" +#endif + +#endif // __LLVM_LIBC_MACROS_FCNTL_MACROS_H diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt @@ -0,0 +1,5 @@ +add_header( + fcntl_macros + HDR + fcntl-macros.h +) diff --git a/libc/include/llvm-libc-macros/linux/fcntl-macros.h b/libc/include/llvm-libc-macros/linux/fcntl-macros.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-macros/linux/fcntl-macros.h @@ -0,0 +1,52 @@ +//===-- Definition of macros from fcntl.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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H +#define __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H + +// File creation flags +#define O_CLOEXEC 02000000 +#define O_CREAT 00000100 +#define O_DIRECTORY 00200000 +#define O_EXCL 00000200 +#define O_NOCTTY 00000400 +#define O_NOFOLLOW 00400000 +#define O_TRUNC 00001000 +#define O_TMPFILE (020000000 | O_DIRECTORY) + +// File status flags +#define O_APPEND 00002000 +#define O_DSYNC 00010000 +#define O_NONBLOCK 00004000 +#define O_SYNC 04000000 | O_DSYNC + +// File access mode mask +#define O_ACCMODE 00000003 + +// File access mode flags +#define O_RDONLY 00000000 +#define O_RDWR 00000002 +#define O_WRONLY 00000001 + +// File mode flags +#define S_IRWXU 0700 +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#define S_IXUSR 0100 +#define S_IRWXG 070 +#define S_IRGRP 040 +#define S_IWGRP 020 +#define S_IXGRP 010 +#define S_IRWXO 07 +#define S_IROTH 04 +#define S_IWOTH 02 +#define S_IXOTH 01 +#define S_ISUID 04000 +#define S_ISGID 02000 + +#endif // __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -12,6 +12,7 @@ add_header(fexcept_t HDR fexcept_t.h) add_header(float_t HDR float_t.h) add_header(imaxdiv_t HDR imaxdiv_t.h) +add_header(mode_t HDR mode_t.h) add_header(mtx_t HDR mtx_t.h) add_header(off_t HDR off_t.h) add_header(once_flag HDR once_flag.h) diff --git a/libc/include/llvm-libc-types/mode_t.h b/libc/include/llvm-libc-types/mode_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/mode_t.h @@ -0,0 +1,14 @@ +//===-- Definition of mode_t type -----------------------------------------===// +// +// 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_TYPES_MODE_T_H +#define __LLVM_LIBC_TYPES_MODE_T_H + +typedef unsigned mode_t; + +#endif // __LLVM_LIBC_TYPES_MODE_T_H diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -17,6 +17,7 @@ ConstType ConstCharPtr = ConstType; ConstType ConstRestrictedCharPtr = ConstType; + NamedType ModeTType = NamedType<"mode_t">; NamedType OffTType = NamedType<"off_t">; NamedType SSizeTType = NamedType<"ssize_t">; @@ -107,6 +108,20 @@ [] // Functions >; + HeaderSpec FCntl = HeaderSpec< + "fcntl.h", + [], // Macros + [ModeTType], + [], // Enumerations + [ + FunctionSpec< + "open", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, + ] + >; + HeaderSpec SysMMan = HeaderSpec< "sys/mman.h", [ @@ -202,6 +217,21 @@ ], [], // Enumerations [ + FunctionSpec< + "close", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "fsync", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "read", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, FunctionSpec< "write", RetValSpec, @@ -280,6 +310,7 @@ let Headers = [ CType, Errno, + FCntl, SysMMan, Signal, UniStd, diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(stdlib) if(${LIBC_TARGET_OS} STREQUAL "linux") + add_subdirectory(fcntl) add_subdirectory(sys) add_subdirectory(unistd) endif() diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/fcntl/CMakeLists.txt copy from libc/src/unistd/CMakeLists.txt copy to libc/src/fcntl/CMakeLists.txt --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/fcntl/CMakeLists.txt @@ -3,8 +3,8 @@ endif() add_entrypoint_object( - write + open ALIAS DEPENDS - .${LIBC_TARGET_OS}.write + .${LIBC_TARGET_OS}.open ) diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/fcntl/linux/CMakeLists.txt copy from libc/src/unistd/linux/CMakeLists.txt copy to libc/src/fcntl/linux/CMakeLists.txt --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/fcntl/linux/CMakeLists.txt @@ -1,12 +1,12 @@ add_entrypoint_object( - write + open SRCS - write.cpp + open.cpp HDRS - ../write.h + ../open.h DEPENDS - libc.include.unistd - libc.include.sys_syscall + libc.include.errno + libc.include.fcntl libc.src.__support.OSUtil.osutil libc.src.errno.__errno_location ) diff --git a/libc/src/fcntl/linux/open.cpp b/libc/src/fcntl/linux/open.cpp new file mode 100644 --- /dev/null +++ b/libc/src/fcntl/linux/open.cpp @@ -0,0 +1,40 @@ +//===-- Implementation of open --------------------------------------------===// +// +// 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/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" + +#include +#include +#include +#include // For syscall numbers. + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, open, (const char *path, int flags, ...)) { + mode_t mode_flags = 0; + // O_TMPFILE is a multi-bit flag so we test all bits by checking for equality + // with O_TMPFILE + if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { + va_list varargs; + va_start(varargs, flags); + mode_flags = va_arg(varargs, mode_t); + va_end(varargs); + } + + int fd = __llvm_libc::syscall(SYS_open, path, flags, mode_flags); + if (fd > 0) + return fd; + + errno = -fd; + return -1; +} + +} // namespace __llvm_libc diff --git a/libc/src/fcntl/open.h b/libc/src/fcntl/open.h new file mode 100644 --- /dev/null +++ b/libc/src/fcntl/open.h @@ -0,0 +1,20 @@ +//===-- Implementation header of open ---------------------------*- 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_FCNTL_OPEN_H +#define LLVM_LIBC_SRC_FCNTL_OPEN_H + +#include + +namespace __llvm_libc { + +int open(const char *path, int flags, ...); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_FCNTL_OPEN_H diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -2,6 +2,27 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() +add_entrypoint_object( + close + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.close +) + +add_entrypoint_object( + fsync + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.fsync +) + +add_entrypoint_object( + read + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.read +) + add_entrypoint_object( write ALIAS diff --git a/libc/src/unistd/close.h b/libc/src/unistd/close.h new file mode 100644 --- /dev/null +++ b/libc/src/unistd/close.h @@ -0,0 +1,18 @@ +//===-- Implementation header for close -------------------------*- 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_CLOSE_H +#define LLVM_LIBC_SRC_UNISTD_CLOSE_H + +namespace __llvm_libc { + +int close(int fd); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_CLOSE_H diff --git a/libc/src/unistd/fsync.h b/libc/src/unistd/fsync.h new file mode 100644 --- /dev/null +++ b/libc/src/unistd/fsync.h @@ -0,0 +1,18 @@ +//===-- Implementation header for fsync -------------------------*- 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_FSYNC_H +#define LLVM_LIBC_SRC_UNISTD_FSYNC_H + +namespace __llvm_libc { + +int fsync(int fd); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_FSYNC_H diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/unistd/linux/CMakeLists.txt @@ -1,3 +1,42 @@ +add_entrypoint_object( + close + SRCS + close.cpp + HDRS + ../close.h + DEPENDS + libc.include.unistd + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.__errno_location +) + +add_entrypoint_object( + fsync + SRCS + fsync.cpp + HDRS + ../fsync.h + DEPENDS + libc.include.unistd + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.__errno_location +) + +add_entrypoint_object( + read + SRCS + read.cpp + HDRS + ../read.h + DEPENDS + libc.include.unistd + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.__errno_location +) + add_entrypoint_object( write SRCS diff --git a/libc/src/unistd/linux/write.cpp b/libc/src/unistd/linux/close.cpp copy from libc/src/unistd/linux/write.cpp copy to libc/src/unistd/linux/close.cpp --- a/libc/src/unistd/linux/write.cpp +++ b/libc/src/unistd/linux/close.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of write -------------------------------------===// +//===-- Linux implementation of close -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "src/unistd/write.h" +#include "src/unistd/close.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include -#include // For syscall numbers. +#include // For syscall numbers. namespace __llvm_libc { -LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) { - long ret = __llvm_libc::syscall(SYS_write, fd, buf, count); +LLVM_LIBC_FUNCTION(int, close, (int fd)) { + long ret = __llvm_libc::syscall(SYS_close, fd); if (ret < 0) { errno = -ret; return -1; diff --git a/libc/src/unistd/linux/write.cpp b/libc/src/unistd/linux/fsync.cpp copy from libc/src/unistd/linux/write.cpp copy to libc/src/unistd/linux/fsync.cpp --- a/libc/src/unistd/linux/write.cpp +++ b/libc/src/unistd/linux/fsync.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of write -------------------------------------===// +//===-- Linux implementation of fsync -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "src/unistd/write.h" +#include "src/unistd/fsync.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include -#include // For syscall numbers. +#include // For syscall numbers. namespace __llvm_libc { -LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) { - long ret = __llvm_libc::syscall(SYS_write, fd, buf, count); +LLVM_LIBC_FUNCTION(int, fsync, (int fd)) { + long ret = __llvm_libc::syscall(SYS_fsync, fd); if (ret < 0) { errno = -ret; return -1; diff --git a/libc/src/unistd/linux/write.cpp b/libc/src/unistd/linux/read.cpp copy from libc/src/unistd/linux/write.cpp copy to libc/src/unistd/linux/read.cpp --- a/libc/src/unistd/linux/write.cpp +++ b/libc/src/unistd/linux/read.cpp @@ -1,4 +1,4 @@ -//===-- Linux implementation of write -------------------------------------===// +//===-- Linux implementation of read --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "src/unistd/write.h" +#include "src/unistd/read.h" #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include -#include // For syscall numbers. +#include // For syscall numbers. namespace __llvm_libc { -LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) { - long ret = __llvm_libc::syscall(SYS_write, fd, buf, count); +LLVM_LIBC_FUNCTION(ssize_t, read, (int fd, void *buf, size_t count)) { + long ret = __llvm_libc::syscall(SYS_read, fd, buf, count); if (ret < 0) { errno = -ret; return -1; diff --git a/libc/src/unistd/linux/write.cpp b/libc/src/unistd/linux/write.cpp --- a/libc/src/unistd/linux/write.cpp +++ b/libc/src/unistd/linux/write.cpp @@ -12,7 +12,7 @@ #include "src/__support/common.h" #include -#include // For syscall numbers. +#include // For syscall numbers. namespace __llvm_libc { diff --git a/libc/src/unistd/read.h b/libc/src/unistd/read.h new file mode 100644 --- /dev/null +++ b/libc/src/unistd/read.h @@ -0,0 +1,20 @@ +//===-- Implementation header for read --------------------------*- 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_READ_H +#define LLVM_LIBC_SRC_UNISTD_READ_H + +#include + +namespace __llvm_libc { + +ssize_t read(int fd, void *buf, size_t count); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_READ_H diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -1,14 +1,18 @@ add_libc_testsuite(libc_unistd_unittests) add_libc_unittest( - write_test + read_write_test SUITE libc_unistd_unittests SRCS - write_test.cpp + read_write_test.cpp DEPENDS libc.include.errno libc.include.unistd + libc.src.fcntl.open + libc.src.unistd.close + libc.src.unistd.fsync + libc.src.unistd.read libc.src.unistd.write libc.test.errno_setter_matcher ) diff --git a/libc/test/src/unistd/read_write_test.cpp b/libc/test/src/unistd/read_write_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/unistd/read_write_test.cpp @@ -0,0 +1,59 @@ +//===-- Unittests for read and write --------------------------------------===// +// +// 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/unistd/close.h" +#include "src/unistd/fsync.h" +#include "src/unistd/read.h" +#include "src/unistd/write.h" +#include "test/ErrnoSetterMatcher.h" +#include "utils/UnitTest/Test.h" +#include "utils/testutils/FDReader.h" + +#include + +TEST(LlvmLibcUniStd, WriteAndReadBackTest) { + using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; + constexpr const char *TEST_FILE = "__unistd_read_write.test"; + int write_fd = __llvm_libc::open(TEST_FILE, O_WRONLY | O_CREAT); + ASSERT_EQ(errno, 0); + ASSERT_GT(write_fd, 0); + constexpr const char HELLO[] = "hello"; + constexpr int HELLO_SIZE = sizeof(HELLO); + ASSERT_THAT(__llvm_libc::write(write_fd, HELLO, HELLO_SIZE), + Succeeds(HELLO_SIZE)); + ASSERT_THAT(__llvm_libc::fsync(write_fd), Succeeds(0)); + ASSERT_THAT(__llvm_libc::close(write_fd), Succeeds(0)); + + int read_fd = __llvm_libc::open(TEST_FILE, O_RDONLY); + ASSERT_EQ(errno, 0); + ASSERT_GT(read_fd, 0); + char read_buf[10]; + ASSERT_THAT(__llvm_libc::read(read_fd, read_buf, HELLO_SIZE), + Succeeds(HELLO_SIZE)); + EXPECT_STREQ(read_buf, HELLO); + ASSERT_THAT(__llvm_libc::close(read_fd), Succeeds(0)); + + // TODO: 'remove' the test file after the test. +} + +TEST(LlvmLibcUniStd, WriteFails) { + using __llvm_libc::testing::ErrnoSetterMatcher::Fails; + + EXPECT_THAT(__llvm_libc::write(-1, "", 1), Fails(EBADF)); + EXPECT_THAT(__llvm_libc::write(1, reinterpret_cast(-1), 1), + Fails(EFAULT)); +} + +TEST(LlvmLibcUniStd, ReadFails) { + using __llvm_libc::testing::ErrnoSetterMatcher::Fails; + + EXPECT_THAT(__llvm_libc::read(-1, nullptr, 1), Fails(EBADF)); + EXPECT_THAT(__llvm_libc::read(0, reinterpret_cast(-1), 1), + Fails(EFAULT)); +} diff --git a/libc/test/src/unistd/write_test.cpp b/libc/test/src/unistd/write_test.cpp deleted file mode 100644 --- a/libc/test/src/unistd/write_test.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//===-- Unittests for write -----------------------------------------------===// -// -// 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/write.h" -#include "test/ErrnoSetterMatcher.h" -#include "utils/UnitTest/Test.h" -#include "utils/testutils/FDReader.h" - -#include - -TEST(LlvmLibcUniStd, WriteBasic) { - using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; - constexpr const char *HELLO = "hello"; - __llvm_libc::testutils::FDReader reader; - EXPECT_THAT(__llvm_libc::write(reader.get_write_fd(), HELLO, 5), Succeeds(5)); - EXPECT_TRUE(reader.match_written(HELLO)); -} - -TEST(LlvmLibcUniStd, WriteFails) { - using __llvm_libc::testing::ErrnoSetterMatcher::Fails; - - EXPECT_THAT(__llvm_libc::write(-1, "", 1), Fails(EBADF)); - EXPECT_THAT(__llvm_libc::write(1, reinterpret_cast(-1), 1), - Fails(EFAULT)); -}