diff options
-rw-r--r-- | libc/misc/dirent/Makefile | 3 | ||||
-rw-r--r-- | libc/misc/dirent/alphasort64.c | 16 | ||||
-rw-r--r-- | libc/misc/dirent/dirstream.h | 2 | ||||
-rw-r--r-- | libc/misc/dirent/opendir.c | 2 | ||||
-rw-r--r-- | libc/misc/dirent/readdir64.c | 68 | ||||
-rw-r--r-- | libc/misc/dirent/scandir64.c | 88 |
6 files changed, 176 insertions, 3 deletions
diff --git a/libc/misc/dirent/Makefile b/libc/misc/dirent/Makefile index 23b024b63..43f233619 100644 --- a/libc/misc/dirent/Makefile +++ b/libc/misc/dirent/Makefile @@ -23,7 +23,8 @@ TOPDIR=../../../ include $(TOPDIR)Rules.mak -CSRC=alphasort.c closedir.c dirfd.c opendir.c readdir.c rewinddir.c scandir.c seekdir.c telldir.c +CSRC=alphasort.c closedir.c dirfd.c opendir.c readdir.c rewinddir.c scandir.c \ + seekdir.c telldir.c readdir64.c alphasort64.c scandir64.c COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) diff --git a/libc/misc/dirent/alphasort64.c b/libc/misc/dirent/alphasort64.c new file mode 100644 index 000000000..94194e0c6 --- /dev/null +++ b/libc/misc/dirent/alphasort64.c @@ -0,0 +1,16 @@ +#include <features.h> +#define _FILE_OFFSET_BITS 64 +#define __USE_LARGEFILE64 +#define __USE_FILE_OFFSET64 +#include <string.h> +#include "dirstream.h" + +#ifdef __UCLIBC_HAVE_LFS__ + +int alphasort64(const void * a, const void * b) +{ + return strcmp ((*(const struct dirent64 **) a)->d_name, + (*(const struct dirent64 **) b)->d_name); +} +#endif /* __UCLIBC_HAVE_LFS__ */ + diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h index 2b06b1501..8131ffce7 100644 --- a/libc/misc/dirent/dirstream.h +++ b/libc/misc/dirent/dirstream.h @@ -54,7 +54,7 @@ struct __dirstream { size_t dd_size; /* -> directory buffer */ - struct dirent *dd_buf; + void *dd_buf; /* offset of the next dir entry in directory. */ off_t dd_nextoff; diff --git a/libc/misc/dirent/opendir.c b/libc/misc/dirent/opendir.c index 0ac1637b3..25b5873e1 100644 --- a/libc/misc/dirent/opendir.c +++ b/libc/misc/dirent/opendir.c @@ -15,7 +15,7 @@ DIR *opendir(const char *name) { int fd; struct stat statbuf; - struct dirent *buf; + char *buf; DIR *ptr; if (stat(name, &statbuf)) diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c new file mode 100644 index 000000000..d0f28030b --- /dev/null +++ b/libc/misc/dirent/readdir64.c @@ -0,0 +1,68 @@ +#include <features.h> +#define _FILE_OFFSET_BITS 64 +#define __USE_LARGEFILE64 +#define __USE_FILE_OFFSET64 +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <dirent.h> +#include "dirstream.h" + +#ifdef __UCLIBC_HAVE_LFS__ + +extern int getdents64 __P ((unsigned int fd, struct dirent64 *dirp, unsigned int count)); + + +struct dirent64 *readdir64(DIR * dir) +{ + int result; + struct dirent64 *de; + + if (!dir) { + __set_errno(EBADF); + return NULL; + } + + /* Are we running an old kernel? */ + if (dir->dd_getdents == no_getdents) { + abort(); + } + + if (dir->dd_size <= dir->dd_nextloc) { + /* read dir->dd_max bytes of directory entries. */ + result = getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); + + /* We assume we have getdents (). */ + dir->dd_getdents = have_getdents; + if (result <= 0) { + result = -result; + if (result > 0) { + /* Are we right? */ + if (result == ENOSYS) { + dir->dd_getdents = no_getdents; + abort(); + } + __set_errno(result); + } + + return NULL; + } + + dir->dd_size = result; + dir->dd_nextloc = 0; + } + + de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc); + + /* Am I right? H.J. */ + dir->dd_nextloc += de->d_reclen; + + /* We have to save the next offset here. */ + dir->dd_nextoff = de->d_off; + + return de; +} +#endif /* __UCLIBC_HAVE_LFS__ */ + + diff --git a/libc/misc/dirent/scandir64.c b/libc/misc/dirent/scandir64.c new file mode 100644 index 000000000..6b0892191 --- /dev/null +++ b/libc/misc/dirent/scandir64.c @@ -0,0 +1,88 @@ +/* -*- Mode: C; c-file-style: "gnu" -*- */ +/* + Copyright (c) 2000 Petter Reinholdtsen + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include <features.h> +#define _FILE_OFFSET_BITS 64 +#define __USE_LARGEFILE64 +#define __USE_FILE_OFFSET64 +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include "dirstream.h" + +#ifdef __UCLIBC_HAVE_LFS__ + +/* + * FIXME: This is a simple hack version which doesn't sort the data, and + * just passes all unsorted. + */ + +int scandir64(const char *dir, struct dirent64 ***namelist, + int (*selector) (const struct dirent64 *), + int (*compar) (const __ptr_t, const __ptr_t)) +{ + DIR *d = opendir(dir); + struct dirent64 *current; + struct dirent64 **names; + int count = 0; + int pos = 0; + int result = -1; + + if (NULL == d) + return -1; + + while (NULL != readdir64(d)) + count++; + + names = malloc(sizeof (struct dirent64 *) * count); + + rewinddir(d); + + while (NULL != (current = readdir64(d))) { + if (NULL == selector || selector(current)) { + struct dirent64 *copyentry = malloc(current->d_reclen); + + memcpy(copyentry, current, current->d_reclen); + + names[pos] = copyentry; + pos++; + } + } + result = closedir(d); + + if (pos != count) + names = realloc(names, sizeof (struct dirent64 *) * pos); + + if (compar != NULL) { + qsort(names, pos, sizeof (struct dirent64 *), compar); + } + + *namelist = names; + + return pos; +} +#endif /* __UCLIBC_HAVE_LFS__ */ + |