libc: Implement a basic subset of dirent.h
This commit is contained in:
parent
32db366781
commit
8bf2904d74
@ -1,28 +1,22 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <luna/dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int dirfd = open("/bin", O_RDONLY);
|
||||
if (dirfd < 0)
|
||||
DIR* dp = opendir("/bin");
|
||||
if (!dp)
|
||||
{
|
||||
perror("open");
|
||||
perror("opendir");
|
||||
return 1;
|
||||
}
|
||||
struct luna_dirent dirent[5];
|
||||
ssize_t nread;
|
||||
do {
|
||||
nread = getdents(dirfd, dirent, 5);
|
||||
if (nread < 0)
|
||||
{
|
||||
perror("getdents");
|
||||
return 1;
|
||||
}
|
||||
for (int i = 0; i < nread; i++) { printf("%s\n", dirent[i].name); }
|
||||
} while (nread == 5);
|
||||
struct dirent* ent = readdir(dp);
|
||||
if (!ent) break;
|
||||
printf("%s\n", ent->d_name);
|
||||
} while (1);
|
||||
|
||||
close(dirfd);
|
||||
closedir(dp);
|
||||
return 0;
|
||||
}
|
@ -10,6 +10,8 @@ typedef long ssize_t;
|
||||
|
||||
#define VFS_MOUNTPOINT 0x1
|
||||
|
||||
#define NAME_MAX 64
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
struct Node;
|
||||
@ -23,7 +25,7 @@ namespace VFS
|
||||
|
||||
struct Node
|
||||
{
|
||||
char name[64];
|
||||
char name[NAME_MAX];
|
||||
uint64_t inode;
|
||||
uint64_t length;
|
||||
int type;
|
||||
|
43
libs/libc/include/dirent.h
Normal file
43
libs/libc/include/dirent.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef _DIRENT_H
|
||||
#define _DIRENT_H
|
||||
|
||||
#include <luna/os-limits.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct dirent
|
||||
{
|
||||
ino_t d_ino;
|
||||
off_t d_off;
|
||||
unsigned short d_reclen;
|
||||
unsigned char d_type;
|
||||
char d_name[NAME_MAX];
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int d_dirfd;
|
||||
} DIR;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Opens the directory at path and returns a handle to it, or NULL on error. */
|
||||
DIR* opendir(const char* path);
|
||||
|
||||
/* Returns a new directory handle associated with the file descriptor fd. */
|
||||
DIR* fdopendir(int fd);
|
||||
|
||||
/* Closes the directory stream. */
|
||||
int closedir(DIR* stream);
|
||||
|
||||
/* Reads an entry from the directory stream. The contents of the pointer returned may be overwritten by subsequent
|
||||
* calls to readdir(). */
|
||||
struct dirent* readdir(DIR* stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,12 +1,13 @@
|
||||
#ifndef _LUNA_DIRENT_H
|
||||
#define _LUNA_DIRENT_H
|
||||
|
||||
#include <luna/os-limits.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct luna_dirent
|
||||
{
|
||||
ino_t inode;
|
||||
char name[64];
|
||||
char name[NAME_MAX];
|
||||
size_t total;
|
||||
off_t offset;
|
||||
};
|
||||
|
@ -4,6 +4,8 @@
|
||||
#define OPEN_MAX 32
|
||||
#define ATEXIT_MAX 32
|
||||
|
||||
#define NAME_MAX 64
|
||||
|
||||
#define PAGESIZE 4096
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
|
53
libs/libc/src/dirent.cpp
Normal file
53
libs/libc/src/dirent.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user