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;
|
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 :
|
MergeObjectFromObjects <$(architecture)>posix_musl.o :
|
||||||
:
|
:
|
||||||
|
<$(architecture)>posix_musl_dirent.o
|
||||||
<$(architecture)>posix_musl_math.o
|
<$(architecture)>posix_musl_math.o
|
||||||
<$(architecture)>posix_musl_misc.o
|
<$(architecture)>posix_musl_misc.o
|
||||||
<$(architecture)>posix_musl_regex.o
|
<$(architecture)>posix_musl_regex.o
|
||||||
@@ -22,6 +23,7 @@ for arch in $(TARGET_ARCHS) {
|
|||||||
HaikuSubInclude math $(arch) ;
|
HaikuSubInclude math $(arch) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HaikuSubInclude dirent ;
|
||||||
HaikuSubInclude misc ;
|
HaikuSubInclude misc ;
|
||||||
HaikuSubInclude regex ;
|
HaikuSubInclude regex ;
|
||||||
HaikuSubInclude search ;
|
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