From 1b72036bef7cdfb58d98db06ae5179870b029784 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 27 Sep 2022 17:28:46 -0400 Subject: [PATCH] libroot: Replace scandir, alphasort implementations with musl's. Notably alphasort actually uses strcoll not strcmp, so this does affect behavior. scandir should be the same. --- src/system/libroot/posix/dirent.c | 82 ------------------- src/system/libroot/posix/musl/Jamfile | 2 + src/system/libroot/posix/musl/dirent/Jamfile | 17 ++++ .../libroot/posix/musl/dirent/alphasort.c | 7 ++ .../libroot/posix/musl/dirent/scandir.c | 46 +++++++++++ 5 files changed, 72 insertions(+), 82 deletions(-) create mode 100644 src/system/libroot/posix/musl/dirent/Jamfile create mode 100644 src/system/libroot/posix/musl/dirent/alphasort.c create mode 100644 src/system/libroot/posix/musl/dirent/scandir.c diff --git a/src/system/libroot/posix/dirent.c b/src/system/libroot/posix/dirent.c index 198c23d9bd..f46be3efdf 100644 --- a/src/system/libroot/posix/dirent.c +++ b/src/system/libroot/posix/dirent.c @@ -308,85 +308,3 @@ dirfd(DIR* dir) { return dir->fd; } - - -int -alphasort(const struct dirent** entry1, const struct dirent** entry2) -{ - return strcmp((*entry1)->d_name, (*entry2)->d_name); -} - - -int -scandir(const char* path, struct dirent*** _entryArray, - int (*selectFunc)(const struct dirent*), - int (*compareFunc)(const struct dirent** entry1, - const struct dirent** entry2)) -{ - struct dirent** array = NULL; - size_t arrayCapacity = 0; - size_t arrayCount = 0; - - DIR* dir = opendir(path); - if (dir == NULL) - return -1; - - while (true) { - struct dirent* copiedEntry; - - struct dirent* entry = readdir(dir); - if (entry == NULL) - break; - - // Check whether or not we should include this entry - if (selectFunc != NULL && !selectFunc(entry)) - continue; - - copiedEntry = malloc(entry->d_reclen); - if (copiedEntry == NULL) - goto error; - - memcpy(copiedEntry, entry, entry->d_reclen); - - // Put it into the array - - if (arrayCount == arrayCapacity) { - struct dirent** newArray; - - // Enlarge array - if (arrayCapacity == 0) - arrayCapacity = 64; - else - arrayCapacity *= 2; - - newArray = realloc(array, arrayCapacity * sizeof(void*)); - if (newArray == NULL) { - free(copiedEntry); - goto error; - } - - array = newArray; - } - - array[arrayCount++] = copiedEntry; - } - - closedir(dir); - - if (arrayCount > 0 && compareFunc != NULL) { - qsort(array, arrayCount, sizeof(void*), - (int (*)(const void*, const void*))compareFunc); - } - - *_entryArray = array; - return arrayCount; - -error: - closedir(dir); - - while (arrayCount-- > 0) - free(array[arrayCount]); - free(array); - - return -1; -} diff --git a/src/system/libroot/posix/musl/Jamfile b/src/system/libroot/posix/musl/Jamfile index 5a0796b7ab..135995d295 100644 --- a/src/system/libroot/posix/musl/Jamfile +++ b/src/system/libroot/posix/musl/Jamfile @@ -7,6 +7,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { MergeObjectFromObjects <$(architecture)>posix_musl.o : : + <$(architecture)>posix_musl_dirent.o <$(architecture)>posix_musl_math.o <$(architecture)>posix_musl_misc.o <$(architecture)>posix_musl_regex.o @@ -22,6 +23,7 @@ for arch in $(TARGET_ARCHS) { HaikuSubInclude math $(arch) ; } +HaikuSubInclude dirent ; HaikuSubInclude misc ; HaikuSubInclude regex ; HaikuSubInclude search ; diff --git a/src/system/libroot/posix/musl/dirent/Jamfile b/src/system/libroot/posix/musl/dirent/Jamfile new file mode 100644 index 0000000000..0a77a597e4 --- /dev/null +++ b/src/system/libroot/posix/musl/dirent/Jamfile @@ -0,0 +1,17 @@ +SubDir HAIKU_TOP src system libroot posix musl dirent ; + +SubDirSysHdrs [ FDirName $(SUBDIR) .. include ] ; +UseHeaders [ FDirName $(SUBDIR) .. internal ] ; +UseHeaders [ FDirName $(SUBDIR) .. arch $(TARGET_ARCH) ] ; + +local architectureObject ; +for architectureObject in [ MultiArchSubDirSetup ] { + on $(architectureObject) { + local architecture = $(TARGET_PACKAGING_ARCH) ; + + MergeObject <$(architecture)>posix_musl_dirent.o : + alphasort.c + scandir.c + ; + } +} diff --git a/src/system/libroot/posix/musl/dirent/alphasort.c b/src/system/libroot/posix/musl/dirent/alphasort.c new file mode 100644 index 0000000000..ab2624e2cc --- /dev/null +++ b/src/system/libroot/posix/musl/dirent/alphasort.c @@ -0,0 +1,7 @@ +#include +#include + +int alphasort(const struct dirent **a, const struct dirent **b) +{ + return strcoll((*a)->d_name, (*b)->d_name); +} diff --git a/src/system/libroot/posix/musl/dirent/scandir.c b/src/system/libroot/posix/musl/dirent/scandir.c new file mode 100644 index 0000000000..b78c6e30fd --- /dev/null +++ b/src/system/libroot/posix/musl/dirent/scandir.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include + +int scandir(const char *path, struct dirent ***res, + int (*sel)(const struct dirent *), + int (*cmp)(const struct dirent **, const struct dirent **)) +{ + DIR *d; + struct dirent *de, **names=0, **tmp; + size_t cnt=0, len=0; + int old_errno = errno; + d = opendir(path); + + if (!d) return -1; + + while ((errno=0), (de = readdir(d))) { + if (sel && !sel(de)) continue; + if (cnt >= len) { + len = 2*len+1; + if (len > SIZE_MAX/sizeof *names) break; + tmp = realloc(names, len * sizeof *names); + if (!tmp) break; + names = tmp; + } + names[cnt] = malloc(de->d_reclen); + if (!names[cnt]) break; + memcpy(names[cnt++], de, de->d_reclen); + } + + closedir(d); + + if (errno) { + if (names) while (cnt-->0) free(names[cnt]); + free(names); + return -1; + } + errno = old_errno; + + if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp); + *res = names; + return cnt; +}