53 lines
1.4 KiB
C++
53 lines
1.4 KiB
C++
|
#include <dirent.h>
|
||
|
#include <errno.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <luna/dirent.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
extern "C"
|
||
|
{
|
||
|
DIR* opendir(const char* path)
|
||
|
{
|
||
|
int dirfd = open(path, O_RDONLY); // FIXME: Implement O_DIRECTORY and use that.
|
||
|
if (dirfd < 0) return NULL;
|
||
|
return fdopendir(dirfd);
|
||
|
}
|
||
|
|
||
|
DIR* fdopendir(int fd)
|
||
|
{
|
||
|
if (fd < 0) return NULL;
|
||
|
DIR* result = (DIR*)malloc(sizeof(DIR));
|
||
|
if (!result) return NULL;
|
||
|
result->d_dirfd = fd;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
int closedir(DIR* stream)
|
||
|
{
|
||
|
int status = close(stream->d_dirfd);
|
||
|
if (status < 0)
|
||
|
{
|
||
|
int savederr = errno;
|
||
|
free(stream);
|
||
|
errno = savederr; // free might reset errno. We don't want that.
|
||
|
}
|
||
|
else { free(stream); }
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
struct dirent* readdir(DIR* stream)
|
||
|
{
|
||
|
static struct dirent result;
|
||
|
struct luna_dirent ent;
|
||
|
ssize_t nread = getdents(stream->d_dirfd, &ent, 1); // FIXME: Use a buffer to avoid too many system calls.
|
||
|
if (nread <= 0) return NULL; // Either EOF or error.
|
||
|
result.d_ino = ent.inode;
|
||
|
result.d_reclen = sizeof(result);
|
||
|
result.d_off = ent.offset;
|
||
|
result.d_type = 0;
|
||
|
strlcpy(result.d_name, ent.name, NAME_MAX);
|
||
|
return &result;
|
||
|
}
|
||
|
}
|