#include "dir.h" #include #include #include #include #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; }