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