fix directory stream on Linux as glibc's dirent.h doesn't put . and .. entries to the start

master
Daniel Kolesa 2016-06-28 19:52:37 +01:00
parent 676f76acee
commit 85b7602654
1 changed files with 10 additions and 10 deletions

View File

@ -243,7 +243,7 @@ struct DirectoryStream {
memcpy(buf, &path[0], path.size()); memcpy(buf, &path[0], path.size());
buf[path.size()] = '\0'; buf[path.size()] = '\0';
p_d = opendir(buf); p_d = opendir(buf);
if (!pop_front() || !skip_dots()) { if (!pop_front()) {
close(); close();
return false; return false;
} }
@ -275,7 +275,7 @@ struct DirectoryStream {
bool rewind() { bool rewind() {
if (!p_d) return false; if (!p_d) return false;
rewinddir(p_d); rewinddir(p_d);
if (!pop_front() || !skip_dots()) { if (!pop_front()) {
close(); close();
return false; return false;
} }
@ -305,6 +305,14 @@ private:
if (!d) return false; if (!d) return false;
if (readdir_r(d, dev, de)) if (readdir_r(d, dev, de))
return false; return false;
/* order of . and .. in the stream is not guaranteed, apparently...
* gotta check every time because of that
*/
while (*de && (!strcmp((*de)->d_name, ".") ||
!strcmp((*de)->d_name, ".."))) {
if (readdir_r(d, dev, de))
return false;
}
return !!*de; return !!*de;
} }
@ -312,14 +320,6 @@ private:
return pop_front(p_d, &p_dev, &p_de); return pop_front(p_d, &p_dev, &p_de);
} }
bool skip_dots() {
while (p_de && (!strcmp(p_de->d_name, ".") ||
!strcmp(p_de->d_name, "..")))
if (readdir_r(p_d, &p_dev, &p_de))
return false;
return !!p_de;
}
FileInfo front() const { FileInfo front() const {
if (!p_de) if (!p_de)
return FileInfo(); return FileInfo();