1 //===--- Implementation of a platform independent Dir data structure ------===// 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 "dir.h" 10 11 #include "src/__support/CPP/mutex.h" // lock_guard 12 #include "src/__support/CPP/new.h" 13 #include "src/__support/error_or.h" 14 #include "src/errno/libc_errno.h" // For error macros 15 16 namespace LIBC_NAMESPACE { 17 open(const char * path)18ErrorOr<Dir *> Dir::open(const char *path) { 19 auto fd = platform_opendir(path); 20 if (!fd) 21 return LIBC_NAMESPACE::Error(fd.error()); 22 23 LIBC_NAMESPACE::AllocChecker ac; 24 Dir *dir = new (ac) Dir(fd.value()); 25 if (!ac) 26 return LIBC_NAMESPACE::Error(ENOMEM); 27 return dir; 28 } 29 read()30ErrorOr<struct ::dirent *> Dir::read() { 31 cpp::lock_guard lock(mutex); 32 if (readptr >= fillsize) { 33 auto readsize = platform_fetch_dirents(fd, buffer); 34 if (!readsize) 35 return LIBC_NAMESPACE::Error(readsize.error()); 36 fillsize = readsize.value(); 37 readptr = 0; 38 } 39 if (fillsize == 0) 40 return nullptr; 41 42 struct ::dirent *d = reinterpret_cast<struct ::dirent *>(buffer + readptr); 43 #ifdef __linux__ 44 // The d_reclen field is available on Linux but not required by POSIX. 45 readptr += d->d_reclen; 46 #else 47 // Other platforms have to implement how the read pointer is to be updated. 48 #error "DIR read pointer update is missing." 49 #endif 50 return d; 51 } 52 close()53int Dir::close() { 54 { 55 cpp::lock_guard lock(mutex); 56 int retval = platform_closedir(fd); 57 if (retval != 0) 58 return retval; 59 } 60 delete this; 61 return 0; 62 } 63 64 } // namespace LIBC_NAMESPACE 65