* Implemented missing alphasort(), and scandir() POSIX functions. Completely

untested yet, though.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34838 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2010-01-01 18:49:55 +00:00
parent 355dc6bef4
commit 31e49a2f1d
2 changed files with 90 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008, Haiku Inc. All Rights Reserved.
* Copyright 2002-2010, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _DIRENT_H
@ -32,7 +32,6 @@ typedef struct __DIR DIR;
extern "C" {
#endif
DIR* fdopendir(int fd);
DIR* opendir(const char* dirName);
struct dirent* readdir(DIR* dir);
int readdir_r(DIR* dir, struct dirent* entry,
@ -42,6 +41,14 @@ void rewinddir(DIR* dir);
void seekdir(DIR* dir, long int position);
long int telldir(DIR* dir);
int dirfd(const DIR* dir);
DIR* fdopendir(int fd);
int alphasort(const struct dirent** entry1,
const struct dirent** entry2);
int scandir(const char* dir, struct dirent*** _entryArray,
int (*selectFunc)(const struct dirent*),
int (*compareFunc)(const struct dirent** entry1,
const struct dirent** entry2));
#ifdef __cplusplus
}

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2004-2010, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -282,3 +282,83 @@ dirfd(const 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)
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;
}