def UniStdAPI : PublicAPI<"unistd.h"> {
let Types = ["size_t", "ssize_t"];
}
+
+def SysStatAPI : PublicAPI<"sys/stat.h"> {
+ let Types = ["mode_t"];
+}
libc.src.sys.mman.mmap
libc.src.sys.mman.munmap
+ # sys/stat.h entrypoints
+ libc.src.sys.stat.mkdir
+ libc.src.sys.stat.mkdirat
+
# unistd.h entrypoints
libc.src.unistd.close
libc.src.unistd.fsync
libc.src.unistd.read
+ libc.src.unistd.rmdir
+ libc.src.unistd.unlink
+ libc.src.unistd.unlinkat
libc.src.unistd.write
)
)
add_gen_header(
+ sys_stat
+ DEF_FILE sys/stat.h.def
+ GEN_HDR sys/stat.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-types.mode_t
+)
+
+add_gen_header(
sys_syscall
DEF_FILE sys/syscall.h.def
GEN_HDR sys/syscall.h
// openat is relative to the current directory.
#define AT_FDCWD -100
+// Special flag to the function unlinkat to indicate that it
+// has to perform the equivalent of "rmdir" on the path argument.
+#define AT_REMOVEDIR 0x200
+
#endif // __LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
--- /dev/null
+//===-- POSIX header stat.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_SYS_STAT_H
+#define LLVM_LIBC_SYS_STAT_H
+
+#include <__llvm-libc-common.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_SYS_STAT_H
[ArgSpec<IntType>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
>,
FunctionSpec<
+ "rmdir",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>]
+ >,
+ FunctionSpec<
+ "unlink",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>]
+ >,
+ FunctionSpec<
+ "unlinkat",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<ConstCharPtr>, ArgSpec<IntType>]
+ >,
+ FunctionSpec<
"write",
RetValSpec<SSizeTType>,
[ArgSpec<IntType>, ArgSpec<ConstVoidPtr>, ArgSpec<SizeTType>]
]
>;
+ HeaderSpec SysStat = HeaderSpec<
+ "sys/stat.h",
+ [], // Macros
+ [ModeTType], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<
+ "mkdir",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>, ArgSpec<ModeTType>]
+ >,
+ FunctionSpec<
+ "mkdirat",
+ RetValSpec<IntType>,
+ [ArgSpec<IntType>, ArgSpec<ConstCharPtr>, ArgSpec<ModeTType>]
+ >,
+ ]
+ >;
+
let Headers = [
CType,
Errno,
FCntl,
- SysMMan,
Signal,
+ SysMMan,
+ SysStat,
UniStd,
String
];
add_subdirectory(mman)
+add_subdirectory(stat)
--- /dev/null
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+ mkdir
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.mkdir
+)
+
+add_entrypoint_object(
+ mkdirat
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.mkdirat
+)
--- /dev/null
+add_entrypoint_object(
+ mkdir
+ SRCS
+ mkdir.cpp
+ HDRS
+ ../mkdir.h
+ DEPENDS
+ libc.include.sys_stat
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.__errno_location
+)
+
+add_entrypoint_object(
+ mkdirat
+ SRCS
+ mkdirat.cpp
+ HDRS
+ ../mkdirat.h
+ DEPENDS
+ libc.include.sys_stat
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.__errno_location
+)
--- /dev/null
+//===-- Linux implementation of mkdir -------------------------------------===//
+//
+// 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/stat/mkdir.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, mkdir, (const char *path, mode_t mode)) {
+#ifdef SYS_mkdir
+ long ret = __llvm_libc::syscall(SYS_mkdir, path, mode);
+#elif defined(SYS_unlinkat)
+ long ret = __llvm_libc::syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+#else
+#error "mkdir and mkdirat syscalls not available."
+#endif
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Linux implementation of mkdirat -----------------------------------===//
+//
+// 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/stat/mkdirat.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, mkdirat, (int dfd, const char *path, mode_t mode)) {
+#ifdef SYS_unlinkat
+ long ret = __llvm_libc::syscall(SYS_mkdirat, dfd, path, mode);
+#else
+#error "mkdirat syscalls not available."
+#endif
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Implementation header for mkdir -------------------------*- 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_SYS_STAT_MKDIR_H
+#define LLVM_LIBC_SRC_SYS_STAT_MKDIR_H
+
+#include <sys/stat.h>
+
+namespace __llvm_libc {
+
+int mkdir(const char *path, mode_t mode);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SYS_STAT_MKDIR_H
--- /dev/null
+//===-- Implementation header for mkdirat -----------------------*- 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_SYS_STAT_MKDIRAT_H
+#define LLVM_LIBC_SRC_SYS_STAT_MKDIRAT_H
+
+#include <sys/stat.h>
+
+namespace __llvm_libc {
+
+int mkdirat(int dfd, const char *path, mode_t mode);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SYS_STAT_MKDIRAT_H
)
add_entrypoint_object(
+ rmdir
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.rmdir
+)
+
+add_entrypoint_object(
+ unlink
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.unlink
+)
+
+add_entrypoint_object(
+ unlinkat
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.unlinkat
+)
+
+add_entrypoint_object(
write
ALIAS
DEPENDS
)
add_entrypoint_object(
+ rmdir
+ SRCS
+ rmdir.cpp
+ HDRS
+ ../rmdir.h
+ DEPENDS
+ libc.include.unistd
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.__errno_location
+)
+
+add_entrypoint_object(
+ unlink
+ SRCS
+ unlink.cpp
+ HDRS
+ ../unlink.h
+ DEPENDS
+ libc.include.unistd
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.__errno_location
+)
+
+add_entrypoint_object(
+ unlinkat
+ SRCS
+ unlinkat.cpp
+ HDRS
+ ../unlinkat.h
+ DEPENDS
+ libc.include.unistd
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.__errno_location
+)
+
+add_entrypoint_object(
write
SRCS
write.cpp
--- /dev/null
+//===-- Linux implementation of rmdir -------------------------------------===//
+//
+// 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/rmdir.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, rmdir, (const char *path)) {
+#ifdef SYS_rmdir
+ long ret = __llvm_libc::syscall(SYS_rmdir, path);
+#elif defined(SYS_unlinkat)
+ long ret = __llvm_libc::syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#else
+#error "rmdir and unlinkat syscalls not available."
+#endif
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Linux implementation of unlink ------------------------------------===//
+//
+// 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/unlink.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, unlink, (const char *path)) {
+#ifdef SYS_unlink
+ long ret = __llvm_libc::syscall(SYS_unlink, path);
+#elif defined(SYS_unlinkat)
+ long ret = __llvm_libc::syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#else
+#error "Unlink syscalls not available."
+#endif
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Linux implementation of unlinkat ----------------------------------===//
+//
+// 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/unlinkat.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, unlinkat, (int dfd, const char *path, int flags)) {
+#ifdef SYS_unlinkat
+ long ret = __llvm_libc::syscall(SYS_unlinkat, dfd, path, flags);
+#else
+#error "unlinkat syscall not available."
+#endif
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Implementation header for rmdir -------------------------*- 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_RMDIR_H
+#define LLVM_LIBC_SRC_UNISTD_RMDIR_H
+
+namespace __llvm_libc {
+
+int rmdir(const char *path);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_UNISTD_RMDIR_H
--- /dev/null
+//===-- Implementation header for unlink ------------------------*- 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_UNLINK_H
+#define LLVM_LIBC_SRC_UNISTD_UNLINK_H
+
+namespace __llvm_libc {
+
+int unlink(const char *path);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_UNISTD_UNLINK_H
--- /dev/null
+//===-- Implementation header for unlinkat ----------------------*- 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_UNLINKAT_H
+#define LLVM_LIBC_SRC_UNISTD_UNLINKAT_H
+
+namespace __llvm_libc {
+
+int unlinkat(int dfd, const char *path, int flags);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_UNISTD_UNLINKAT_H
add_subdirectory(mman)
+add_subdirectory(stat)
--- /dev/null
+add_libc_testsuite(libc_sys_stat_unittests)
+
+add_subdirectory(testdata)
+
+add_libc_unittest(
+ mkdirat_test
+ SUITE
+ libc_sys_stat_unittests
+ SRCS
+ mkdirat_test.cpp
+ DEPENDS
+ libc.include.errno
+ libc.include.fcntl
+ libc.include.sys_stat
+ libc.src.sys.stat.mkdirat
+ libc.src.unistd.rmdir
+)
--- /dev/null
+//===-- Unittests for mkdirat ---------------------------------------------===//
+//
+// 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/stat/mkdirat.h"
+#include "src/unistd/rmdir.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+#include "utils/testutils/FDReader.h"
+
+#include <errno.h>
+#include <fcntl.h>
+
+TEST(LlvmLibcMkdiratTest, CreateAndRemove) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_DIR = "testdata/rmdir.testdir";
+ ASSERT_THAT(__llvm_libc::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU), Succeeds(0));
+ ASSERT_THAT(__llvm_libc::rmdir(TEST_DIR), Succeeds(0));
+}
+
+TEST(LlvmLibcMkdiratTest, BadPath) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+ ASSERT_THAT(__llvm_libc::mkdirat(AT_FDCWD, "non-existent-dir/test", S_IRWXU),
+ Fails(ENOENT));
+}
--- /dev/null
+# This directory will be used to create test files and delete them
+# from tests.
add_libc_testsuite(libc_unistd_unittests)
+add_subdirectory(testdata)
+
add_libc_unittest(
read_write_test
SUITE
libc.src.unistd.write
libc.test.errno_setter_matcher
)
+
+add_libc_unittest(
+ rmdir_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ rmdir_test.cpp
+ DEPENDS
+ libc.include.errno
+ libc.include.fcntl
+ libc.src.sys.stat.mkdir
+ libc.src.unistd.rmdir
+)
+
+add_libc_unittest(
+ unlink_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ unlink_test.cpp
+ DEPENDS
+ libc.include.errno
+ libc.include.unistd
+ libc.src.fcntl.open
+ libc.src.unistd.close
+ libc.src.unistd.unlink
+)
+
+add_libc_unittest(
+ unlinkat_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ unlinkat_test.cpp
+ DEPENDS
+ libc.include.errno
+ libc.include.unistd
+ libc.src.fcntl.open
+ libc.src.fcntl.openat
+ libc.src.unistd.close
+ libc.src.unistd.unlinkat
+)
--- /dev/null
+//===-- Unittests for rmdir -----------------------------------------------===//
+//
+// 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/stat/mkdir.h"
+#include "src/unistd/rmdir.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+#include "utils/testutils/FDReader.h"
+
+#include <errno.h>
+#include <fcntl.h>
+
+TEST(LlvmLibcRmdirTest, CreateAndRemove) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_DIR = "testdata/rmdir.testdir";
+ ASSERT_THAT(__llvm_libc::mkdir(TEST_DIR, S_IRWXU), Succeeds(0));
+ ASSERT_THAT(__llvm_libc::rmdir(TEST_DIR), Succeeds(0));
+}
+
+TEST(LlvmLibcRmdirTest, RemoveNonExistentDir) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+ ASSERT_THAT(__llvm_libc::rmdir("testdata/non-existent-dir"), Fails(ENOENT));
+}
--- /dev/null
+# This directory will be used to create test files and delete them
+# from tests.
--- /dev/null
+//===-- Unittests for unlink ----------------------------------------------===//
+//
+// 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/unlink.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+#include "utils/testutils/FDReader.h"
+
+#include <errno.h>
+
+TEST(LlvmLibcUnlinkTest, CreateAndUnlink) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_FILE = "testdata/unlink.test";
+ int write_fd = __llvm_libc::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+ ASSERT_EQ(errno, 0);
+ ASSERT_GT(write_fd, 0);
+ ASSERT_THAT(__llvm_libc::close(write_fd), Succeeds(0));
+ ASSERT_THAT(__llvm_libc::unlink(TEST_FILE), Succeeds(0));
+}
+
+TEST(LlvmLibcUnlinkTest, UnlinkNonExistentFile) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+ ASSERT_THAT(__llvm_libc::unlink("testdata/non-existent-file"), Fails(ENOENT));
+}
--- /dev/null
+//===-- Unittests for unlinkat --------------------------------------------===//
+//
+// 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/fcntl/openat.h"
+#include "src/unistd/close.h"
+#include "src/unistd/unlinkat.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+#include "utils/testutils/FDReader.h"
+
+#include <errno.h>
+
+TEST(LlvmLibcUnlinkatTest, CreateAndDeleteTest) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+ constexpr const char *TEST_DIR = "testdata";
+ constexpr const char *TEST_FILE = "openat.test";
+ int dir_fd = __llvm_libc::open(TEST_DIR, O_DIRECTORY);
+ ASSERT_EQ(errno, 0);
+ ASSERT_GT(dir_fd, 0);
+ int write_fd =
+ __llvm_libc::openat(dir_fd, TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+ ASSERT_EQ(errno, 0);
+ ASSERT_GT(write_fd, 0);
+ ASSERT_THAT(__llvm_libc::close(write_fd), Succeeds(0));
+ ASSERT_THAT(__llvm_libc::unlinkat(dir_fd, TEST_FILE, 0), Succeeds(0));
+ ASSERT_THAT(__llvm_libc::close(dir_fd), Succeeds(0));
+}
+
+TEST(LlvmLibcUnlinkatTest, UnlinkatNonExistentFile) {
+ constexpr const char *TEST_DIR = "testdata";
+ int dir_fd = __llvm_libc::open(TEST_DIR, O_DIRECTORY);
+ ASSERT_EQ(errno, 0);
+ ASSERT_GT(dir_fd, 0);
+ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+ using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+ ASSERT_THAT(__llvm_libc::unlinkat(dir_fd, "non-existent-file", 0),
+ Fails(ENOENT));
+ ASSERT_THAT(__llvm_libc::close(dir_fd), Succeeds(0));
+}