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