options/posix: implement readdir_r
@@ -66,9 +66,26 @@ struct dirent *readdir(DIR *dir) {
dir->__ent_next += entp->d_reclen;
return &dir->__current;
}
-int readdir_r(DIR *__restrict, struct dirent *__restrict, struct dirent **__restrict) {
- __ensure(!"Not implemented");
- __builtin_unreachable();
+int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) {
+ if(!mlibc::sys_read_entries) {
+ MLIBC_MISSING_SYSDEP();
+ return ENOSYS;
+ }
+
+ __ensure(dir->__ent_next <= dir->__ent_limit);
+ if(dir->__ent_next == dir->__ent_limit) {
+ if(int e = mlibc::sys_read_entries(dir->__handle, dir->__ent_buffer, 2048, &dir->__ent_limit); e)
+ __ensure(!"mlibc::sys_read_entries() failed");
+ dir->__ent_next = 0;
+ if(!dir->__ent_limit)
+ return 0;
+ }
+
+ auto entp = reinterpret_cast<struct dirent *>(dir->__ent_buffer + dir->__ent_next);
+ memcpy(entry, entp, sizeof(struct dirent));
+ dir->__ent_next += entp->d_reclen;
+ *result = entry;
+ return 0;
}
void rewinddir(DIR *) {
__ensure(!"Not implemented");
