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__ */ + | 
