| ... | ... | @@ -37,6 +37,8 @@ pub const MAX_PATH_BYTES = switch (builtin.os) { |
| 37 | 37 | else => @compileError("Unsupported OS"), |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | pub const MAX_BUF_BYTES: usize = 8192; |
| 41 | |
| 40 | 42 | // here we replace the standard +/ with -_ so that it can be used in a file name |
| 41 | 43 | const b64_fs_encoder = base64.Base64Encoder.init("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", base64.standard_pad_char); |
| 42 | 44 | |
| ... | ... | @@ -371,7 +373,7 @@ const DeleteTreeError = error{ |
| 371 | 373 | /// this function recursively removes its entries and then tries again. |
| 372 | 374 | /// TODO determine if we can remove the allocator requirement |
| 373 | 375 | /// https://github.com/ziglang/zig/issues/2886 |
| 374 | | pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError!void { |
| 376 | pub fn deleteTree(full_path: []const u8) DeleteTreeError!void { |
| 375 | 377 | start_over: while (true) { |
| 376 | 378 | var got_access_denied = false; |
| 377 | 379 | // First, try deleting the item as a file. This way we don't follow sym links. |
| ... | ... | @@ -395,7 +397,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError! |
| 395 | 397 | => return err, |
| 396 | 398 | } |
| 397 | 399 | { |
| 398 | | var dir = Dir.open(allocator, full_path) catch |err| switch (err) { |
| 400 | var dir = Dir.open(full_path) catch |err| switch (err) { |
| 399 | 401 | error.NotDir => { |
| 400 | 402 | if (got_access_denied) { |
| 401 | 403 | return error.AccessDenied; |
| ... | ... | @@ -424,17 +426,14 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError! |
| 424 | 426 | }; |
| 425 | 427 | defer dir.close(); |
| 426 | 428 | |
| 427 | | var full_entry_buf = std.ArrayList(u8).init(allocator); |
| 428 | | defer full_entry_buf.deinit(); |
| 429 | | |
| 430 | 429 | while (try dir.next()) |entry| { |
| 431 | | try full_entry_buf.resize(full_path.len + entry.name.len + 1); |
| 432 | | const full_entry_path = full_entry_buf.toSlice(); |
| 430 | var full_entry_buf: [MAX_BUF_BYTES]u8 = undefined; |
| 431 | const full_entry_path = full_entry_buf[0..]; |
| 433 | 432 | mem.copy(u8, full_entry_path, full_path); |
| 434 | 433 | full_entry_path[full_path.len] = path.sep; |
| 435 | 434 | mem.copy(u8, full_entry_path[full_path.len + 1 ..], entry.name); |
| 436 | 435 | |
| 437 | | try deleteTree(allocator, full_entry_path); |
| 436 | try deleteTree(full_entry_path[0..full_path.len + entry.name.len + 1]); |
| 438 | 437 | } |
| 439 | 438 | } |
| 440 | 439 | return deleteDir(full_path); |
| ... | ... | @@ -445,19 +444,18 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError! |
| 445 | 444 | /// files, and into the one that reads files from an open directory handle. |
| 446 | 445 | pub const Dir = struct { |
| 447 | 446 | handle: Handle, |
| 448 | | allocator: *Allocator, |
| 449 | 447 | |
| 450 | 448 | pub const Handle = switch (builtin.os) { |
| 451 | 449 | .macosx, .ios, .freebsd, .netbsd => struct { |
| 452 | 450 | fd: i32, |
| 453 | 451 | seek: i64, |
| 454 | | buf: []u8, |
| 452 | buf: [MAX_BUF_BYTES]u8, |
| 455 | 453 | index: usize, |
| 456 | 454 | end_index: usize, |
| 457 | 455 | }, |
| 458 | 456 | .linux => struct { |
| 459 | 457 | fd: i32, |
| 460 | | buf: []u8, |
| 458 | buf: [MAX_BUF_BYTES]u8, |
| 461 | 459 | index: usize, |
| 462 | 460 | end_index: usize, |
| 463 | 461 | }, |
| ... | ... | @@ -512,9 +510,8 @@ pub const Dir = struct { |
| 512 | 510 | /// Call close when done. |
| 513 | 511 | /// TODO remove the allocator requirement from this API |
| 514 | 512 | /// https://github.com/ziglang/zig/issues/2885 |
| 515 | | pub fn open(allocator: *Allocator, dir_path: []const u8) OpenError!Dir { |
| 513 | pub fn open(dir_path: []const u8) OpenError!Dir { |
| 516 | 514 | return Dir{ |
| 517 | | .allocator = allocator, |
| 518 | 515 | .handle = switch (builtin.os) { |
| 519 | 516 | .windows => blk: { |
| 520 | 517 | var find_file_data: os.windows.WIN32_FIND_DATAW = undefined; |
| ... | ... | @@ -548,7 +545,6 @@ pub const Dir = struct { |
| 548 | 545 | if (os.windows.is_the_target) { |
| 549 | 546 | return os.windows.FindClose(self.handle.handle); |
| 550 | 547 | } |
| 551 | | self.allocator.free(self.handle.buf); |
| 552 | 548 | os.close(self.handle.fd); |
| 553 | 549 | } |
| 554 | 550 | |
| ... | ... | @@ -579,14 +575,10 @@ pub const Dir = struct { |
| 579 | 575 | fn nextDarwin(self: *Dir) !?Entry { |
| 580 | 576 | start_over: while (true) { |
| 581 | 577 | if (self.handle.index >= self.handle.end_index) { |
| 582 | | if (self.handle.buf.len == 0) { |
| 583 | | self.handle.buf = try self.allocator.alloc(u8, mem.page_size); |
| 584 | | } |
| 585 | | |
| 586 | 578 | while (true) { |
| 587 | 579 | const rc = os.system.__getdirentries64( |
| 588 | 580 | self.handle.fd, |
| 589 | | self.handle.buf.ptr, |
| 581 | self.handle.buf[0..].ptr, |
| 590 | 582 | self.handle.buf.len, |
| 591 | 583 | &self.handle.seek, |
| 592 | 584 | ); |
| ... | ... | @@ -596,10 +588,7 @@ pub const Dir = struct { |
| 596 | 588 | os.EBADF => unreachable, |
| 597 | 589 | os.EFAULT => unreachable, |
| 598 | 590 | os.ENOTDIR => unreachable, |
| 599 | | os.EINVAL => { |
| 600 | | self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); |
| 601 | | continue; |
| 602 | | }, |
| 591 | os.EINVAL => unreachable, |
| 603 | 592 | else => |err| return os.unexpectedErrno(err), |
| 604 | 593 | } |
| 605 | 594 | } |
| ... | ... | @@ -666,21 +655,14 @@ pub const Dir = struct { |
| 666 | 655 | fn nextLinux(self: *Dir) !?Entry { |
| 667 | 656 | start_over: while (true) { |
| 668 | 657 | if (self.handle.index >= self.handle.end_index) { |
| 669 | | if (self.handle.buf.len == 0) { |
| 670 | | self.handle.buf = try self.allocator.alloc(u8, mem.page_size); |
| 671 | | } |
| 672 | | |
| 673 | 658 | while (true) { |
| 674 | | const rc = os.linux.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len); |
| 659 | const rc = os.linux.getdents64(self.handle.fd, self.handle.buf[0..].ptr, self.handle.buf.len); |
| 675 | 660 | switch (os.linux.getErrno(rc)) { |
| 676 | 661 | 0 => {}, |
| 677 | 662 | os.EBADF => unreachable, |
| 678 | 663 | os.EFAULT => unreachable, |
| 679 | 664 | os.ENOTDIR => unreachable, |
| 680 | | os.EINVAL => { |
| 681 | | self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); |
| 682 | | continue; |
| 683 | | }, |
| 665 | os.EINVAL => unreachable, |
| 684 | 666 | else => |err| return os.unexpectedErrno(err), |
| 685 | 667 | } |
| 686 | 668 | if (rc == 0) return null; |
| ... | ... | @@ -720,14 +702,10 @@ pub const Dir = struct { |
| 720 | 702 | fn nextBsd(self: *Dir) !?Entry { |
| 721 | 703 | start_over: while (true) { |
| 722 | 704 | if (self.handle.index >= self.handle.end_index) { |
| 723 | | if (self.handle.buf.len == 0) { |
| 724 | | self.handle.buf = try self.allocator.alloc(u8, mem.page_size); |
| 725 | | } |
| 726 | | |
| 727 | 705 | while (true) { |
| 728 | 706 | const rc = os.system.getdirentries( |
| 729 | 707 | self.handle.fd, |
| 730 | | self.handle.buf.ptr, |
| 708 | self.handle.buf[0..].ptr, |
| 731 | 709 | self.handle.buf.len, |
| 732 | 710 | &self.handle.seek, |
| 733 | 711 | ); |
| ... | ... | @@ -736,10 +714,7 @@ pub const Dir = struct { |
| 736 | 714 | os.EBADF => unreachable, |
| 737 | 715 | os.EFAULT => unreachable, |
| 738 | 716 | os.ENOTDIR => unreachable, |
| 739 | | os.EINVAL => { |
| 740 | | self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); |
| 741 | | continue; |
| 742 | | }, |
| 717 | os.EINVAL => unreachable, |
| 743 | 718 | else => |err| return os.unexpectedErrno(err), |
| 744 | 719 | } |
| 745 | 720 | if (rc == 0) return null; |
| ... | ... | @@ -807,7 +782,7 @@ pub const Walker = struct { |
| 807 | 782 | try self.name_buffer.append(base.name); |
| 808 | 783 | if (base.kind == .Directory) { |
| 809 | 784 | // TODO https://github.com/ziglang/zig/issues/2888 |
| 810 | | var new_dir = try Dir.open(self.stack.allocator, self.name_buffer.toSliceConst()); |
| 785 | var new_dir = try Dir.open(self.name_buffer.toSliceConst()); |
| 811 | 786 | { |
| 812 | 787 | errdefer new_dir.close(); |
| 813 | 788 | try self.stack.append(StackItem{ |
| ... | ... | @@ -841,7 +816,7 @@ pub const Walker = struct { |
| 841 | 816 | pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker { |
| 842 | 817 | assert(!mem.endsWith(u8, dir_path, path.sep_str)); |
| 843 | 818 | |
| 844 | | var dir_it = try Dir.open(allocator, dir_path); |
| 819 | var dir_it = try Dir.open(dir_path); |
| 845 | 820 | errdefer dir_it.close(); |
| 846 | 821 | |
| 847 | 822 | var name_buffer = try std.Buffer.init(allocator, dir_path); |