#include #include #include #include #include #include #include extern "C" { DIR* opendir(const char* path) { int fd = open(path, O_RDONLY | O_DIRECTORY); if (fd < 0) return NULL; return fdopendir(fd); } 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; } int dirfd(DIR* stream) { return stream->d_dirfd; } void rewinddir(DIR* stream) { lseek(stream->d_dirfd, 0, SEEK_SET); } long telldir(DIR* stream) { return lseek(stream->d_dirfd, 0, SEEK_CUR); } void seekdir(DIR* stream, long offset) { lseek(stream->d_dirfd, offset, SEEK_SET); } }