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 <fcntl.h>
|
||||||
#include <luna/dirent.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int dirfd = open("/bin", O_RDONLY);
|
DIR* dp = opendir("/bin");
|
||||||
if (dirfd < 0)
|
if (!dp)
|
||||||
{
|
{
|
||||||
perror("open");
|
perror("opendir");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
struct luna_dirent dirent[5];
|
|
||||||
ssize_t nread;
|
|
||||||
do {
|
do {
|
||||||
nread = getdents(dirfd, dirent, 5);
|
struct dirent* ent = readdir(dp);
|
||||||
if (nread < 0)
|
if (!ent) break;
|
||||||
{
|
printf("%s\n", ent->d_name);
|
||||||
perror("getdents");
|
} while (1);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < nread; i++) { printf("%s\n", dirent[i].name); }
|
|
||||||
} while (nread == 5);
|
|
||||||
|
|
||||||
close(dirfd);
|
closedir(dp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -10,6 +10,8 @@ typedef long ssize_t;
|
|||||||
|
|
||||||
#define VFS_MOUNTPOINT 0x1
|
#define VFS_MOUNTPOINT 0x1
|
||||||
|
|
||||||
|
#define NAME_MAX 64
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
{
|
{
|
||||||
struct Node;
|
struct Node;
|
||||||
@ -23,7 +25,7 @@ namespace VFS
|
|||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
char name[64];
|
char name[NAME_MAX];
|
||||||
uint64_t inode;
|
uint64_t inode;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
int type;
|
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
|
#ifndef _LUNA_DIRENT_H
|
||||||
#define _LUNA_DIRENT_H
|
#define _LUNA_DIRENT_H
|
||||||
|
|
||||||
|
#include <luna/os-limits.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
struct luna_dirent
|
struct luna_dirent
|
||||||
{
|
{
|
||||||
ino_t inode;
|
ino_t inode;
|
||||||
char name[64];
|
char name[NAME_MAX];
|
||||||
size_t total;
|
size_t total;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#define OPEN_MAX 32
|
#define OPEN_MAX 32
|
||||||
#define ATEXIT_MAX 32
|
#define ATEXIT_MAX 32
|
||||||
|
|
||||||
|
#define NAME_MAX 64
|
||||||
|
|
||||||
#define PAGESIZE 4096
|
#define PAGESIZE 4096
|
||||||
#define PAGE_SIZE 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