diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-15 14:12:11 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-15 14:12:11 -0700 |
commit | 0506a36568ff0b4fd482513bc919d2031c35d04f (patch) | |
tree | e028694f0ec2a7fa5edb682479deef89ada29bd1 | |
parent | 761b6499b9f9d333ef4860e95d1e2539c0326ec3 (diff) | |
download | klibc-0506a36568ff0b4fd482513bc919d2031c35d04f.tar.gz |
[klibc] Add fdopendir(), fix dirfd()
Add fdopendir() by splitting opendir() into two components. Note
that the fdopendir() implementation doesn't actually check the
validity of the file descriptor; we just let readdir() return an error
if someone passed us garbage.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | usr/include/dirent.h | 4 | ||||
-rw-r--r-- | usr/klibc/readdir.c | 27 |
2 files changed, 22 insertions, 9 deletions
diff --git a/usr/include/dirent.h b/usr/include/dirent.h index d36e9749d71fe..43df503cd47f0 100644 --- a/usr/include/dirent.h +++ b/usr/include/dirent.h @@ -5,6 +5,7 @@ #ifndef _DIRENT_H #define _DIRENT_H +#include <klibc/compiler.h> #include <klibc/extern.h> #include <klibc/sysconfig.h> #include <sys/dirent.h> @@ -23,10 +24,11 @@ struct _IO_dir { }; typedef struct _IO_dir DIR; +__extern DIR *fdopendir(int); __extern DIR *opendir(const char *); __extern struct dirent *readdir(DIR *); __extern int closedir(DIR *); -static __inline__ int dirfd(DIR * __d) +__static_inline int dirfd(DIR * __d) { return __d->__fd; } diff --git a/usr/klibc/readdir.c b/usr/klibc/readdir.c index 453fc082ca6ad..8134c92f90e66 100644 --- a/usr/klibc/readdir.c +++ b/usr/klibc/readdir.c @@ -5,26 +5,37 @@ #include <unistd.h> #include <fcntl.h> #include <stdlib.h> +#include <errno.h> #define __KLIBC_DIRENT_INTERNALS #include <dirent.h> -DIR *opendir(const char *name) +DIR *fdopendir(int fd) { - DIR *dp = malloc(sizeof(DIR)); + DIR *dp = zalloc(sizeof(DIR)); if (!dp) return NULL; - dp->__fd = open(name, O_DIRECTORY | O_RDONLY); + dp->__fd = fd; + return dp; +} - if (dp->__fd < 0) { - free(dp); - return NULL; - } +DIR *opendir(const char *name) +{ + int fd, err; + DIR *dp; - dp->bytes_left = 0; + fd = open(name, O_DIRECTORY | O_RDONLY); + if (fd < 0) + return NULL; + dp = fdopendir(fd); + if (!dp) { + err = errno; + close(fd); + errno = err; + } return dp; } |