| ... | @@ -300,6 +300,7 @@ pub const Dir = struct { | ... | @@ -300,6 +300,7 @@ pub const Dir = struct { |
| 300 | buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)), | 300 | buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)), |
| 301 | index: usize, | 301 | index: usize, |
| 302 | end_index: usize, | 302 | end_index: usize, |
| | 303 | first_iter: bool, |
| 303 | | 304 | |
| 304 | const Self = @This(); | 305 | const Self = @This(); |
| 305 | | 306 | |
| ... | @@ -319,6 +320,10 @@ pub const Dir = struct { | ... | @@ -319,6 +320,10 @@ pub const Dir = struct { |
| 319 | fn nextDarwin(self: *Self) !?Entry { | 320 | fn nextDarwin(self: *Self) !?Entry { |
| 320 | start_over: while (true) { | 321 | start_over: while (true) { |
| 321 | if (self.index >= self.end_index) { | 322 | if (self.index >= self.end_index) { |
| | 323 | if (self.first_iter) { |
| | 324 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 325 | self.first_iter = false; |
| | 326 | } |
| 322 | const rc = os.system.__getdirentries64( | 327 | const rc = os.system.__getdirentries64( |
| 323 | self.dir.fd, | 328 | self.dir.fd, |
| 324 | &self.buf, | 329 | &self.buf, |
| ... | @@ -369,6 +374,10 @@ pub const Dir = struct { | ... | @@ -369,6 +374,10 @@ pub const Dir = struct { |
| 369 | fn nextSolaris(self: *Self) !?Entry { | 374 | fn nextSolaris(self: *Self) !?Entry { |
| 370 | start_over: while (true) { | 375 | start_over: while (true) { |
| 371 | if (self.index >= self.end_index) { | 376 | if (self.index >= self.end_index) { |
| | 377 | if (self.first_iter) { |
| | 378 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 379 | self.first_iter = false; |
| | 380 | } |
| 372 | const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len); | 381 | const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len); |
| 373 | switch (os.errno(rc)) { | 382 | switch (os.errno(rc)) { |
| 374 | .SUCCESS => {}, | 383 | .SUCCESS => {}, |
| ... | @@ -423,6 +432,10 @@ pub const Dir = struct { | ... | @@ -423,6 +432,10 @@ pub const Dir = struct { |
| 423 | fn nextBsd(self: *Self) !?Entry { | 432 | fn nextBsd(self: *Self) !?Entry { |
| 424 | start_over: while (true) { | 433 | start_over: while (true) { |
| 425 | if (self.index >= self.end_index) { | 434 | if (self.index >= self.end_index) { |
| | 435 | if (self.first_iter) { |
| | 436 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 437 | self.first_iter = false; |
| | 438 | } |
| 426 | const rc = if (builtin.os.tag == .netbsd) | 439 | const rc = if (builtin.os.tag == .netbsd) |
| 427 | os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len) | 440 | os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len) |
| 428 | else | 441 | else |
| ... | @@ -479,6 +492,7 @@ pub const Dir = struct { | ... | @@ -479,6 +492,7 @@ pub const Dir = struct { |
| 479 | buf: [8192]u8, // TODO align(@alignOf(os.dirent64)), | 492 | buf: [8192]u8, // TODO align(@alignOf(os.dirent64)), |
| 480 | index: usize, | 493 | index: usize, |
| 481 | end_index: usize, | 494 | end_index: usize, |
| | 495 | first_iter: bool, |
| 482 | | 496 | |
| 483 | const Self = @This(); | 497 | const Self = @This(); |
| 484 | | 498 | |
| ... | @@ -491,6 +505,10 @@ pub const Dir = struct { | ... | @@ -491,6 +505,10 @@ pub const Dir = struct { |
| 491 | // TODO: find a better max | 505 | // TODO: find a better max |
| 492 | const HAIKU_MAX_COUNT = 10000; | 506 | const HAIKU_MAX_COUNT = 10000; |
| 493 | if (self.index >= self.end_index) { | 507 | if (self.index >= self.end_index) { |
| | 508 | if (self.first_iter) { |
| | 509 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 510 | self.first_iter = false; |
| | 511 | } |
| 494 | const rc = os.system._kern_read_dir( | 512 | const rc = os.system._kern_read_dir( |
| 495 | self.dir.fd, | 513 | self.dir.fd, |
| 496 | &self.buf, | 514 | &self.buf, |
| ... | @@ -563,6 +581,7 @@ pub const Dir = struct { | ... | @@ -563,6 +581,7 @@ pub const Dir = struct { |
| 563 | buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)), | 581 | buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)), |
| 564 | index: usize, | 582 | index: usize, |
| 565 | end_index: usize, | 583 | end_index: usize, |
| | 584 | first_iter: bool, |
| 566 | | 585 | |
| 567 | const Self = @This(); | 586 | const Self = @This(); |
| 568 | const linux = os.linux; | 587 | const linux = os.linux; |
| ... | @@ -574,6 +593,10 @@ pub const Dir = struct { | ... | @@ -574,6 +593,10 @@ pub const Dir = struct { |
| 574 | pub fn next(self: *Self) Error!?Entry { | 593 | pub fn next(self: *Self) Error!?Entry { |
| 575 | start_over: while (true) { | 594 | start_over: while (true) { |
| 576 | if (self.index >= self.end_index) { | 595 | if (self.index >= self.end_index) { |
| | 596 | if (self.first_iter) { |
| | 597 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 598 | self.first_iter = false; |
| | 599 | } |
| 577 | const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len); | 600 | const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len); |
| 578 | switch (linux.getErrno(rc)) { | 601 | switch (linux.getErrno(rc)) { |
| 579 | .SUCCESS => {}, | 602 | .SUCCESS => {}, |
| ... | @@ -620,7 +643,7 @@ pub const Dir = struct { | ... | @@ -620,7 +643,7 @@ pub const Dir = struct { |
| 620 | buf: [8192]u8 align(@alignOf(os.windows.FILE_BOTH_DIR_INFORMATION)), | 643 | buf: [8192]u8 align(@alignOf(os.windows.FILE_BOTH_DIR_INFORMATION)), |
| 621 | index: usize, | 644 | index: usize, |
| 622 | end_index: usize, | 645 | end_index: usize, |
| 623 | first: bool, | 646 | first_iter: bool, |
| 624 | name_data: [256]u8, | 647 | name_data: [256]u8, |
| 625 | | 648 | |
| 626 | const Self = @This(); | 649 | const Self = @This(); |
| ... | @@ -645,9 +668,9 @@ pub const Dir = struct { | ... | @@ -645,9 +668,9 @@ pub const Dir = struct { |
| 645 | .FileBothDirectoryInformation, | 668 | .FileBothDirectoryInformation, |
| 646 | w.FALSE, | 669 | w.FALSE, |
| 647 | null, | 670 | null, |
| 648 | if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE), | 671 | if (self.first_iter) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE), |
| 649 | ); | 672 | ); |
| 650 | self.first = false; | 673 | self.first_iter = false; |
| 651 | if (io.Information == 0) return null; | 674 | if (io.Information == 0) return null; |
| 652 | self.index = 0; | 675 | self.index = 0; |
| 653 | self.end_index = io.Information; | 676 | self.end_index = io.Information; |
| ... | @@ -769,18 +792,20 @@ pub const Dir = struct { | ... | @@ -769,18 +792,20 @@ pub const Dir = struct { |
| 769 | .index = 0, | 792 | .index = 0, |
| 770 | .end_index = 0, | 793 | .end_index = 0, |
| 771 | .buf = undefined, | 794 | .buf = undefined, |
| | 795 | .first_iter = true, |
| 772 | }, | 796 | }, |
| 773 | .linux, .haiku => return Iterator{ | 797 | .linux, .haiku => return Iterator{ |
| 774 | .dir = self, | 798 | .dir = self, |
| 775 | .index = 0, | 799 | .index = 0, |
| 776 | .end_index = 0, | 800 | .end_index = 0, |
| 777 | .buf = undefined, | 801 | .buf = undefined, |
| | 802 | .first_iter = true, |
| 778 | }, | 803 | }, |
| 779 | .windows => return Iterator{ | 804 | .windows => return Iterator{ |
| 780 | .dir = self, | 805 | .dir = self, |
| 781 | .index = 0, | 806 | .index = 0, |
| 782 | .end_index = 0, | 807 | .end_index = 0, |
| 783 | .first = true, | 808 | .first_iter = true, |
| 784 | .buf = undefined, | 809 | .buf = undefined, |
| 785 | .name_data = undefined, | 810 | .name_data = undefined, |
| 786 | }, | 811 | }, |