From f6fabdfcc7ee34bbaef30c5cef540152e5c7b224 Mon Sep 17 00:00:00 2001
From: Eric Andersen <andersen@codepoet.org>
Date: Wed, 17 Oct 2001 03:17:15 +0000
Subject: In theory, this adds readdir64 and friends.  Dunno if they work yet
 or not....  -Erik

---
 libc/misc/dirent/Makefile      |  3 +-
 libc/misc/dirent/alphasort64.c | 16 ++++++++
 libc/misc/dirent/dirstream.h   |  2 +-
 libc/misc/dirent/opendir.c     |  2 +-
 libc/misc/dirent/readdir64.c   | 68 ++++++++++++++++++++++++++++++++
 libc/misc/dirent/scandir64.c   | 88 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 libc/misc/dirent/alphasort64.c
 create mode 100644 libc/misc/dirent/readdir64.c
 create mode 100644 libc/misc/dirent/scandir64.c

(limited to 'libc/misc/dirent')

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__ */
+
-- 
cgit v1.2.3