aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2012-05-15 14:12:11 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2012-05-15 14:12:11 -0700
commit0506a36568ff0b4fd482513bc919d2031c35d04f (patch)
treee028694f0ec2a7fa5edb682479deef89ada29bd1
parent761b6499b9f9d333ef4860e95d1e2539c0326ec3 (diff)
downloadklibc-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.h4
-rw-r--r--usr/klibc/readdir.c27
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;
}