lib: c: io: implement standard FILE and DIR interfaces

This commit is contained in:
2026-03-25 20:21:12 +00:00
parent b975256cb9
commit 96784f611f
21 changed files with 599 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
#include "dir.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define DEFAULT_BUFFER_SIZE 4096
static void dirent_convert(const struct dentry *in, struct dirent *out)
{
out->d_ino = in->d_ino;
out->d_type = in->d_type;
out->d_reclen = in->d_reclen;
strncpy(out->d_name, in->d_name, sizeof out->d_name - 1);
out->d_name[sizeof out->d_name - 1] = 0;
}
int __libc_dir_refill(struct __opaque_dir *d)
{
if (d->d_fd < 0) {
return EBADF;
}
if (d->d_flags & DIR_ERR) {
return EIO;
}
if (d->d_flags & DIR_EOF) {
return SUCCESS;
}
if (!d->d_buf) {
d->d_buf_max = DEFAULT_BUFFER_SIZE;
d->d_buf = malloc(d->d_buf_max);
if (!d->d_buf) {
d->d_buf_max = 0;
return ENOMEM;
}
}
long r = getdents(d->d_fd, (struct dentry *)d->d_buf, d->d_buf_max);
if (r < 0) {
return -r;
}
d->d_buf_datalen = r;
if (r > 0) {
struct dentry *dent
= (struct dentry *)(d->d_buf + d->d_buf_readptr);
dirent_convert(dent, &d->d_current);
}
return SUCCESS;
}
int __libc_dir_move_next(struct __opaque_dir *d)
{
if (d->d_fd < 0) {
return -EBADF;
}
if (d->d_flags & DIR_ERR) {
return -EIO;
}
if (d->d_flags & DIR_EOF) {
return -SUCCESS;
}
d->d_buf_readptr += d->d_current.d_reclen;
if (d->d_buf_readptr >= d->d_buf_datalen) {
return 0;
}
struct dentry *dent = (struct dentry *)(d->d_buf + d->d_buf_readptr);
dirent_convert(dent, &d->d_current);
return 1;
}