73 lines
1.7 KiB
C++
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);
|
|
}
|
|
} |