| ... | ... | @@ -595,6 +595,19 @@ pub const IterableDir = struct { |
| 595 | 595 | /// Memory such as file names referenced in this returned entry becomes invalid |
| 596 | 596 | /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized. |
| 597 | 597 | pub fn next(self: *Self) Error!?Entry { |
| 598 | return self.nextLinux() catch |err| switch (err) { |
| 599 | // To be consistent across platforms, iteration ends if the directory being iterated is deleted during iteration. |
| 600 | // This matches the behavior of non-Linux UNIX platforms. |
| 601 | error.DirNotFound => null, |
| 602 | else => |e| return e, |
| 603 | }; |
| 604 | } |
| 605 | |
| 606 | pub const ErrorLinux = error{DirNotFound} || IteratorError; |
| 607 | |
| 608 | /// Implementation of `next` that can return `error.DirNotFound` if the directory being |
| 609 | /// iterated was deleted during iteration (this error is Linux specific). |
| 610 | pub fn nextLinux(self: *Self) ErrorLinux!?Entry { |
| 598 | 611 | start_over: while (true) { |
| 599 | 612 | if (self.index >= self.end_index) { |
| 600 | 613 | if (self.first_iter) { |
| ... | ... | @@ -607,7 +620,7 @@ pub const IterableDir = struct { |
| 607 | 620 | .BADF => unreachable, // Dir is invalid or was opened without iteration ability |
| 608 | 621 | .FAULT => unreachable, |
| 609 | 622 | .NOTDIR => unreachable, |
| 610 | | .NOENT => return null, // The directory being iterated was deleted during iteration. |
| 623 | .NOENT => return error.DirNotFound, // The directory being iterated was deleted during iteration. |
| 611 | 624 | .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net. |
| 612 | 625 | else => |err| return os.unexpectedErrno(err), |
| 613 | 626 | } |
| ... | ... | @@ -729,6 +742,20 @@ pub const IterableDir = struct { |
| 729 | 742 | /// Memory such as file names referenced in this returned entry becomes invalid |
| 730 | 743 | /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized. |
| 731 | 744 | pub fn next(self: *Self) Error!?Entry { |
| 745 | return self.nextWasi() catch |err| switch (err) { |
| 746 | // To be consistent across platforms, iteration ends if the directory being iterated is deleted during iteration. |
| 747 | // This matches the behavior of non-Linux UNIX platforms. |
| 748 | error.DirNotFound => null, |
| 749 | else => |e| return e, |
| 750 | }; |
| 751 | } |
| 752 | |
| 753 | pub const ErrorWasi = error{DirNotFound} || IteratorError; |
| 754 | |
| 755 | /// Implementation of `next` that can return platform-dependent errors depending on the host platform. |
| 756 | /// When the host platform is Linux, `error.DirNotFound` can be returned if the directory being |
| 757 | /// iterated was deleted during iteration. |
| 758 | pub fn nextWasi(self: *Self) ErrorWasi!?Entry { |
| 732 | 759 | // We intentinally use fd_readdir even when linked with libc, |
| 733 | 760 | // since its implementation is exactly the same as below, |
| 734 | 761 | // and we avoid the code complexity here. |
| ... | ... | @@ -742,7 +769,7 @@ pub const IterableDir = struct { |
| 742 | 769 | .FAULT => unreachable, |
| 743 | 770 | .NOTDIR => unreachable, |
| 744 | 771 | .INVAL => unreachable, |
| 745 | | .NOENT => return null, // The directory being iterated was deleted during iteration. |
| 772 | .NOENT => return error.DirNotFound, // The directory being iterated was deleted during iteration. |
| 746 | 773 | .NOTCAPABLE => return error.AccessDenied, |
| 747 | 774 | else => |err| return os.unexpectedErrno(err), |
| 748 | 775 | } |