Browse Source

Implement missing readdir64_r.c
-Erik

Eric Andersen 23 years ago
parent
commit
4cd5ca906c
2 changed files with 81 additions and 1 deletions
  1. 2 1
      libc/misc/dirent/Makefile
  2. 79 0
      libc/misc/dirent/readdir64_r.c

+ 2 - 1
libc/misc/dirent/Makefile

@@ -25,7 +25,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 readdir64.c alphasort64.c scandir64.c readdir_r.c
+     	seekdir.c telldir.c readdir64.c alphasort64.c scandir64.c readdir_r.c \
+	readdir64_r.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 OBJS=$(COBJS)
 

+ 79 - 0
libc/misc/dirent/readdir64_r.c

@@ -0,0 +1,79 @@
+#include <features.h>
+#ifdef __UCLIBC_HAVE_LFS__
+#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64 
+#undef _FILE_OFFSET_BITS
+#define	_FILE_OFFSET_BITS   64
+#endif
+#ifndef __USE_LARGEFILE64
+# define __USE_LARGEFILE64	1
+#endif
+/* We absolutely do _NOT_ want interfaces silently
+ * renamed under us or very bad things will happen... */
+#ifdef __USE_FILE_OFFSET64
+# undef __USE_FILE_OFFSET64
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include "dirstream.h"
+
+extern int getdents64 __P ((unsigned int fd, struct dirent64 *dirp, unsigned int count));
+
+
+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;
+
+#ifdef __UCLIBC_HAS_THREADS__
+	pthread_mutex_lock(&(dir->dd_lock));
+#endif
+
+	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 = 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:
+
+#ifdef __UCLIBC_HAS_THREADS__
+	pthread_mutex_unlock(&(dir->dd_lock));
+#endif
+        return((de != NULL)? 0 : ret);
+}
+#endif /* __UCLIBC_HAVE_LFS__ */
+