Luna/libs/libc/src/dirent.cpp

73 lines
1.7 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 fd = open(path, O_RDONLY | O_DIRECTORY);
if (fd < 0) return NULL;
return fdopendir(fd);
}
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;
}
int dirfd(DIR* stream)
{
return stream->d_dirfd;
}
void rewinddir(DIR* stream)
{
lseek(stream->d_dirfd, 0, SEEK_SET);
}
long telldir(DIR* stream)
{
return lseek(stream->d_dirfd, 0, SEEK_CUR);
}
void seekdir(DIR* stream, long offset)
{
lseek(stream->d_dirfd, offset, SEEK_SET);
}
}