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

maximilian attems max at stro.at
Wed Aug 10 13:57:02 PDT 2011


Initial implemenation with quick test.

Reviewed-by: Sam Ravnborg <sam at ravnborg.org>
Signed-off-by: maximilian attems <max at stro.at>
---
 v4: checkpatch warnings.
 v3: return ENOMEM on malloc failure.                                            v2: seperate file.

 usr/include/dirent.h        |    1 +
 usr/klibc/Kbuild            |    3 ++-
 usr/klibc/fdopendir.c       |   41 +++++++++++++++++++++++++++++++++++++++++
 usr/klibc/tests/Kbuild      |    1 +
 usr/klibc/tests/fdopendir.c |   31 +++++++++++++++++++++++++++++++
 5 files changed, 76 insertions(+), 1 deletions(-)
 create mode 100644 usr/klibc/fdopendir.c
 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/Kbuild b/usr/klibc/Kbuild
index c4f9ae2..48575a5 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -42,7 +42,8 @@ klib-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \
 	  seteuid.o setegid.o \
 	  getenv.o setenv.o putenv.o __put_env.o unsetenv.o \
 	  clearenv.o nullenv.o \
-	  getopt.o getopt_long.o readdir.o scandir.o alphasort.o remove.o \
+	  getopt.o getopt_long.o \
+	  readdir.o scandir.o fdopendir.o alphasort.o remove.o \
 	  syslog.o closelog.o pty.o getpt.o posix_openpt.o isatty.o reboot.o \
 	  time.o utime.o llseek.o nice.o getpriority.o \
 	  qsort.o bsearch.o \
diff --git a/usr/klibc/fdopendir.c b/usr/klibc/fdopendir.c
new file mode 100644
index 0000000..e89d957
--- /dev/null
+++ b/usr/klibc/fdopendir.c
@@ -0,0 +1,41 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define __KLIBC_DIRENT_INTERNALS
+#include <dirent.h>
+
+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) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	dp->__fd = fd;
+	dp->next = NULL;
+	dp->bytes_left = 0;
+	return dp;
+}
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..3fcaebd
--- /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