1*35ea84adSSiva Chandra Reddy //===--- Linux implementation of the Dir helpers --------------------------===//
2*35ea84adSSiva Chandra Reddy //
3*35ea84adSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*35ea84adSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5*35ea84adSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*35ea84adSSiva Chandra Reddy //
7*35ea84adSSiva Chandra Reddy //===----------------------------------------------------------------------===//
8*35ea84adSSiva Chandra Reddy 
9*35ea84adSSiva Chandra Reddy #include "dir.h"
10*35ea84adSSiva Chandra Reddy 
11*35ea84adSSiva Chandra Reddy #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12*35ea84adSSiva Chandra Reddy 
13*35ea84adSSiva Chandra Reddy #include <errno.h>
14*35ea84adSSiva Chandra Reddy #include <fcntl.h>       // For open flags
15*35ea84adSSiva Chandra Reddy #include <sys/syscall.h> // For syscall numbers
16*35ea84adSSiva Chandra Reddy 
17*35ea84adSSiva Chandra Reddy namespace __llvm_libc {
18*35ea84adSSiva Chandra Reddy 
platform_opendir(const char * name)19*35ea84adSSiva Chandra Reddy int platform_opendir(const char *name) {
20*35ea84adSSiva Chandra Reddy   int open_flags = O_RDONLY | O_DIRECTORY | O_CLOEXEC;
21*35ea84adSSiva Chandra Reddy #ifdef SYS_open
22*35ea84adSSiva Chandra Reddy   int fd = __llvm_libc::syscall(SYS_open, name, open_flags);
23*35ea84adSSiva Chandra Reddy #elif defined(SYS_openat)
24*35ea84adSSiva Chandra Reddy   int fd = __llvm_libc::syscall(SYS_openat, AT_FDCWD, name, open_flags);
25*35ea84adSSiva Chandra Reddy #else
26*35ea84adSSiva Chandra Reddy #error                                                                         \
27*35ea84adSSiva Chandra Reddy     "SYS_open and SYS_openat syscalls not available to perform an open operation."
28*35ea84adSSiva Chandra Reddy #endif
29*35ea84adSSiva Chandra Reddy 
30*35ea84adSSiva Chandra Reddy   if (fd < 0) {
31*35ea84adSSiva Chandra Reddy     errno = -fd;
32*35ea84adSSiva Chandra Reddy     return -1;
33*35ea84adSSiva Chandra Reddy   }
34*35ea84adSSiva Chandra Reddy   return fd;
35*35ea84adSSiva Chandra Reddy }
36*35ea84adSSiva Chandra Reddy 
platform_fetch_dirents(int fd,cpp::MutableArrayRef<uint8_t> buffer)37*35ea84adSSiva Chandra Reddy size_t platform_fetch_dirents(int fd, cpp::MutableArrayRef<uint8_t> buffer) {
38*35ea84adSSiva Chandra Reddy   long size =
39*35ea84adSSiva Chandra Reddy       __llvm_libc::syscall(SYS_getdents, fd, buffer.data(), buffer.size());
40*35ea84adSSiva Chandra Reddy   if (size < 0) {
41*35ea84adSSiva Chandra Reddy     errno = -size;
42*35ea84adSSiva Chandra Reddy     return 0;
43*35ea84adSSiva Chandra Reddy   }
44*35ea84adSSiva Chandra Reddy   return size;
45*35ea84adSSiva Chandra Reddy }
46*35ea84adSSiva Chandra Reddy 
platform_closedir(int fd)47*35ea84adSSiva Chandra Reddy bool platform_closedir(int fd) {
48*35ea84adSSiva Chandra Reddy   long ret = __llvm_libc::syscall(SYS_close, fd);
49*35ea84adSSiva Chandra Reddy   if (ret < 0) {
50*35ea84adSSiva Chandra Reddy     errno = -ret;
51*35ea84adSSiva Chandra Reddy     return false;
52*35ea84adSSiva Chandra Reddy   }
53*35ea84adSSiva Chandra Reddy   return true;
54*35ea84adSSiva Chandra Reddy }
55*35ea84adSSiva Chandra Reddy 
56*35ea84adSSiva Chandra Reddy } // namespace __llvm_libc
57