82 lines
1.4 KiB
C
82 lines
1.4 KiB
C
|
|
#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;
|
||
|
|
}
|