}
struct dirent *readdir_ensure_type(DIR *d) {
- struct dirent *de;
+ int r;
assert(d);
- errno = 0;
- de = readdir(d);
- if (de)
- (void) dirent_ensure_type(d, de);
- return de;
+ /* Like readdir(), but fills in .d_type if it is DT_UNKNOWN */
+
+ for (;;) {
+ struct dirent *de;
+
+ errno = 0;
+ de = readdir(d);
+ if (!de)
+ return NULL;
+
+ r = dirent_ensure_type(d, de);
+ if (r >= 0)
+ return de;
+ if (r != -ENOENT) {
+ errno = -r; /* We want to be compatible with readdir(), hence propagate error via errno here */
+ return NULL;
+ }
+
+ /* Vanished by now? Then skip immedately to next */
+ }
}
-struct dirent *readdir_no_dot(DIR *dirp) {
- struct dirent *d;
+struct dirent *readdir_no_dot(DIR *d) {
+ assert(d);
for (;;) {
- d = readdir_ensure_type(dirp);
- if (d && dot_or_dot_dot(d->d_name))
- continue;
- return d;
+ struct dirent *de;
+
+ de = readdir_ensure_type(d);
+ if (!de || !dot_or_dot_dot(de->d_name))
+ return de;
}
}