diff options
Diffstat (limited to 'lib/mlibc/options/posix/generic/dirent-stubs.cpp')
-rw-r--r-- | lib/mlibc/options/posix/generic/dirent-stubs.cpp | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/lib/mlibc/options/posix/generic/dirent-stubs.cpp b/lib/mlibc/options/posix/generic/dirent-stubs.cpp deleted file mode 100644 index 1352585..0000000 --- a/lib/mlibc/options/posix/generic/dirent-stubs.cpp +++ /dev/null @@ -1,180 +0,0 @@ - -#include <errno.h> -#include <dirent.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> -#include <stdlib.h> - -#include <bits/ensure.h> -#include <frg/allocation.hpp> -#include <mlibc/allocator.hpp> -#include <mlibc/posix-sysdeps.hpp> -#include <mlibc/debug.hpp> - -// Code taken from musl -int alphasort(const struct dirent **a, const struct dirent **b) { - return strcoll((*a)->d_name, (*b)->d_name); -} - -int closedir(DIR *dir) { - // TODO: Deallocate the dir structure. - close(dir->__handle); - return 0; -} -int dirfd(DIR *dir) { - return dir->__handle; -} -DIR *fdopendir(int fd) { - struct stat st; - - if(fstat(fd, &st) < 0) { - return nullptr; - } - // Musl implements this, but O_PATH is only declared on the linux abi - /*if(fcntl(fd, F_GETFL) & O_PATH) { - errno = EBADF; - return nullptr; - }*/ - if(!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - return nullptr; - } - auto dir = frg::construct<__mlibc_dir_struct>(getAllocator()); - __ensure(dir); - dir->__ent_next = 0; - dir->__ent_limit = 0; - int flags = fcntl(fd, F_GETFD); - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); - dir->__handle = fd; - return dir; -} -DIR *opendir(const char *path) { - auto dir = frg::construct<__mlibc_dir_struct>(getAllocator()); - __ensure(dir); - dir->__ent_next = 0; - dir->__ent_limit = 0; - - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_open_dir, nullptr); - if(int e = mlibc::sys_open_dir(path, &dir->__handle); e) { - errno = e; - frg::destruct(getAllocator(), dir); - return nullptr; - }else{ - return dir; - } -} -struct dirent *readdir(DIR *dir) { - __ensure(dir->__ent_next <= dir->__ent_limit); - if(dir->__ent_next == dir->__ent_limit) { - MLIBC_CHECK_OR_ENOSYS(mlibc::sys_read_entries, nullptr); - if(int e = mlibc::sys_read_entries(dir->__handle, dir->__ent_buffer, 2048, &dir->__ent_limit); e) - __ensure(!"mlibc::sys_read_entries() failed"); - dir->__ent_next = 0; - if(!dir->__ent_limit) - return nullptr; - } - - auto entp = reinterpret_cast<struct dirent *>(dir->__ent_buffer + dir->__ent_next); - // We only copy as many bytes as we need to avoid buffer-overflows. - memcpy(&dir->__current, entp, offsetof(struct dirent, d_name) + strlen(entp->d_name) + 1); - dir->__ent_next += entp->d_reclen; - return &dir->__current; -} -int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) { - if(!mlibc::sys_read_entries) { - MLIBC_MISSING_SYSDEP(); - return ENOSYS; - } - - __ensure(dir->__ent_next <= dir->__ent_limit); - if(dir->__ent_next == dir->__ent_limit) { - if(int e = mlibc::sys_read_entries(dir->__handle, dir->__ent_buffer, 2048, &dir->__ent_limit); e) - __ensure(!"mlibc::sys_read_entries() failed"); - dir->__ent_next = 0; - if(!dir->__ent_limit) { - *result = NULL; - return 0; - } - } - - auto entp = reinterpret_cast<struct dirent *>(dir->__ent_buffer + dir->__ent_next); - // We only copy as many bytes as we need to avoid buffer-overflows. - memcpy(entry, entp, offsetof(struct dirent, d_name) + strlen(entp->d_name) + 1); - dir->__ent_next += entp->d_reclen; - *result = entry; - return 0; -} - -void rewinddir(DIR *dir) { - lseek(dir->__handle, 0, SEEK_SET); - dir->__ent_next = 0; -} - -int scandir(const char *path, struct dirent ***res, int (*select)(const struct dirent *), - int (*compare)(const struct dirent **, const struct dirent **)) { - DIR *dir = opendir(path); - if (!dir) - return -1; // errno will be set by opendir() - - // we should save the errno - int old_errno = errno; - errno = 0; - - struct dirent *dir_ent; - struct dirent **array = nullptr, **tmp = nullptr; - int length = 0; - int count = 0; - while((dir_ent = readdir(dir)) && !errno) { - if(select && !select(dir_ent)) - continue; - - if(count >= length) { - length = 2*length + 1; - tmp = static_cast<struct dirent**>(realloc(array, - length * sizeof(struct dirent*))); - // we need to check the call actually goes through - // before we overwrite array so that we can - // deallocate the already written entries should realloc() - // have failed - if(!tmp) - break; - array = tmp; - } - array[count] = static_cast<struct dirent*>(malloc(dir_ent->d_reclen)); - if(!array[count]) - break; - - memcpy(array[count], dir_ent, dir_ent->d_reclen); - count++; - } - - if(errno) { - if(array) - while(count-- > 0) - free(array[count]); - free(array); - return -1; - } - - // from here we can set the old errno back - errno = old_errno; - - if(compare) - qsort(array, count, sizeof(struct dirent*), - (int (*)(const void *, const void *)) compare); - *res = array; - return count; -} -void seekdir(DIR *, long) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} -long telldir(DIR *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int versionsort(const struct dirent **a, const struct dirent **b) { - return strverscmp((*a)->d_name, (*b)->d_name); -} |