| ... | @@ -302,6 +302,7 @@ pub const Dir = struct { | ... | @@ -302,6 +302,7 @@ pub const Dir = struct { |
| 302 | buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)), | 302 | buf: [8192]u8, // TODO align(@alignOf(os.system.dirent)), |
| 303 | index: usize, | 303 | index: usize, |
| 304 | end_index: usize, | 304 | end_index: usize, |
| | 305 | first_iter: bool, |
| 305 | | 306 | |
| 306 | const Self = @This(); | 307 | const Self = @This(); |
| 307 | | 308 | |
| ... | @@ -321,6 +322,10 @@ pub const Dir = struct { | ... | @@ -321,6 +322,10 @@ pub const Dir = struct { |
| 321 | fn nextDarwin(self: *Self) !?Entry { | 322 | fn nextDarwin(self: *Self) !?Entry { |
| 322 | start_over: while (true) { | 323 | start_over: while (true) { |
| 323 | if (self.index >= self.end_index) { | 324 | if (self.index >= self.end_index) { |
| | 325 | if (self.first_iter) { |
| | 326 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 327 | self.first_iter = false; |
| | 328 | } |
| 324 | const rc = os.system.__getdirentries64( | 329 | const rc = os.system.__getdirentries64( |
| 325 | self.dir.fd, | 330 | self.dir.fd, |
| 326 | &self.buf, | 331 | &self.buf, |
| ... | @@ -371,6 +376,10 @@ pub const Dir = struct { | ... | @@ -371,6 +376,10 @@ pub const Dir = struct { |
| 371 | fn nextSolaris(self: *Self) !?Entry { | 376 | fn nextSolaris(self: *Self) !?Entry { |
| 372 | start_over: while (true) { | 377 | start_over: while (true) { |
| 373 | if (self.index >= self.end_index) { | 378 | if (self.index >= self.end_index) { |
| | 379 | if (self.first_iter) { |
| | 380 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 381 | self.first_iter = false; |
| | 382 | } |
| 374 | const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len); | 383 | const rc = os.system.getdents(self.dir.fd, &self.buf, self.buf.len); |
| 375 | switch (os.errno(rc)) { | 384 | switch (os.errno(rc)) { |
| 376 | .SUCCESS => {}, | 385 | .SUCCESS => {}, |
| ... | @@ -425,6 +434,10 @@ pub const Dir = struct { | ... | @@ -425,6 +434,10 @@ pub const Dir = struct { |
| 425 | fn nextBsd(self: *Self) !?Entry { | 434 | fn nextBsd(self: *Self) !?Entry { |
| 426 | start_over: while (true) { | 435 | start_over: while (true) { |
| 427 | if (self.index >= self.end_index) { | 436 | if (self.index >= self.end_index) { |
| | 437 | if (self.first_iter) { |
| | 438 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 439 | self.first_iter = false; |
| | 440 | } |
| 428 | const rc = if (builtin.os.tag == .netbsd) | 441 | const rc = if (builtin.os.tag == .netbsd) |
| 429 | os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len) | 442 | os.system.__getdents30(self.dir.fd, &self.buf, self.buf.len) |
| 430 | else | 443 | else |
| ... | @@ -481,6 +494,7 @@ pub const Dir = struct { | ... | @@ -481,6 +494,7 @@ pub const Dir = struct { |
| 481 | buf: [8192]u8, // TODO align(@alignOf(os.dirent64)), | 494 | buf: [8192]u8, // TODO align(@alignOf(os.dirent64)), |
| 482 | index: usize, | 495 | index: usize, |
| 483 | end_index: usize, | 496 | end_index: usize, |
| | 497 | first_iter: bool, |
| 484 | | 498 | |
| 485 | const Self = @This(); | 499 | const Self = @This(); |
| 486 | | 500 | |
| ... | @@ -493,6 +507,10 @@ pub const Dir = struct { | ... | @@ -493,6 +507,10 @@ pub const Dir = struct { |
| 493 | // TODO: find a better max | 507 | // TODO: find a better max |
| 494 | const HAIKU_MAX_COUNT = 10000; | 508 | const HAIKU_MAX_COUNT = 10000; |
| 495 | if (self.index >= self.end_index) { | 509 | if (self.index >= self.end_index) { |
| | 510 | if (self.first_iter) { |
| | 511 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 512 | self.first_iter = false; |
| | 513 | } |
| 496 | const rc = os.system._kern_read_dir( | 514 | const rc = os.system._kern_read_dir( |
| 497 | self.dir.fd, | 515 | self.dir.fd, |
| 498 | &self.buf, | 516 | &self.buf, |
| ... | @@ -565,6 +583,7 @@ pub const Dir = struct { | ... | @@ -565,6 +583,7 @@ pub const Dir = struct { |
| 565 | buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)), | 583 | buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(linux.dirent64)), |
| 566 | index: usize, | 584 | index: usize, |
| 567 | end_index: usize, | 585 | end_index: usize, |
| | 586 | first_iter: bool, |
| 568 | | 587 | |
| 569 | const Self = @This(); | 588 | const Self = @This(); |
| 570 | const linux = os.linux; | 589 | const linux = os.linux; |
| ... | @@ -576,6 +595,10 @@ pub const Dir = struct { | ... | @@ -576,6 +595,10 @@ pub const Dir = struct { |
| 576 | pub fn next(self: *Self) Error!?Entry { | 595 | pub fn next(self: *Self) Error!?Entry { |
| 577 | start_over: while (true) { | 596 | start_over: while (true) { |
| 578 | if (self.index >= self.end_index) { | 597 | if (self.index >= self.end_index) { |
| | 598 | if (self.first_iter) { |
| | 599 | std.os.lseek_SET(self.dir.fd, 0) catch unreachable; // EBADF here likely means that the Dir was not opened with iteration permissions |
| | 600 | self.first_iter = false; |
| | 601 | } |
| 579 | const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len); | 602 | const rc = linux.getdents64(self.dir.fd, &self.buf, self.buf.len); |
| 580 | switch (linux.getErrno(rc)) { | 603 | switch (linux.getErrno(rc)) { |
| 581 | .SUCCESS => {}, | 604 | .SUCCESS => {}, |
| ... | @@ -622,7 +645,7 @@ pub const Dir = struct { | ... | @@ -622,7 +645,7 @@ pub const Dir = struct { |
| 622 | buf: [8192]u8 align(@alignOf(os.windows.FILE_BOTH_DIR_INFORMATION)), | 645 | buf: [8192]u8 align(@alignOf(os.windows.FILE_BOTH_DIR_INFORMATION)), |
| 623 | index: usize, | 646 | index: usize, |
| 624 | end_index: usize, | 647 | end_index: usize, |
| 625 | first: bool, | 648 | first_iter: bool, |
| 626 | name_data: [256]u8, | 649 | name_data: [256]u8, |
| 627 | | 650 | |
| 628 | const Self = @This(); | 651 | const Self = @This(); |
| ... | @@ -647,9 +670,9 @@ pub const Dir = struct { | ... | @@ -647,9 +670,9 @@ pub const Dir = struct { |
| 647 | .FileBothDirectoryInformation, | 670 | .FileBothDirectoryInformation, |
| 648 | w.FALSE, | 671 | w.FALSE, |
| 649 | null, | 672 | null, |
| 650 | if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE), | 673 | if (self.first_iter) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE), |
| 651 | ); | 674 | ); |
| 652 | self.first = false; | 675 | self.first_iter = false; |
| 653 | if (io.Information == 0) return null; | 676 | if (io.Information == 0) return null; |
| 654 | self.index = 0; | 677 | self.index = 0; |
| 655 | self.end_index = io.Information; | 678 | self.end_index = io.Information; |
| ... | @@ -771,18 +794,20 @@ pub const Dir = struct { | ... | @@ -771,18 +794,20 @@ pub const Dir = struct { |
| 771 | .index = 0, | 794 | .index = 0, |
| 772 | .end_index = 0, | 795 | .end_index = 0, |
| 773 | .buf = undefined, | 796 | .buf = undefined, |
| | 797 | .first_iter = true, |
| 774 | }, | 798 | }, |
| 775 | .linux, .haiku => return Iterator{ | 799 | .linux, .haiku => return Iterator{ |
| 776 | .dir = self, | 800 | .dir = self, |
| 777 | .index = 0, | 801 | .index = 0, |
| 778 | .end_index = 0, | 802 | .end_index = 0, |
| 779 | .buf = undefined, | 803 | .buf = undefined, |
| | 804 | .first_iter = true, |
| 780 | }, | 805 | }, |
| 781 | .windows => return Iterator{ | 806 | .windows => return Iterator{ |
| 782 | .dir = self, | 807 | .dir = self, |
| 783 | .index = 0, | 808 | .index = 0, |
| 784 | .end_index = 0, | 809 | .end_index = 0, |
| 785 | .first = true, | 810 | .first_iter = true, |
| 786 | .buf = undefined, | 811 | .buf = undefined, |
| 787 | .name_data = undefined, | 812 | .name_data = undefined, |
| 788 | }, | 813 | }, |