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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
|
||||
int alphasort(const struct dirent **a, const struct dirent **b)
|
||||
{
|
||||
return strcoll((*a)->d_name, (*b)->d_name);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user