diff options
Diffstat (limited to 'libc/bionic/dirent.cpp')
-rw-r--r-- | libc/bionic/dirent.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/libc/bionic/dirent.cpp b/libc/bionic/dirent.cpp index 7abc7f3..fb45398 100644 --- a/libc/bionic/dirent.cpp +++ b/libc/bionic/dirent.cpp @@ -30,6 +30,8 @@ #include <errno.h> #include <fcntl.h> +#include <malloc.h> +#include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -43,6 +45,7 @@ struct DIR { int fd_; size_t available_bytes_; dirent* next_; + long current_pos_; pthread_mutex_t mutex_; dirent buff_[15]; }; @@ -55,6 +58,7 @@ static DIR* __allocate_DIR(int fd) { d->fd_ = fd; d->available_bytes_ = 0; d->next_ = NULL; + d->current_pos_ = 0L; pthread_mutex_init(&d->mutex_, NULL); return d; } @@ -78,7 +82,7 @@ DIR* fdopendir(int fd) { } DIR* opendir(const char* path) { - int fd = open(path, O_RDONLY | O_DIRECTORY); + int fd = open(path, O_CLOEXEC | O_DIRECTORY | O_RDONLY); return (fd != -1) ? __allocate_DIR(fd) : NULL; } @@ -100,6 +104,9 @@ static dirent* __readdir_locked(DIR* d) { dirent* entry = d->next_; d->next_ = reinterpret_cast<dirent*>(reinterpret_cast<char*>(entry) + entry->d_reclen); d->available_bytes_ -= entry->d_reclen; + // The directory entry offset uses 0, 1, 2 instead of real file offset, + // so the value range of long type is enough. + d->current_pos_ = static_cast<long>(entry->d_off); return entry; } @@ -146,6 +153,20 @@ void rewinddir(DIR* d) { ScopedPthreadMutexLocker locker(&d->mutex_); lseek(d->fd_, 0, SEEK_SET); d->available_bytes_ = 0; + d->current_pos_ = 0L; +} + +void seekdir(DIR* d, long offset) { + ScopedPthreadMutexLocker locker(&d->mutex_); + off_t ret = lseek(d->fd_, offset, SEEK_SET); + if (ret != -1L) { + d->available_bytes_ = 0; + d->current_pos_ = ret; + } +} + +long telldir(DIR* d) { + return d->current_pos_; } int alphasort(const dirent** a, const dirent** b) { |