commit 81f1b58d3ec9c41568677179b86052a077506ebe
parent c170e6f97f87c2f42bac587c650ec4f7eb7e5633
Author: Sebastian <sebastian@sebsite.pw>
Date: Tue, 17 Oct 2023 21:09:40 -0400
fs: skip . and .. when iterating
Nearly all code that uses fs::iter/os::iter needs to include something
along the lines of `if (ent.name == "." || ent.name == "..") continue;`.
So fs::next has been modified to skip over `.` and `..` instead.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
6 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/cmd/hare/cache.ha b/cmd/hare/cache.ha
@@ -54,9 +54,6 @@ fn dirsize(buf: *path::buffer) (size | error) = {
case void =>
break;
case let d: fs::dirent =>
- if (d.name == "." || d.name == "..") {
- continue;
- };
path::push(buf, d.name)?;
let stat = os::stat(path::string(buf))?;
s += stat.sz;
diff --git a/fs/fs.ha b/fs/fs.ha
@@ -301,7 +301,8 @@ export fn symlink(fs: *fs, target: str, path: str) (void | error) = {
};
// Returns the next directory entry from an iterator, or void if none remain.
-// It is a programming error to call this again after it has returned void. The
-// file stat returned may only have the type bits set on the file mode; callers
-// should call [[stat]] to obtain the detailed file mode.
+// '.' and '..' are skipped. It is a programming error to call this again after
+// it has returned void. The file stat returned may only have the type bits set
+// on the file mode; callers should call [[stat]] to obtain the detailed file
+// mode.
export fn next(iter: *iterator) (dirent | void) = iter.next(iter);
diff --git a/fs/util.ha b/fs/util.ha
@@ -118,9 +118,6 @@ fn rmdirall_path(fs: *fs, buf: *path::buffer) (void | error) = {
for (true) {
match (next(it)) {
case let ent: dirent =>
- if (ent.name == "." || ent.name == "..") {
- continue;
- };
path::push(buf, ent.name)!;
switch (ent.ftype & mode::DIR) {
diff --git a/hare/module/srcs.ha b/hare/module/srcs.ha
@@ -281,9 +281,6 @@ fn _findsrcs(
case void =>
break;
case let d: fs::dirent =>
- if (d.name == "." || d.name == "..") {
- continue;
- };
path::push(buf, d.name)?;
defer path::pop(buf);
diff --git a/os/+freebsd/dirfdfs.ha b/os/+freebsd/dirfdfs.ha
@@ -386,6 +386,9 @@ fn iter_next(iter: *fs::iterator) (fs::dirent | void) = {
let de = &iter.buf[iter.buf_pos]: *rt::freebsd11_dirent;
iter.buf_pos += de.d_reclen;
let name = c::tostr(&de.d_name: *const c::char)!;
+ if (name == "." || name == "..") {
+ return iter_next(iter);
+ };
let ftype: fs::mode = switch (de.d_type) {
case rt::DT_UNKNOWN =>
diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha
@@ -429,6 +429,9 @@ fn iter_next(iter: *fs::iterator) (fs::dirent | void) = {
let de = &iter.buf[iter.buf_pos]: *rt::dirent64;
iter.buf_pos += de.d_reclen;
let name = c::tostr(&de.d_name: *const c::char)!;
+ if (name == "." || name == "..") {
+ return iter_next(iter);
+ };
let ftype: fs::mode = switch (de.d_type) {
case rt::DT_UNKNOWN =>