summaryrefslogtreecommitdiff
path: root/libc/misc/dirent
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc/dirent')
-rw-r--r--libc/misc/dirent/Makefile.in24
-rw-r--r--libc/misc/dirent/alphasort.c11
-rw-r--r--libc/misc/dirent/alphasort64.c13
-rw-r--r--libc/misc/dirent/closedir.c5
-rw-r--r--libc/misc/dirent/dirfd.c1
-rw-r--r--libc/misc/dirent/dirstream.h21
-rw-r--r--libc/misc/dirent/opendir.c98
-rw-r--r--libc/misc/dirent/readdir.c29
-rw-r--r--libc/misc/dirent/readdir64.c53
-rw-r--r--libc/misc/dirent/readdir64_r.c64
-rw-r--r--libc/misc/dirent/readdir_r.c29
-rw-r--r--libc/misc/dirent/rewinddir.c1
-rw-r--r--libc/misc/dirent/scandir.c59
-rw-r--r--libc/misc/dirent/scandir64.c111
-rw-r--r--libc/misc/dirent/seekdir.c1
-rw-r--r--libc/misc/dirent/versionsort.c17
-rw-r--r--libc/misc/dirent/versionsort64.c18
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 = &current->d_name[_D_ALLOC_NAMLEN (current)] - (char *) current;
- vnew = (struct dirent *) malloc (dsize);
+ dsize = &current->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 = &current->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