lib: c: io: implement standard FILE and DIR interfaces
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user