diff options
Diffstat (limited to 'libc/misc/dirent')
| -rw-r--r-- | libc/misc/dirent/Makefile.in | 24 | ||||
| -rw-r--r-- | libc/misc/dirent/alphasort.c | 11 | ||||
| -rw-r--r-- | libc/misc/dirent/alphasort64.c | 13 | ||||
| -rw-r--r-- | libc/misc/dirent/closedir.c | 5 | ||||
| -rw-r--r-- | libc/misc/dirent/dirfd.c | 1 | ||||
| -rw-r--r-- | libc/misc/dirent/dirstream.h | 21 | ||||
| -rw-r--r-- | libc/misc/dirent/opendir.c | 98 | ||||
| -rw-r--r-- | libc/misc/dirent/readdir.c | 29 | ||||
| -rw-r--r-- | libc/misc/dirent/readdir64.c | 53 | ||||
| -rw-r--r-- | libc/misc/dirent/readdir64_r.c | 64 | ||||
| -rw-r--r-- | libc/misc/dirent/readdir_r.c | 29 | ||||
| -rw-r--r-- | libc/misc/dirent/rewinddir.c | 1 | ||||
| -rw-r--r-- | libc/misc/dirent/scandir.c | 59 | ||||
| -rw-r--r-- | libc/misc/dirent/scandir64.c | 111 | ||||
| -rw-r--r-- | libc/misc/dirent/seekdir.c | 1 | ||||
| -rw-r--r-- | libc/misc/dirent/versionsort.c | 17 | ||||
| -rw-r--r-- | libc/misc/dirent/versionsort64.c | 18 |
17 files changed, 223 insertions, 332 deletions
diff --git a/libc/misc/dirent/Makefile.in b/libc/misc/dirent/Makefile.in index b35efa0b1..5cae8d44d 100644 --- a/libc/misc/dirent/Makefile.in +++ b/libc/misc/dirent/Makefile.in @@ -1,26 +1,28 @@ # Makefile for uClibc # -# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC := alphasort.c closedir.c dirfd.c opendir.c readdir.c rewinddir.c \ - scandir.c seekdir.c telldir.c readdir_r.c +subdirs += libc/misc/dirent -ifeq ($(UCLIBC_HAS_LFS),y) -CSRC += readdir64.c alphasort64.c scandir64.c readdir64_r.c -endif +CSRC := alphasort.c readdir.c scandir.c versionsort.c +CSRC_R := readdir_r.c +CSRC-y := closedir.c dirfd.c opendir.c rewinddir.c seekdir.c telldir.c $(CSRC) \ + $(CSRC_R) +CSRC-$(UCLIBC_HAS_LFS) += $(patsubst %.c,%64.c,$(CSRC)) +CSRC-$(UCLIBC_HAS_LFS) += $(patsubst %_r.c,%64_r.c,$(CSRC_R)) MISC_DIRENT_DIR := $(top_srcdir)libc/misc/dirent MISC_DIRENT_OUT := $(top_builddir)libc/misc/dirent -MISC_DIRENT_SRC := $(patsubst %.c,$(MISC_DIRENT_DIR)/%.c,$(CSRC)) -MISC_DIRENT_OBJ := $(patsubst %.c,$(MISC_DIRENT_OUT)/%.o,$(CSRC)) +MISC_DIRENT_SRC := $(patsubst %.c,$(MISC_DIRENT_DIR)/%.c,$(CSRC-y)) +MISC_DIRENT_OBJ := $(patsubst %.c,$(MISC_DIRENT_OUT)/%.o,$(CSRC-y)) libc-y += $(MISC_DIRENT_OBJ) -objclean-y += misc_dirent_objclean +objclean-y += CLEAN_libc/misc/dirent -misc_dirent_objclean: - $(RM) $(MISC_DIRENT_OUT)/*.{o,os} +CLEAN_libc/misc/dirent: + $(do_rm) $(addprefix $(MISC_DIRENT_OUT)/*., o os) diff --git a/libc/misc/dirent/alphasort.c b/libc/misc/dirent/alphasort.c index 70aa2a516..67b3b7859 100644 --- a/libc/misc/dirent/alphasort.c +++ b/libc/misc/dirent/alphasort.c @@ -8,11 +8,10 @@ #include <string.h> #include "dirstream.h" -/* Experimentally off - libc_hidden_proto(strcmp) */ - -int alphasort(const void * a, const void * b) +int alphasort(const struct dirent **a, const struct dirent **b) { - return strcmp ((*(const struct dirent **) a)->d_name, - (*(const struct dirent **) b)->d_name); + return strcoll((*a)->d_name, (*b)->d_name); } - +#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64 +strong_alias_untyped(alphasort,alphasort64) +#endif diff --git a/libc/misc/dirent/alphasort64.c b/libc/misc/dirent/alphasort64.c index de7a87a9a..6eb414241 100644 --- a/libc/misc/dirent/alphasort64.c +++ b/libc/misc/dirent/alphasort64.c @@ -5,15 +5,14 @@ */ #include <_lfs_64.h> - #include <dirent.h> -#include <string.h> -#include "dirstream.h" -/* Experimentally off - libc_hidden_proto(strcmp) */ +#if __WORDSIZE != 64 +# include <string.h> +# include "dirstream.h" -int alphasort64(const void * a, const void * b) +int alphasort64(const struct dirent64 **a, const struct dirent64 **b) { - return strcmp ((*(const struct dirent64 **) a)->d_name, - (*(const struct dirent64 **) b)->d_name); + return strcoll((*a)->d_name, (*b)->d_name); } +#endif diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c index 3dc0bd17a..dfb53f888 100644 --- a/libc/misc/dirent/closedir.c +++ b/libc/misc/dirent/closedir.c @@ -9,9 +9,8 @@ #include <stdlib.h> #include <unistd.h> #include "dirstream.h" +#include <not-cancel.h> -libc_hidden_proto(closedir) -libc_hidden_proto(close) int closedir(DIR * dir) { @@ -33,6 +32,6 @@ int closedir(DIR * dir) __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); free(dir->dd_buf); free(dir); - return close(fd); + return close_not_cancel(fd); } libc_hidden_def(closedir) diff --git a/libc/misc/dirent/dirfd.c b/libc/misc/dirent/dirfd.c index c6f46e965..649dd4ad8 100644 --- a/libc/misc/dirent/dirfd.c +++ b/libc/misc/dirent/dirfd.c @@ -8,7 +8,6 @@ #include <errno.h> #include "dirstream.h" -libc_hidden_proto(dirfd) int dirfd(DIR * dir) { diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h index 370886aa7..59b8bafb9 100644 --- a/libc/misc/dirent/dirstream.h +++ b/libc/misc/dirent/dirstream.h @@ -13,8 +13,7 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ +not, see <http://www.gnu.org/licenses/>. */ /* * POSIX Standard: 5.1.2 Directory Operations <dirent.h> @@ -29,18 +28,6 @@ Cambridge, MA 02139, USA. */ #include <bits/uClibc_mutex.h> -/* For now, syscall readdir () only supports one entry at a time. It - * will be changed in the future. -#define NUMENT 3 -*/ -#ifndef NUMENT -#define NUMENT 1 -#endif - -#define SINGLE_READDIR 11 -#define MULTI_READDIR 12 -#define NEW_READDIR 13 - /* Directory stream type. */ struct __dirstream { /* file descriptor */ @@ -65,10 +52,4 @@ struct __dirstream { __UCLIBC_MUTEX(dd_lock); }; /* stream data from opendir() */ - -extern ssize_t __getdents(int fd, char *buf, size_t count) attribute_hidden; -#ifdef __UCLIBC_HAS_LFS__ -extern ssize_t __getdents64 (int fd, char *buf, size_t count) attribute_hidden; -#endif - #endif /* dirent.h */ diff --git a/libc/misc/dirent/opendir.c b/libc/misc/dirent/opendir.c index 26ab91511..8af00f88c 100644 --- a/libc/misc/dirent/opendir.c +++ b/libc/misc/dirent/opendir.c @@ -12,14 +12,56 @@ #include <unistd.h> #include <sys/dir.h> #include <sys/stat.h> +#include <not-cancel.h> +#include <dirent.h> #include "dirstream.h" -libc_hidden_proto(opendir) -libc_hidden_proto(open) -libc_hidden_proto(fcntl) -libc_hidden_proto(close) -libc_hidden_proto(stat) -libc_hidden_proto(fstat) +static DIR *fd_to_DIR(int fd, __blksize_t size) +{ + DIR *ptr; + + ptr = malloc(sizeof(*ptr)); + if (!ptr) + return NULL; + + ptr->dd_fd = fd; + ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0; + ptr->dd_max = size; + if (ptr->dd_max < 512) + ptr->dd_max = 512; + + ptr->dd_buf = calloc(1, ptr->dd_max); + if (!ptr->dd_buf) { + free(ptr); + return NULL; + } + __UCLIBC_MUTEX_INIT_VAR(ptr->dd_lock); + + return ptr; +} + +DIR *fdopendir(int fd) +{ + int flags; + struct stat st; + + if (fstat(fd, &st)) + return NULL; + if (!S_ISDIR(st.st_mode)) { + __set_errno(ENOTDIR); + return NULL; + } + + flags = fcntl(fd, F_GETFL); + if (flags == -1) + return NULL; + if ((flags & O_ACCMODE) == O_WRONLY) { + __set_errno(EINVAL); + return NULL; + } + + return fd_to_DIR(fd, st.st_blksize); +} /* opendir just makes an open() call - it return NULL if it fails * (open sets errno), otherwise it returns a DIR * pointer. @@ -40,44 +82,36 @@ DIR *opendir(const char *name) } # define O_DIRECTORY 0 #endif - if ((fd = open(name, O_RDONLY|O_NDELAY|O_DIRECTORY)) < 0) + fd = open_not_cancel_2(name, O_RDONLY|O_NDELAY|O_DIRECTORY|O_CLOEXEC); + if (fd < 0) return NULL; - /* Note: we should check to make sure that between the stat() and open() * call, 'name' didnt change on us, but that's only if O_DIRECTORY isnt * defined and since Linux has supported it for like ever, i'm not going * to worry about it right now (if ever). */ - if (fstat(fd, &statbuf) < 0) - goto close_and_ret; + + if (fstat(fd, &statbuf) < 0) { + /* this close() never fails + *int saved_errno; + *saved_errno = errno; */ + close_not_cancel_no_status(fd); + /*__set_errno(saved_errno);*/ + return NULL; + } /* According to POSIX, directory streams should be closed when * exec. From "Anna Pluzhnikov" <besp@midway.uchicago.edu>. */ - if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { - int saved_errno; -close_and_ret: - saved_errno = errno; - close(fd); - __set_errno(saved_errno); - return NULL; - } - if (!(ptr = malloc(sizeof(*ptr)))) - goto nomem_close_and_ret; +#ifndef __ASSUME_O_CLOEXEC + fcntl_not_cancel(fd, F_SETFD, FD_CLOEXEC); +#endif - ptr->dd_fd = fd; - ptr->dd_nextloc = ptr->dd_size = ptr->dd_nextoff = 0; - ptr->dd_max = statbuf.st_blksize; - if (ptr->dd_max < 512) - ptr->dd_max = 512; + ptr = fd_to_DIR(fd, statbuf.st_blksize); - if (!(ptr->dd_buf = calloc(1, ptr->dd_max))) { - free(ptr); -nomem_close_and_ret: - close(fd); - __set_errno(ENOMEM); - return NULL; + if (!ptr) { + close_not_cancel_no_status(fd); + /* __set_errno(ENOMEM); */ } - __pthread_mutex_init(&(ptr->dd_lock), NULL); return ptr; } libc_hidden_def(opendir) diff --git a/libc/misc/dirent/readdir.c b/libc/misc/dirent/readdir.c index 2fb7a7246..75171064d 100644 --- a/libc/misc/dirent/readdir.c +++ b/libc/misc/dirent/readdir.c @@ -4,21 +4,22 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#include <features.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> #include <dirent.h> +#include <errno.h> +#define __need_NULL +#include <stddef.h> #include "dirstream.h" -libc_hidden_proto(readdir) +#ifndef __READDIR +# define __READDIR readdir +# define __DIRENT_TYPE struct dirent +# define __GETDENTS __getdents +#endif -struct dirent *readdir(DIR * dir) +__DIRENT_TYPE *__READDIR(DIR * dir) { ssize_t bytes; - struct dirent *de; + __DIRENT_TYPE *de; if (!dir) { __set_errno(EBADF); @@ -30,7 +31,7 @@ struct dirent *readdir(DIR * dir) do { if (dir->dd_size <= dir->dd_nextloc) { /* read dir->dd_max bytes of directory entries. */ - bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); + bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max); if (bytes <= 0) { de = NULL; goto all_done; @@ -39,7 +40,7 @@ struct dirent *readdir(DIR * dir) dir->dd_nextloc = 0; } - de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc); + de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc); /* Am I right? H.J. */ dir->dd_nextloc += de->d_reclen; @@ -54,4 +55,8 @@ all_done: __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); return de; } -libc_hidden_def(readdir) +libc_hidden_def(__READDIR) +#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64 +strong_alias_untyped(readdir,readdir64) +libc_hidden_def(readdir64) +#endif diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c index e8a29da96..17577a7b6 100644 --- a/libc/misc/dirent/readdir64.c +++ b/libc/misc/dirent/readdir64.c @@ -5,53 +5,12 @@ */ #include <_lfs_64.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> #include <dirent.h> -#include "dirstream.h" - -libc_hidden_proto(readdir64) -struct dirent64 *readdir64(DIR * dir) -{ - ssize_t bytes; - struct dirent64 *de; - - if (!dir) { - __set_errno(EBADF); - return NULL; - } - - __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { - /* read dir->dd_max bytes of directory entries. */ - bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); - if (bytes <= 0) { - de = NULL; - goto all_done; - } - dir->dd_size = bytes; - 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; - - /* Skip deleted files. */ - } while (de->d_ino == 0); -all_done: - __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); +#if __WORDSIZE != 64 +# define __READDIR readdir64 +# define __DIRENT_TYPE struct dirent64 +# define __GETDENTS __getdents64 - return de; -} -libc_hidden_def(readdir64) +# include "readdir.c" +#endif diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c index 2958b1d1a..c045cbdea 100644 --- a/libc/misc/dirent/readdir64_r.c +++ b/libc/misc/dirent/readdir64_r.c @@ -5,64 +5,12 @@ */ #include <_lfs_64.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> #include <dirent.h> -#include "dirstream.h" - -/* Experimentally off - libc_hidden_proto(memcpy) */ - -libc_hidden_proto(readdir64_r) -int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result) -{ - int ret; - ssize_t bytes; - struct dirent64 *de; - - if (!dir) { - __set_errno(EBADF); - return(EBADF); - } - de = NULL; - - __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { - /* read dir->dd_max bytes of directory entries. */ - bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); - if (bytes <= 0) { - *result = NULL; - ret = (bytes==0)? 0 : errno; - goto all_done; - } - dir->dd_size = bytes; - 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; - /* Skip deleted files. */ - } while (de->d_ino == 0); - - if (de == NULL) { - *result = NULL; - } else { - *result = memcpy (entry, de, de->d_reclen); - } - ret = 0; -all_done: +#if __WORDSIZE != 64 +# define __READDIR_R readdir64_r +# define __DIRENT_TYPE struct dirent64 +# define __GETDENTS __getdents64 - __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - return((de != NULL)? 0 : ret); -} -libc_hidden_def(readdir64_r) +# include "readdir_r.c" +#endif diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c index 194af621f..5beebfed0 100644 --- a/libc/misc/dirent/readdir_r.c +++ b/libc/misc/dirent/readdir_r.c @@ -4,35 +4,38 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ +#include <dirent.h> #include <errno.h> -#include <stdlib.h> #include <string.h> -#include <unistd.h> -#include <dirent.h> +#define __need_NULL +#include <stddef.h> #include "dirstream.h" -/* Experimentally off - libc_hidden_proto(memcpy) */ +#ifndef __READDIR_R +# define __READDIR_R readdir_r +# define __DIRENT_TYPE struct dirent +# define __GETDENTS __getdents +#endif -libc_hidden_proto(readdir_r) -int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) +int __READDIR_R(DIR *dir, __DIRENT_TYPE *entry, __DIRENT_TYPE **result) { int ret; ssize_t bytes; - struct dirent *de; + __DIRENT_TYPE *de; if (!dir) { __set_errno(EBADF); return(EBADF); } - de = NULL; __UCLIBC_MUTEX_LOCK(dir->dd_lock); do { if (dir->dd_size <= dir->dd_nextloc) { /* read dir->dd_max bytes of directory entries. */ - bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); + bytes = __GETDENTS(dir->dd_fd, dir->dd_buf, dir->dd_max); if (bytes <= 0) { + de = NULL; *result = NULL; ret = (bytes==0)? 0 : errno; goto all_done; @@ -41,7 +44,7 @@ int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) dir->dd_nextloc = 0; } - de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc); + de = (__DIRENT_TYPE *) (((char *) dir->dd_buf) + dir->dd_nextloc); /* Am I right? H.J. */ dir->dd_nextloc += de->d_reclen; @@ -63,4 +66,8 @@ all_done: __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); return((de != NULL)? 0 : ret); } -libc_hidden_def(readdir_r) +libc_hidden_def(__READDIR_R) +#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64 +strong_alias_untyped(readdir_r,readdir64_r) +libc_hidden_def(readdir64_r) +#endif diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c index 1bbda0809..0a8f14740 100644 --- a/libc/misc/dirent/rewinddir.c +++ b/libc/misc/dirent/rewinddir.c @@ -9,7 +9,6 @@ #include <unistd.h> #include "dirstream.h" -libc_hidden_proto(lseek) /* rewinddir() just does an lseek(fd,0,0) - see close for comments */ void rewinddir(DIR * dir) diff --git a/libc/misc/dirent/scandir.c b/libc/misc/dirent/scandir.c index aba63f20b..c036ce59b 100644 --- a/libc/misc/dirent/scandir.c +++ b/libc/misc/dirent/scandir.c @@ -1,30 +1,29 @@ +/* vi: set sw=4 ts=4: */ /* - * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ #include <dirent.h> -#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> -#include <sys/types.h> #include "dirstream.h" -/* Experimentally off - libc_hidden_proto(memcpy) */ -libc_hidden_proto(readdir) -libc_hidden_proto(opendir) -libc_hidden_proto(closedir) -libc_hidden_proto(qsort) +#ifndef __SCANDIR +# define __SCANDIR scandir +# define __DIRENT_TYPE struct dirent +# define __READDIR readdir +#endif -int scandir(const char *dir, struct dirent ***namelist, - int (*selector) (const struct dirent *), - int (*compar) (const void *, const void *)) +int __SCANDIR(const char *dir, __DIRENT_TYPE ***namelist, + int (*selector) (const __DIRENT_TYPE *), + int (*compar) (const __DIRENT_TYPE **, const __DIRENT_TYPE **)) { DIR *dp = opendir (dir); - struct dirent *current; - struct dirent **names = NULL; + __DIRENT_TYPE *current; + __DIRENT_TYPE **names = NULL; size_t names_size = 0, pos; int save; @@ -35,10 +34,21 @@ int scandir(const char *dir, struct dirent ***namelist, __set_errno (0); pos = 0; - while ((current = readdir (dp)) != NULL) - if (selector == NULL || (*selector) (current)) + while ((current = __READDIR (dp)) != NULL) { + int use_it = selector == NULL; + + if (! use_it) + { + use_it = (*selector) (current); + /* The selector function might have changed errno. + * It was zero before and it need to be again to make + * the latter tests work. */ + if (! use_it) + __set_errno (0); + } + if (use_it) { - struct dirent *vnew; + __DIRENT_TYPE *vnew; size_t dsize; /* Ignore errors from selector or readdir */ @@ -46,24 +56,26 @@ int scandir(const char *dir, struct dirent ***namelist, if (unlikely(pos == names_size)) { - struct dirent **new; + __DIRENT_TYPE **new; if (names_size == 0) names_size = 10; else names_size *= 2; - new = (struct dirent **) realloc (names, names_size * sizeof (struct dirent *)); + new = (__DIRENT_TYPE **) realloc (names, + names_size * sizeof (__DIRENT_TYPE *)); if (new == NULL) break; names = new; } - dsize = ¤t->d_name[_D_ALLOC_NAMLEN (current)] - (char *) current; - vnew = (struct dirent *) malloc (dsize); + dsize = ¤t->d_name[_D_ALLOC_NAMLEN(current)] - (char*)current; + vnew = (__DIRENT_TYPE *) malloc (dsize); if (vnew == NULL) break; - names[pos++] = (struct dirent *) memcpy (vnew, current, dsize); + names[pos++] = (__DIRENT_TYPE *) memcpy (vnew, current, dsize); } + } if (unlikely(errno != 0)) { @@ -81,7 +93,10 @@ int scandir(const char *dir, struct dirent ***namelist, /* Sort the list if we have a comparison function to sort with. */ if (compar != NULL) - qsort (names, pos, sizeof (struct dirent *), compar); + qsort (names, pos, sizeof (__DIRENT_TYPE *), (comparison_fn_t) compar); *namelist = names; return pos; } +#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64 +strong_alias_untyped(scandir,scandir64) +#endif diff --git a/libc/misc/dirent/scandir64.c b/libc/misc/dirent/scandir64.c index 083d2de18..634c5d886 100644 --- a/libc/misc/dirent/scandir64.c +++ b/libc/misc/dirent/scandir64.c @@ -1,105 +1,16 @@ -/* Copyright (C) 1992-1998, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. - */ - -/* Modified for uClibc by Erik Andersen - */ +/* + * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <_lfs_64.h> - #include <dirent.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/types.h> -#include "dirstream.h" - -/* Experimentally off - libc_hidden_proto(memcpy) */ -libc_hidden_proto(opendir) -libc_hidden_proto(closedir) -libc_hidden_proto(qsort) -libc_hidden_proto(readdir64) - -int scandir64(const char *dir, struct dirent64 ***namelist, - int (*selector) (const struct dirent64 *), - int (*compar) (const void *, const void *)) -{ - DIR *dp = opendir (dir); - struct dirent64 *current; - struct dirent64 **names = NULL; - size_t names_size = 0, pos; - int save; - - if (dp == NULL) - return -1; - - save = errno; - __set_errno (0); - - pos = 0; - while ((current = readdir64 (dp)) != NULL) - if (selector == NULL || (*selector) (current)) - { - struct dirent64 *vnew; - size_t dsize; - - /* Ignore errors from selector or readdir64 */ - __set_errno (0); - - if (unlikely(pos == names_size)) - { - struct dirent64 **new; - if (names_size == 0) - names_size = 10; - else - names_size *= 2; - new = (struct dirent64 **) realloc (names, names_size * sizeof (struct dirent64 *)); - if (new == NULL) - break; - names = new; - } - - dsize = ¤t->d_name[_D_ALLOC_NAMLEN (current)] - (char *) current; - vnew = (struct dirent64 *) malloc (dsize); - if (vnew == NULL) - break; - - names[pos++] = (struct dirent64 *) memcpy (vnew, current, dsize); - } - - if (unlikely(errno != 0)) - { - save = errno; - closedir (dp); - while (pos > 0) - free (names[--pos]); - free (names); - __set_errno (save); - return -1; - } - closedir (dp); - __set_errno (save); +#if __WORDSIZE != 64 +# define __SCANDIR scandir64 +# define __DIRENT_TYPE struct dirent64 +# define __READDIR readdir64 - /* Sort the list if we have a comparison function to sort with. */ - if (compar != NULL) - qsort (names, pos, sizeof (struct dirent64 *), compar); - *namelist = names; - return pos; -} +# include "scandir.c" +#endif diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c index c41844856..eaf447ea2 100644 --- a/libc/misc/dirent/seekdir.c +++ b/libc/misc/dirent/seekdir.c @@ -9,7 +9,6 @@ #include <unistd.h> #include "dirstream.h" -libc_hidden_proto(lseek) void seekdir(DIR * dir, long int offset) { diff --git a/libc/misc/dirent/versionsort.c b/libc/misc/dirent/versionsort.c new file mode 100644 index 000000000..8e56ec56b --- /dev/null +++ b/libc/misc/dirent/versionsort.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2008-2009 Hai Zaar, Codefidence Ltd <haizaar@codefidence.com> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <dirent.h> +#include <string.h> +#include "dirstream.h" + +int versionsort(const struct dirent **a, const struct dirent **b) +{ + return strverscmp((*a)->d_name, (*b)->d_name); +} +#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64 +strong_alias_untyped(versionsort,versionsort64) +#endif diff --git a/libc/misc/dirent/versionsort64.c b/libc/misc/dirent/versionsort64.c new file mode 100644 index 000000000..28fef7d3f --- /dev/null +++ b/libc/misc/dirent/versionsort64.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2008-2009 Hai Zaar, Codefidence Ltd <haizaar@codefidence.com> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <_lfs_64.h> +#include <dirent.h> + +#if __WORDSIZE != 64 +# include <string.h> +# include "dirstream.h" + +int versionsort64(const struct dirent64 **a, const struct dirent64 **b) +{ + return strverscmp((*a)->d_name, (*b)->d_name); +} +#endif |
