Author: axeld Date: 2010-01-01 19:49:55 +0100 (Fri, 01 Jan 2010) New Revision: 34838 Changeset: http://dev.haiku-os.org/changeset/34838/haiku Modified: haiku/trunk/headers/posix/dirent.h haiku/trunk/src/system/libroot/posix/dirent.c Log: * Implemented missing alphasort(), and scandir() POSIX functions. Completely untested yet, though. Modified: haiku/trunk/headers/posix/dirent.h =================================================================== --- haiku/trunk/headers/posix/dirent.h 2010-01-01 17:09:23 UTC (rev 34837) +++ haiku/trunk/headers/posix/dirent.h 2010-01-01 18:49:55 UTC (rev 34838) @@ -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 @@ 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,7 +41,15 @@ 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 } #endif Modified: haiku/trunk/src/system/libroot/posix/dirent.c =================================================================== --- haiku/trunk/src/system/libroot/posix/dirent.c 2010-01-01 17:09:23 UTC (rev 34837) +++ haiku/trunk/src/system/libroot/posix/dirent.c 2010-01-01 18:49:55 UTC (rev 34838) @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx - * Copyright 2004-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2004-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -282,3 +282,83 @@ { 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; +}