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 <stdlib.h> 12 13 namespace __llvm_libc { 14 open(const char * path)15Dir *Dir::open(const char *path) { 16 int fd = platform_opendir(path); 17 if (fd < 0) 18 return nullptr; 19 20 Dir *dir = reinterpret_cast<Dir *>(malloc(sizeof(Dir))); 21 dir->fd = fd; 22 dir->readptr = 0; 23 dir->fillsize = 0; 24 Mutex::init(&dir->mutex, false, false, false); 25 26 return dir; 27 } 28 read()29struct ::dirent *Dir::read() { 30 MutexLock lock(&mutex); 31 if (readptr >= fillsize) { 32 fillsize = platform_fetch_dirents( 33 fd, cpp::MutableArrayRef<uint8_t>(buffer, BUFSIZE)); 34 if (fillsize == 0) 35 return nullptr; 36 readptr = 0; 37 } 38 struct ::dirent *d = reinterpret_cast<struct ::dirent *>(buffer + readptr); 39 #ifdef __unix__ 40 // The d_reclen field is available on Linux but not required by POSIX. 41 readptr += d->d_reclen; 42 #else 43 // Other platforms have to implement how the read pointer is to be updated. 44 #error "DIR read pointer update is missing." 45 #endif 46 return d; 47 } 48 close()49int Dir::close() { 50 { 51 MutexLock lock(&mutex); 52 if (!platform_closedir(fd)) 53 return -1; 54 } 55 free(this); 56 return 0; 57 } 58 59 } // namespace __llvm_libc 60