Luna/libc/src/dirent.cpp

56 lines
1.1 KiB
C++
Raw Normal View History

#include <bits/getdents.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
extern "C"
{
DIR* opendir(const char* path)
{
DIR* dp = (DIR*)malloc(sizeof(DIR));
if (!dp) { return nullptr; }
// FIXME: Use O_DIRECTORY (validate that path is actually a directory)
int fd = open(path, O_RDONLY);
if (fd < 0)
{
free(dp);
return nullptr;
}
dp->_fd = fd;
return dp;
}
struct dirent* readdir(DIR* stream)
{
// FIXME: Very hackish, right now luna_dirent and dirent have the same layout.
static luna_dirent ent;
long rc = syscall(SYS_getdents, stream->_fd, &ent, 1);
if (rc < 0)
{
errno = -rc;
return nullptr;
}
// End-of-file (no more directory entries)
if (rc < 1) return nullptr;
return (struct dirent*)&ent;
}
int closedir(DIR* stream)
{
if (close(stream->_fd) < 0) return -1;
free(stream);
return 0;
}
}