| ... | @@ -110,3 +110,42 @@ pub fn makeOpenPath(self: Dir, sub_path: [:0]const u8, flags: OpenDirFlags) !Dir | ... | @@ -110,3 +110,42 @@ pub fn makeOpenPath(self: Dir, sub_path: [:0]const u8, flags: OpenDirFlags) !Dir |
| 110 | pub fn readlink(self: Dir, noalias sub_path: [:0]const u8, noalias buf: []u8) ![:0]u8 { | 110 | pub fn readlink(self: Dir, noalias sub_path: [:0]const u8, noalias buf: []u8) ![:0]u8 { |
| 111 | return sys.readlinkat(@intFromEnum(self.fd), sub_path, buf); | 111 | return sys.readlinkat(@intFromEnum(self.fd), sub_path, buf); |
| 112 | } | 112 | } |
| | 113 | |
| | 114 | pub fn iterate(self: Dir) Iterator { |
| | 115 | return .{ |
| | 116 | .dir = self, |
| | 117 | .buf = undefined, |
| | 118 | .idx = 0, |
| | 119 | .len = 0, |
| | 120 | }; |
| | 121 | } |
| | 122 | |
| | 123 | pub const Iterator = struct { |
| | 124 | dir: Dir, |
| | 125 | buf: [1024]u8, |
| | 126 | idx: usize, |
| | 127 | len: usize, |
| | 128 | |
| | 129 | pub fn next(iter: *Iterator) !?Entry { |
| | 130 | if (iter.idx == iter.len) { |
| | 131 | const len = try sys.getdents(@intFromEnum(iter.dir.fd), &iter.buf); |
| | 132 | if (len == 0) return null; |
| | 133 | iter.len = len; |
| | 134 | } |
| | 135 | const ent: *align(1) sys.struct_dirent = @ptrCast(&iter.buf[iter.idx]); |
| | 136 | iter.idx += ent.reclen; |
| | 137 | const name_nidx = std.mem.indexOfScalar(u8, &ent.name, 0).?; |
| | 138 | const name = ent.name[0..name_nidx :0]; |
| | 139 | if (std.mem.eql(u8, name, ".")) return next(iter); |
| | 140 | if (std.mem.eql(u8, name, "..")) return next(iter); |
| | 141 | return .{ |
| | 142 | .name = name, |
| | 143 | .type = ent.type, |
| | 144 | }; |
| | 145 | } |
| | 146 | |
| | 147 | pub const Entry = struct { |
| | 148 | name: [:0]const u8, |
| | 149 | type: sys.DT, |
| | 150 | }; |
| | 151 | }; |