[klibc] [PATCH] dirent.h add fdopendir()

maximilian attems max at stro.at
Wed Aug 10 11:43:55 PDT 2011


Initial implemenation with quick test.

Signed-off-by: maximilian attems <max at stro.at>
---

Should maybe go to a seperate file too..

 usr/include/dirent.h        |    1 +
 usr/klibc/readdir.c         |   37 ++++++++++++++++++++++++++++++++++++-
 usr/klibc/tests/Kbuild      |    1 +
 usr/klibc/tests/fdopendir.c |   31 +++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 1 deletions(-)
 create mode 100644 usr/klibc/tests/fdopendir.c

diff --git a/usr/include/dirent.h b/usr/include/dirent.h
index 725452e..bc08c5c 100644
--- a/usr/include/dirent.h
+++ b/usr/include/dirent.h
@@ -23,6 +23,7 @@ struct _IO_dir {
 typedef struct _IO_dir DIR;
 
 __extern DIR *opendir(const char *);
+__extern DIR *fdopendir(int);
 __extern struct dirent *readdir(DIR *);
 __extern int closedir(DIR *);
 static __inline__ int dirfd(DIR * __d)
diff --git a/usr/klibc/readdir.c b/usr/klibc/readdir.c
index 453fc08..1ea8b99 100644
--- a/usr/klibc/readdir.c
+++ b/usr/klibc/readdir.c
@@ -1,10 +1,13 @@
 /*
- * readdir.c: opendir/readdir/closedir
+ * readdir.c: opendir/fdopendir/readdir/closedir
  */
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #define __KLIBC_DIRENT_INTERNALS
 #include <dirent.h>
@@ -28,6 +31,38 @@ DIR *opendir(const char *name)
 	return dp;
 }
 
+DIR *fdopendir(int fd)
+{
+	DIR *dp;
+	int flags;
+	struct stat st;
+
+	if (fstat(fd, &st))
+		return NULL;
+	if (!S_ISDIR(st.st_mode)) {
+		errno = ENOTDIR;
+		return NULL;
+	}
+
+	flags = fcntl(fd, F_GETFL);
+	if (flags == -1)
+		return NULL;
+	if ((flags & O_ACCMODE) == O_WRONLY) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	dp = malloc(sizeof(DIR));
+
+	if(!dp)
+		return NULL;
+
+	dp->__fd = fd;
+	dp->next = NULL;
+	dp->bytes_left = 0;
+	return dp;
+}
+
 struct dirent *readdir(DIR *dir)
 {
 	struct dirent *dent;
diff --git a/usr/klibc/tests/Kbuild b/usr/klibc/tests/Kbuild
index a3e0254..5e6e073 100644
--- a/usr/klibc/tests/Kbuild
+++ b/usr/klibc/tests/Kbuild
@@ -14,6 +14,7 @@ static-y := $(test-files:.c=)
 shared-y := $(addsuffix .shared, $(static-y))
 
 environ.shared-y	:= environ.o
+fdopendir.shared-y	:= fdopendir.o
 fcntl.shared-y		:= fcntl.o
 fnmatch.shared-y	:= fnmatch.o
 getopttest.shared-y	:= getopttest.o
diff --git a/usr/klibc/tests/fdopendir.c b/usr/klibc/tests/fdopendir.c
new file mode 100644
index 0000000..14bd99b
--- /dev/null
+++ b/usr/klibc/tests/fdopendir.c
@@ -0,0 +1,31 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdio.h>
+
+int main()
+{
+	DIR *dir;
+	struct dirent dirent;
+	int fd;
+
+	/* XXX: use mktemps */
+	fd = open("/tmp/", O_RDONLY);
+	if (fd < 0) {
+		perror("open");
+		return 1;
+	}
+
+	dir = fdopendir(fd);
+	if (!dir) {
+		perror("fdopendir");
+		close(fd):
+		return 1;
+	}
+	while ((dirent = readdir(dir)) != NULL)
+		;
+
+	closedir(dir):
+	return 0;
+}
-- 
1.7.5.4



More information about the klibc mailing list