| author | |
| committer | |
| log | b9e3df92db1b5cb137d880a7612b6ee2e7e1f60e |
| tree | 19cf169ef5797b19337ec1ba578097f6c2d01a08 |
| parent | bd17a373cc20c919be9fa279a4420033e959ca92 |
| parent | f7bcc8e04087e2308582d8b6f068e2e71b65bef9 |
closes #5617
closes #56163 files changed, 45 insertions(+), 10 deletions(-)
lib/std/fs.zig+2-7| ... | @@ -1229,14 +1229,9 @@ pub const Dir = struct { | ... | @@ -1229,14 +1229,9 @@ pub const Dir = struct { |
| 1229 | var file = try self.openFile(file_path, .{}); | 1229 | var file = try self.openFile(file_path, .{}); |
| 1230 | defer file.close(); | 1230 | defer file.close(); |
| 1231 | 1231 | ||
| 1232 | const size = math.cast(usize, try file.getEndPos()) catch math.maxInt(usize); | 1232 | const stat_size = try file.getEndPos(); |
| 1233 | if (size > max_bytes) return error.FileTooBig; | ||
| 1234 | 1233 | ||
| 1235 | const buf = try allocator.allocWithOptions(u8, size, alignment, optional_sentinel); | 1234 | return file.readAllAllocOptions(allocator, stat_size, max_bytes, alignment, optional_sentinel); |
| 1236 | errdefer allocator.free(buf); | ||
| 1237 | |||
| 1238 | try file.inStream().readNoEof(buf); | ||
| 1239 | return buf; | ||
| 1240 | } | 1235 | } |
| 1241 | 1236 | ||
| 1242 | pub const DeleteTreeError = error{ | 1237 | pub const DeleteTreeError = error{ |
lib/std/fs/file.zig+28-1| ... | @@ -209,7 +209,7 @@ pub const File = struct { | ... | @@ -209,7 +209,7 @@ pub const File = struct { |
| 209 | /// TODO: integrate with async I/O | 209 | /// TODO: integrate with async I/O |
| 210 | pub fn mode(self: File) ModeError!Mode { | 210 | pub fn mode(self: File) ModeError!Mode { |
| 211 | if (builtin.os.tag == .windows) { | 211 | if (builtin.os.tag == .windows) { |
| 212 | return {}; | 212 | return 0; |
| 213 | } | 213 | } |
| 214 | return (try self.stat()).mode; | 214 | return (try self.stat()).mode; |
| 215 | } | 215 | } |
| ... | @@ -306,6 +306,33 @@ pub const File = struct { | ... | @@ -306,6 +306,33 @@ pub const File = struct { |
| 306 | try os.futimens(self.handle, &times); | 306 | try os.futimens(self.handle, &times); |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | /// On success, caller owns returned buffer. | ||
| 310 | /// If the file is larger than `max_bytes`, returns `error.FileTooBig`. | ||
| 311 | pub fn readAllAlloc(self: File, allocator: *mem.Allocator, stat_size: u64, max_bytes: usize) ![]u8 { | ||
| 312 | return self.readAllAllocOptions(allocator, stat_size, max_bytes, @alignOf(u8), null); | ||
| 313 | } | ||
| 314 | |||
| 315 | /// On success, caller owns returned buffer. | ||
| 316 | /// If the file is larger than `max_bytes`, returns `error.FileTooBig`. | ||
| 317 | /// Allows specifying alignment and a sentinel value. | ||
| 318 | pub fn readAllAllocOptions( | ||
| 319 | self: File, | ||
| 320 | allocator: *mem.Allocator, | ||
| 321 | stat_size: u64, | ||
| 322 | max_bytes: usize, | ||
| 323 | comptime alignment: u29, | ||
| 324 | comptime optional_sentinel: ?u8, | ||
| 325 | ) !(if (optional_sentinel) |s| [:s]align(alignment) u8 else []align(alignment) u8) { | ||
| 326 | const size = math.cast(usize, stat_size) catch math.maxInt(usize); | ||
| 327 | if (size > max_bytes) return error.FileTooBig; | ||
| 328 | |||
| 329 | const buf = try allocator.allocWithOptions(u8, size, alignment, optional_sentinel); | ||
| 330 | errdefer allocator.free(buf); | ||
| 331 | |||
| 332 | try self.inStream().readNoEof(buf); | ||
| 333 | return buf; | ||
| 334 | } | ||
| 335 | |||
| 309 | pub const ReadError = os.ReadError; | 336 | pub const ReadError = os.ReadError; |
| 310 | pub const PReadError = os.PReadError; | 337 | pub const PReadError = os.PReadError; |
| 311 | 338 |
src-self-hosted/main.zig+15-2| ... | @@ -684,7 +684,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | ... | @@ -684,7 +684,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 684 | if (fmt.seen.exists(real_path)) return; | 684 | if (fmt.seen.exists(real_path)) return; |
| 685 | try fmt.seen.put(real_path); | 685 | try fmt.seen.put(real_path); |
| 686 | 686 | ||
| 687 | const source_code = fs.cwd().readFileAlloc(fmt.gpa, real_path, max_src_size) catch |err| switch (err) { | 687 | const source_file = fs.cwd().openFile(real_path, .{}) catch |err| switch (err) { |
| 688 | error.IsDir, error.AccessDenied => { | 688 | error.IsDir, error.AccessDenied => { |
| 689 | var dir = try fs.cwd().openDir(file_path, .{ .iterate = true }); | 689 | var dir = try fs.cwd().openDir(file_path, .{ .iterate = true }); |
| 690 | defer dir.close(); | 690 | defer dir.close(); |
| ... | @@ -705,6 +705,19 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | ... | @@ -705,6 +705,19 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 705 | return; | 705 | return; |
| 706 | }, | 706 | }, |
| 707 | }; | 707 | }; |
| 708 | defer source_file.close(); | ||
| 709 | |||
| 710 | const stat = source_file.stat() catch |err| { | ||
| 711 | std.debug.warn("unable to stat '{}': {}\n", .{ file_path, err }); | ||
| 712 | fmt.any_error = true; | ||
| 713 | return; | ||
| 714 | }; | ||
| 715 | |||
| 716 | const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| { | ||
| 717 | std.debug.warn("unable to read '{}': {}\n", .{ file_path, err }); | ||
| 718 | fmt.any_error = true; | ||
| 719 | return; | ||
| 720 | }; | ||
| 708 | defer fmt.gpa.free(source_code); | 721 | defer fmt.gpa.free(source_code); |
| 709 | 722 | ||
| 710 | const tree = std.zig.parse(fmt.gpa, source_code) catch |err| { | 723 | const tree = std.zig.parse(fmt.gpa, source_code) catch |err| { |
| ... | @@ -729,7 +742,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | ... | @@ -729,7 +742,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 729 | fmt.any_error = true; | 742 | fmt.any_error = true; |
| 730 | } | 743 | } |
| 731 | } else { | 744 | } else { |
| 732 | const baf = try io.BufferedAtomicFile.create(fmt.gpa, fs.cwd(), real_path, .{}); | 745 | const baf = try io.BufferedAtomicFile.create(fmt.gpa, fs.cwd(), real_path, .{ .mode = stat.mode }); |
| 733 | defer baf.destroy(); | 746 | defer baf.destroy(); |
| 734 | 747 | ||
| 735 | const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree); | 748 | const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree); |