[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