1 //===--- Linux implementation of the Dir helpers --------------------------===// 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 "src/__support/File/dir.h" 10 11 #include "src/__support/OSUtil/syscall.h" // For internal syscall function. 12 #include "src/__support/error_or.h" 13 #include "src/__support/macros/config.h" 14 15 #include "hdr/fcntl_macros.h" // For open flags 16 #include <sys/syscall.h> // For syscall numbers 17 18 namespace LIBC_NAMESPACE_DECL { 19 20 ErrorOr<int> platform_opendir(const char *name) { 21 int open_flags = O_RDONLY | O_DIRECTORY | O_CLOEXEC; 22 #ifdef SYS_open 23 int fd = LIBC_NAMESPACE::syscall_impl<int>(SYS_open, name, open_flags); 24 #elif defined(SYS_openat) 25 int fd = 26 LIBC_NAMESPACE::syscall_impl<int>(SYS_openat, AT_FDCWD, name, open_flags); 27 #else 28 #error \ 29 "SYS_open and SYS_openat syscalls not available to perform an open operation." 30 #endif 31 32 if (fd < 0) { 33 return LIBC_NAMESPACE::Error(-fd); 34 } 35 return fd; 36 } 37 38 ErrorOr<size_t> platform_fetch_dirents(int fd, cpp::span<uint8_t> buffer) { 39 #ifdef SYS_getdents64 40 long size = LIBC_NAMESPACE::syscall_impl<long>(SYS_getdents64, fd, 41 buffer.data(), buffer.size()); 42 #else 43 #error "getdents64 syscalls not available to perform a fetch dirents operation." 44 #endif 45 46 if (size < 0) { 47 return LIBC_NAMESPACE::Error(static_cast<int>(-size)); 48 } 49 return size; 50 } 51 52 int platform_closedir(int fd) { 53 int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_close, fd); 54 if (ret < 0) { 55 return static_cast<int>(-ret); 56 } 57 return 0; 58 } 59 60 } // namespace LIBC_NAMESPACE_DECL 61