diff options
Diffstat (limited to 'src/dirent/readdir.c')
| -rw-r--r-- | src/dirent/readdir.c | 49 |
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; } /* |
