| ... | @@ -662,6 +662,7 @@ pub const IterableDir = struct { | ... | @@ -662,6 +662,7 @@ pub const IterableDir = struct { |
| 662 | .NOTDIR => unreachable, | 662 | .NOTDIR => unreachable, |
| 663 | .NOENT => return error.DirNotFound, // The directory being iterated was deleted during iteration. | 663 | .NOENT => return error.DirNotFound, // The directory being iterated was deleted during iteration. |
| 664 | .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net. | 664 | .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net. |
| | 665 | .ACCES => return error.AccessDenied, // Do not have permission to iterate this directory. |
| 665 | else => |err| return os.unexpectedErrno(err), | 666 | else => |err| return os.unexpectedErrno(err), |
| 666 | } | 667 | } |
| 667 | if (rc == 0) return null; | 668 | if (rc == 0) return null; |
| ... | @@ -957,7 +958,17 @@ pub const IterableDir = struct { | ... | @@ -957,7 +958,17 @@ pub const IterableDir = struct { |
| 957 | var top = &self.stack.items[self.stack.items.len - 1]; | 958 | var top = &self.stack.items[self.stack.items.len - 1]; |
| 958 | var containing = top; | 959 | var containing = top; |
| 959 | var dirname_len = top.dirname_len; | 960 | var dirname_len = top.dirname_len; |
| 960 | if (try top.iter.next()) |base| { | 961 | if (top.iter.next() catch |err| { |
| | 962 | // If we get an error, then we want the user to be able to continue |
| | 963 | // walking if they want, which means that we need to pop the directory |
| | 964 | // that errored from the stack. Otherwise, all future `next` calls would |
| | 965 | // likely just fail with the same error. |
| | 966 | var item = self.stack.pop(); |
| | 967 | if (self.stack.items.len != 0) { |
| | 968 | item.iter.dir.close(); |
| | 969 | } |
| | 970 | return err; |
| | 971 | }) |base| { |
| 961 | self.name_buffer.shrinkRetainingCapacity(dirname_len); | 972 | self.name_buffer.shrinkRetainingCapacity(dirname_len); |
| 962 | if (self.name_buffer.items.len != 0) { | 973 | if (self.name_buffer.items.len != 0) { |
| 963 | try self.name_buffer.append(path.sep); | 974 | try self.name_buffer.append(path.sep); |
| ... | @@ -972,7 +983,7 @@ pub const IterableDir = struct { | ... | @@ -972,7 +983,7 @@ pub const IterableDir = struct { |
| 972 | { | 983 | { |
| 973 | errdefer new_dir.close(); | 984 | errdefer new_dir.close(); |
| 974 | try self.stack.append(StackItem{ | 985 | try self.stack.append(StackItem{ |
| 975 | .iter = new_dir.iterate(), | 986 | .iter = new_dir.iterateAssumeFirstIteration(), |
| 976 | .dirname_len = self.name_buffer.items.len, | 987 | .dirname_len = self.name_buffer.items.len, |
| 977 | }); | 988 | }); |
| 978 | top = &self.stack.items[self.stack.items.len - 1]; | 989 | top = &self.stack.items[self.stack.items.len - 1]; |