summaryrefslogtreecommitdiff
path: root/src/dirent/readdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dirent/readdir.c')
-rw-r--r--src/dirent/readdir.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c
index 0e079f82..f8198169 100644
--- a/src/dirent/readdir.c
+++ b/src/dirent/readdir.c
@@ -1,10 +1,55 @@
#include <dirent.h>
+#include "limits.h"
+#include "errno.h"
+#include "sys/types.h"
#include "stddef.h"
+#include "_dirent.h"
+#include "unistd.h"
+#include "../_syscall.h"
+
+#ifndef NAME_MAX
+#define NAME_MAX _POSIX_NAME_MAX
+#endif
struct dirent * readdir(DIR * dirp)
{
- (void)dirp;
- return NULL;
+ struct {
+ unsigned long inode;
+ unsigned long offset;
+ unsigned short length;
+ } kernel_de = { 0, 0, 0 };
+ if (read(dirp->fd, &kernel_de, sizeof(kernel_de)) == -1) {
+ if (errno == EISDIR) {
+ struct {
+ long inode;
+ off_t offset;
+ unsigned short reclen;
+ char name[NAME_MAX + 1];
+ } linux = { 0, 0, 0, "" };
+ long ret = __syscall(__syscall_lookup(getdents), dirp->fd, &linux, sizeof(linux));
+ if (ret < 0) {
+ errno = -ret;
+ return NULL;
+ }
+
+ #ifdef _XOPEN_SOURCE
+ dirp->de.d_ino = linux.inode;
+ #endif
+ strcpy(dirp->de.d_name, linux.name);
+ return &dirp->de;
+ }
+ return NULL;
+ }
+
+ #ifdef _XOPEN_SOURCE
+ dirp->de.d_ino = inode;
+ #endif
+
+ if (read(dirp->fd, &dirp->de.d_name, kernel_de.length) == -1) {
+ return NULL;
+ }
+
+ return &dirp->de;
}
/*