| author | |
| committer | |
| log | af835111fa1397578392a4774454ac0d71eca77d |
| tree | b089216012a03836c96facdb94c26a52815ed2e0 |
| parent | 7555085e6304419c25bb870567eb265bb22d0337 |
Before this commit, if Walker.next errored with e.g. `error.AccessDenied` and the caller did something like `while (true) { walker.next() catch continue; }`, then the directory that errored with AccessDenied would be continually iterated in each `next` call and error every time with AccessDenied.
After this commit, the directory that errored will be popped off the stack before the error is returned, meaning that in the subsequent `next` call, it won't be retried and the Walker will continue with whatever directories remain on its stack.
For a real example, before this commit, walking `/proc/` on my system would infinitely loop due to repeated AccessDenied errors on the same directory. After this commit, I am able to walk `/proc/` on my system fully (skipping over any directories that are unable to be iterated).1 files changed, 11 insertions(+), 1 deletions(-)
lib/std/fs.zig+11-1| ... | ... | @@ -958,7 +958,17 @@ pub const IterableDir = struct { |
| 958 | 958 | var top = &self.stack.items[self.stack.items.len - 1]; |
| 959 | 959 | var containing = top; |
| 960 | 960 | var dirname_len = top.dirname_len; |
| 961 | 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| { | |
| 962 | 972 | self.name_buffer.shrinkRetainingCapacity(dirname_len); |
| 963 | 973 | if (self.name_buffer.items.len != 0) { |
| 964 | 974 | try self.name_buffer.append(path.sep); |