From 31e49a2f1de5dbf89d312330180b5ee8cfd3f460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 1 Jan 2010 18:49:55 +0000 Subject: [PATCH] * 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 --- headers/posix/dirent.h | 11 ++++- src/system/libroot/posix/dirent.c | 82 ++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/headers/posix/dirent.h b/headers/posix/dirent.h index 25bc7b4352..6831bdeb48 100644 --- a/headers/posix/dirent.h +++ b/headers/posix/dirent.h @@ -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 } diff --git a/src/system/libroot/posix/dirent.c b/src/system/libroot/posix/dirent.c index c1e93e93cc..8b0a870694 100644 --- a/src/system/libroot/posix/dirent.c +++ b/src/system/libroot/posix/dirent.c @@ -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; +}