| author | |
| committer | |
| log | ffb0e283d7aaaa896cd3db32ca11460ea63c8855 |
| tree | c12b079906590b17d1edd0394b92ee4aa10c4ba7 |
| parent | 3b390e4f139220ed11918524288238c289ce0c6d |
27 files changed, 463 insertions(+), 362 deletions(-)
lib/compiler/build_runner.zig+15-17| ... | ... | @@ -379,9 +379,11 @@ pub fn main() !void { |
| 379 | 379 | validateSystemLibraryOptions(builder); |
| 380 | 380 | |
| 381 | 381 | { |
| 382 | var stdout_bw = std.fs.File.stdout().writer().buffered(&stdio_buffer); | |
| 383 | if (help_menu) return usage(builder, &stdout_bw); | |
| 384 | if (steps_menu) return steps(builder, &stdout_bw); | |
| 382 | var fw = std.fs.File.stdout().writer(); | |
| 383 | var bw = fw.interface().buffered(&stdio_buffer); | |
| 384 | defer bw.flush() catch {}; | |
| 385 | if (help_menu) return usage(builder, &bw); | |
| 386 | if (steps_menu) return steps(builder, &bw); | |
| 385 | 387 | } |
| 386 | 388 | |
| 387 | 389 | var run: Run = .{ |
| ... | ... | @@ -694,16 +696,13 @@ fn runStepNames( |
| 694 | 696 | const ttyconf = run.ttyconf; |
| 695 | 697 | |
| 696 | 698 | if (run.summary != .none) { |
| 697 | var bw = std.debug.lockStdErr2(&stdio_buffer); | |
| 698 | defer { | |
| 699 | bw.flush() catch {}; | |
| 700 | std.debug.unlockStdErr(); | |
| 701 | } | |
| 699 | const bw = std.debug.lockStderrWriter(&stdio_buffer); | |
| 700 | defer std.debug.unlockStderrWriter(); | |
| 702 | 701 | |
| 703 | 702 | const total_count = success_count + failure_count + pending_count + skipped_count; |
| 704 | ttyconf.setColor(&bw, .cyan) catch {}; | |
| 703 | ttyconf.setColor(bw, .cyan) catch {}; | |
| 705 | 704 | bw.writeAll("Build Summary:") catch {}; |
| 706 | ttyconf.setColor(&bw, .reset) catch {}; | |
| 705 | ttyconf.setColor(bw, .reset) catch {}; | |
| 707 | 706 | bw.print(" {d}/{d} steps succeeded", .{ success_count, total_count }) catch {}; |
| 708 | 707 | if (skipped_count > 0) bw.print("; {d} skipped", .{skipped_count}) catch {}; |
| 709 | 708 | if (failure_count > 0) bw.print("; {d} failed", .{failure_count}) catch {}; |
| ... | ... | @@ -713,8 +712,6 @@ fn runStepNames( |
| 713 | 712 | if (test_fail_count > 0) bw.print("; {d} failed", .{test_fail_count}) catch {}; |
| 714 | 713 | if (test_leak_count > 0) bw.print("; {d} leaked", .{test_leak_count}) catch {}; |
| 715 | 714 | |
| 716 | bw.writeByte('\n') catch {}; | |
| 717 | ||
| 718 | 715 | // Print a fancy tree with build results. |
| 719 | 716 | var step_stack_copy = try step_stack.clone(gpa); |
| 720 | 717 | defer step_stack_copy.deinit(gpa); |
| ... | ... | @@ -722,7 +719,7 @@ fn runStepNames( |
| 722 | 719 | var print_node: PrintNode = .{ .parent = null }; |
| 723 | 720 | if (step_names.len == 0) { |
| 724 | 721 | print_node.last = true; |
| 725 | printTreeStep(b, b.default_step, run, &bw, ttyconf, &print_node, &step_stack_copy) catch {}; | |
| 722 | printTreeStep(b, b.default_step, run, bw, ttyconf, &print_node, &step_stack_copy) catch {}; | |
| 726 | 723 | } else { |
| 727 | 724 | const last_index = if (run.summary == .all) b.top_level_steps.count() else blk: { |
| 728 | 725 | var i: usize = step_names.len; |
| ... | ... | @@ -741,9 +738,10 @@ fn runStepNames( |
| 741 | 738 | for (step_names, 0..) |step_name, i| { |
| 742 | 739 | const tls = b.top_level_steps.get(step_name).?; |
| 743 | 740 | print_node.last = i + 1 == last_index; |
| 744 | printTreeStep(b, &tls.step, run, &bw, ttyconf, &print_node, &step_stack_copy) catch {}; | |
| 741 | printTreeStep(b, &tls.step, run, bw, ttyconf, &print_node, &step_stack_copy) catch {}; | |
| 745 | 742 | } |
| 746 | 743 | } |
| 744 | bw.writeByte('\n') catch {}; | |
| 747 | 745 | } |
| 748 | 746 | |
| 749 | 747 | if (failure_count == 0) { |
| ... | ... | @@ -1129,11 +1127,11 @@ fn workerMakeOneStep( |
| 1129 | 1127 | const show_stderr = s.result_stderr.len > 0; |
| 1130 | 1128 | |
| 1131 | 1129 | if (show_error_msgs or show_compile_errors or show_stderr) { |
| 1132 | var bw = std.debug.lockStdErr2(&stdio_buffer); | |
| 1133 | defer std.debug.unlockStdErr(); | |
| 1130 | const bw = std.debug.lockStderrWriter(&stdio_buffer); | |
| 1131 | defer std.debug.unlockStderrWriter(); | |
| 1134 | 1132 | |
| 1135 | 1133 | const gpa = b.allocator; |
| 1136 | printErrorMessages(gpa, s, .{ .ttyconf = run.ttyconf }, &bw, run.prominent_compile_errors) catch {}; | |
| 1134 | printErrorMessages(gpa, s, .{ .ttyconf = run.ttyconf }, bw, run.prominent_compile_errors) catch {}; | |
| 1137 | 1135 | } |
| 1138 | 1136 | |
| 1139 | 1137 | handle_result: { |
lib/std/Build.zig+11-11| ... | ... | @@ -2766,7 +2766,7 @@ fn dumpBadDirnameHelp( |
| 2766 | 2766 | comptime msg: []const u8, |
| 2767 | 2767 | args: anytype, |
| 2768 | 2768 | ) anyerror!void { |
| 2769 | const w = debug.lockStderrWriter(); | |
| 2769 | const w = debug.lockStderrWriter(&.{}); | |
| 2770 | 2770 | defer debug.unlockStderrWriter(); |
| 2771 | 2771 | |
| 2772 | 2772 | const stderr: fs.File = .stderr(); |
| ... | ... | @@ -2802,9 +2802,9 @@ pub fn dumpBadGetPathHelp( |
| 2802 | 2802 | src_builder: *Build, |
| 2803 | 2803 | asking_step: ?*Step, |
| 2804 | 2804 | ) anyerror!void { |
| 2805 | var buffered_writer = stderr.writer().unbuffered(); | |
| 2806 | const w = &buffered_writer; | |
| 2807 | try w.print( | |
| 2805 | var fw = stderr.writer(); | |
| 2806 | var bw = fw.interface().unbuffered(); | |
| 2807 | try bw.print( | |
| 2808 | 2808 | \\getPath() was called on a GeneratedFile that wasn't built yet. |
| 2809 | 2809 | \\ source package path: {s} |
| 2810 | 2810 | \\ Is there a missing Step dependency on step '{s}'? |
| ... | ... | @@ -2815,21 +2815,21 @@ pub fn dumpBadGetPathHelp( |
| 2815 | 2815 | }); |
| 2816 | 2816 | |
| 2817 | 2817 | const tty_config = std.io.tty.detectConfig(stderr); |
| 2818 | tty_config.setColor(w, .red) catch {}; | |
| 2818 | tty_config.setColor(&bw, .red) catch {}; | |
| 2819 | 2819 | try stderr.writeAll(" The step was created by this stack trace:\n"); |
| 2820 | tty_config.setColor(w, .reset) catch {}; | |
| 2820 | tty_config.setColor(&bw, .reset) catch {}; | |
| 2821 | 2821 | |
| 2822 | 2822 | s.dump(stderr); |
| 2823 | 2823 | if (asking_step) |as| { |
| 2824 | tty_config.setColor(w, .red) catch {}; | |
| 2825 | try w.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name}); | |
| 2826 | tty_config.setColor(w, .reset) catch {}; | |
| 2824 | tty_config.setColor(&bw, .red) catch {}; | |
| 2825 | try bw.print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name}); | |
| 2826 | tty_config.setColor(&bw, .reset) catch {}; | |
| 2827 | 2827 | |
| 2828 | 2828 | as.dump(stderr); |
| 2829 | 2829 | } |
| 2830 | tty_config.setColor(w, .red) catch {}; | |
| 2830 | tty_config.setColor(&bw, .red) catch {}; | |
| 2831 | 2831 | try stderr.writeAll(" Hope that helps. Proceeding to panic.\n"); |
| 2832 | tty_config.setColor(w, .reset) catch {}; | |
| 2832 | tty_config.setColor(&bw, .reset) catch {}; | |
| 2833 | 2833 | } |
| 2834 | 2834 | |
| 2835 | 2835 | pub const InstallDir = union(enum) { |
lib/std/Build/Cache.zig+4-3| ... | ... | @@ -68,7 +68,7 @@ const PrefixedPath = struct { |
| 68 | 68 | |
| 69 | 69 | fn findPrefix(cache: *const Cache, file_path: []const u8) !PrefixedPath { |
| 70 | 70 | const gpa = cache.gpa; |
| 71 | const resolved_path = try fs.path.resolve(gpa, &[_][]const u8{file_path}); | |
| 71 | const resolved_path = try fs.path.resolve(gpa, &.{file_path}); | |
| 72 | 72 | errdefer gpa.free(resolved_path); |
| 73 | 73 | return findPrefixResolved(cache, resolved_path); |
| 74 | 74 | } |
| ... | ... | @@ -132,7 +132,7 @@ pub const Hasher = crypto.auth.siphash.SipHash128(1, 3); |
| 132 | 132 | /// Initial state with random bytes, that can be copied. |
| 133 | 133 | /// Refresh this with new random bytes when the manifest |
| 134 | 134 | /// format is modified in a non-backwards-compatible way. |
| 135 | pub const hasher_init: Hasher = Hasher.init(&[_]u8{ | |
| 135 | pub const hasher_init: Hasher = Hasher.init(&.{ | |
| 136 | 136 | 0x33, 0x52, 0xa2, 0x84, |
| 137 | 137 | 0xcf, 0x17, 0x56, 0x57, |
| 138 | 138 | 0x01, 0xbb, 0xcd, 0xe4, |
| ... | ... | @@ -1143,7 +1143,8 @@ pub const Manifest = struct { |
| 1143 | 1143 | } |
| 1144 | 1144 | |
| 1145 | 1145 | try manifest_file.setEndPos(contents.items.len); |
| 1146 | try manifest_file.pwriteAll(contents.items, 0); | |
| 1146 | var pos: usize = 0; | |
| 1147 | while (pos < contents.items.len) pos += try manifest_file.pwrite(contents.items[pos..], pos); | |
| 1147 | 1148 | } |
| 1148 | 1149 | |
| 1149 | 1150 | if (self.want_shared_lock) { |
lib/std/Build/Fuzz.zig+2-2| ... | ... | @@ -124,7 +124,7 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, ttyconf: std.io.tty.Config, par |
| 124 | 124 | const show_stderr = compile.step.result_stderr.len > 0; |
| 125 | 125 | |
| 126 | 126 | if (show_error_msgs or show_compile_errors or show_stderr) { |
| 127 | const bw = std.debug.lockStderrWriter(); | |
| 127 | const bw = std.debug.lockStderrWriter(&.{}); | |
| 128 | 128 | defer std.debug.unlockStderrWriter(); |
| 129 | 129 | build_runner.printErrorMessages(gpa, &compile.step, .{ .ttyconf = ttyconf }, bw, false) catch {}; |
| 130 | 130 | } |
| ... | ... | @@ -151,7 +151,7 @@ fn fuzzWorkerRun( |
| 151 | 151 | |
| 152 | 152 | run.rerunInFuzzMode(web_server, unit_test_index, prog_node) catch |err| switch (err) { |
| 153 | 153 | error.MakeFailed => { |
| 154 | const bw = std.debug.lockStderrWriter(); | |
| 154 | const bw = std.debug.lockStderrWriter(&.{}); | |
| 155 | 155 | defer std.debug.unlockStderrWriter(); |
| 156 | 156 | build_runner.printErrorMessages(gpa, &run.step, .{ .ttyconf = ttyconf }, bw, false) catch {}; |
| 157 | 157 | return; |
lib/std/Build/Fuzz/WebServer.zig+10-2| ... | ... | @@ -98,8 +98,16 @@ fn now(s: *const WebServer) i64 { |
| 98 | 98 | fn accept(ws: *WebServer, connection: std.net.Server.Connection) void { |
| 99 | 99 | defer connection.stream.close(); |
| 100 | 100 | |
| 101 | var read_buffer: [0x4000]u8 = undefined; | |
| 102 | var server = std.http.Server.init(connection, &read_buffer); | |
| 101 | var sr = connection.stream.reader(); | |
| 102 | var rb: [0x4000]u8 = undefined; | |
| 103 | var br: std.io.BufferedReader = undefined; | |
| 104 | br.init(sr.interface(), &rb); | |
| 105 | ||
| 106 | var sw = connection.stream.writer(); | |
| 107 | var wb: [0x4000]u8 = undefined; | |
| 108 | var bw = sw.interface().buffered(&wb); | |
| 109 | ||
| 110 | var server: std.http.Server = .init(&br, &bw); | |
| 103 | 111 | var web_socket: std.http.WebSocket = undefined; |
| 104 | 112 | var send_buffer: [0x4000]u8 = undefined; |
| 105 | 113 | var ws_recv_buffer: [0x4000]u8 align(4) = undefined; |
lib/std/Build/Step.zig+6-5| ... | ... | @@ -287,7 +287,8 @@ pub fn cast(step: *Step, comptime T: type) ?*T { |
| 287 | 287 | |
| 288 | 288 | /// For debugging purposes, prints identifying information about this Step. |
| 289 | 289 | pub fn dump(step: *Step, file: std.fs.File) void { |
| 290 | var bw = file.writer().unbuffered(); | |
| 290 | var fw = file.writer(); | |
| 291 | var bw = fw.interface().unbuffered(); | |
| 291 | 292 | const tty_config = std.io.tty.detectConfig(file); |
| 292 | 293 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { |
| 293 | 294 | bw.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{ |
| ... | ... | @@ -469,7 +470,7 @@ pub fn evalZigProcess( |
| 469 | 470 | // This is intentionally printed for failure on the first build but not for |
| 470 | 471 | // subsequent rebuilds. |
| 471 | 472 | if (s.result_error_bundle.errorMessageCount() > 0) { |
| 472 | return s.fail("the following command failed with {d} compilation errors:\n{s}\n", .{ | |
| 473 | return s.fail("the following command failed with {d} compilation errors:\n{s}", .{ | |
| 473 | 474 | s.result_error_bundle.errorMessageCount(), |
| 474 | 475 | try allocPrintCmd(arena, null, argv), |
| 475 | 476 | }); |
| ... | ... | @@ -689,7 +690,7 @@ pub inline fn handleChildProcUnsupported( |
| 689 | 690 | ) error{ OutOfMemory, MakeFailed }!void { |
| 690 | 691 | if (!std.process.can_spawn) { |
| 691 | 692 | return s.fail( |
| 692 | "unable to execute the following command: host cannot spawn child processes\n{s}\n", | |
| 693 | "unable to execute the following command: host cannot spawn child processes\n{s}", | |
| 693 | 694 | .{try allocPrintCmd(s.owner.allocator, opt_cwd, argv)}, |
| 694 | 695 | ); |
| 695 | 696 | } |
| ... | ... | @@ -706,14 +707,14 @@ pub fn handleChildProcessTerm( |
| 706 | 707 | .Exited => |code| { |
| 707 | 708 | if (code != 0) { |
| 708 | 709 | return s.fail( |
| 709 | "the following command exited with error code {d}:\n{s}\n", | |
| 710 | "the following command exited with error code {d}:\n{s}", | |
| 710 | 711 | .{ code, try allocPrintCmd(arena, opt_cwd, argv) }, |
| 711 | 712 | ); |
| 712 | 713 | } |
| 713 | 714 | }, |
| 714 | 715 | .Signal, .Stopped, .Unknown => { |
| 715 | 716 | return s.fail( |
| 716 | "the following command terminated unexpectedly:\n{s}\n", | |
| 717 | "the following command terminated unexpectedly:\n{s}", | |
| 717 | 718 | .{try allocPrintCmd(arena, opt_cwd, argv)}, |
| 718 | 719 | ); |
| 719 | 720 | }, |
lib/std/Build/Step/CheckObject.zig+1-1| ... | ... | @@ -1791,7 +1791,7 @@ const ElfDumper = struct { |
| 1791 | 1791 | .p64 => @sizeOf(u64), |
| 1792 | 1792 | }; |
| 1793 | 1793 | try br.discard(num * ptr_size); |
| 1794 | const strtab = try br.peekAll(0); | |
| 1794 | const strtab = try br.peekGreedy(0); | |
| 1795 | 1795 | |
| 1796 | 1796 | assert(ctx.symtab.len == 0); |
| 1797 | 1797 | ctx.symtab = try ctx.gpa.alloc(ArSymtabEntry, num); |
lib/std/Build/Step/Run.zig+14-7| ... | ... | @@ -73,9 +73,12 @@ skip_foreign_checks: bool, |
| 73 | 73 | /// external executor (such as qemu) but not fail if the executor is unavailable. |
| 74 | 74 | failing_to_execute_foreign_is_an_error: bool, |
| 75 | 75 | |
| 76 | /// Deprecated for `stdio_limit`. | |
| 77 | max_stdio_size: usize, | |
| 78 | ||
| 76 | 79 | /// If stderr or stdout exceeds this amount, the child process is killed and |
| 77 | 80 | /// the step fails. |
| 78 | max_stdio_size: usize, | |
| 81 | stdio_limit: std.io.Reader.Limit, | |
| 79 | 82 | |
| 80 | 83 | captured_stdout: ?*Output, |
| 81 | 84 | captured_stderr: ?*Output, |
| ... | ... | @@ -186,6 +189,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run { |
| 186 | 189 | .skip_foreign_checks = false, |
| 187 | 190 | .failing_to_execute_foreign_is_an_error = true, |
| 188 | 191 | .max_stdio_size = 10 * 1024 * 1024, |
| 192 | .stdio_limit = .unlimited, | |
| 189 | 193 | .captured_stdout = null, |
| 190 | 194 | .captured_stderr = null, |
| 191 | 195 | .dep_output_file = null, |
| ... | ... | @@ -1772,6 +1776,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult { |
| 1772 | 1776 | var stdout_bytes: ?[]const u8 = null; |
| 1773 | 1777 | var stderr_bytes: ?[]const u8 = null; |
| 1774 | 1778 | |
| 1779 | run.stdio_limit = .limited(run.stdio_limit.min(run.max_stdio_size)); | |
| 1775 | 1780 | if (child.stdout) |stdout| { |
| 1776 | 1781 | if (child.stderr) |stderr| { |
| 1777 | 1782 | var poller = std.io.poll(arena, enum { stdout, stderr }, .{ |
| ... | ... | @@ -1781,19 +1786,21 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult { |
| 1781 | 1786 | defer poller.deinit(); |
| 1782 | 1787 | |
| 1783 | 1788 | while (try poller.poll()) { |
| 1784 | if (poller.fifo(.stdout).count > run.max_stdio_size) | |
| 1785 | return error.StdoutStreamTooLong; | |
| 1786 | if (poller.fifo(.stderr).count > run.max_stdio_size) | |
| 1787 | return error.StderrStreamTooLong; | |
| 1789 | if (run.stdio_limit.toInt()) |limit| { | |
| 1790 | if (poller.fifo(.stderr).count > limit) | |
| 1791 | return error.StdoutStreamTooLong; | |
| 1792 | if (poller.fifo(.stderr).count > limit) | |
| 1793 | return error.StderrStreamTooLong; | |
| 1794 | } | |
| 1788 | 1795 | } |
| 1789 | 1796 | |
| 1790 | 1797 | stdout_bytes = try poller.fifo(.stdout).toOwnedSlice(); |
| 1791 | 1798 | stderr_bytes = try poller.fifo(.stderr).toOwnedSlice(); |
| 1792 | 1799 | } else { |
| 1793 | stdout_bytes = try stdout.reader().readAlloc(arena, run.max_stdio_size); | |
| 1800 | stdout_bytes = try stdout.readToEndAlloc(arena, run.stdio_limit); | |
| 1794 | 1801 | } |
| 1795 | 1802 | } else if (child.stderr) |stderr| { |
| 1796 | stderr_bytes = try stderr.reader().readAlloc(arena, run.max_stdio_size); | |
| 1803 | stderr_bytes = try stderr.readToEndAlloc(arena, run.stdio_limit); | |
| 1797 | 1804 | } |
| 1798 | 1805 | |
| 1799 | 1806 | if (stderr_bytes) |bytes| if (bytes.len > 0) { |
lib/std/crypto/siphash.zig+32-7| ... | ... | @@ -239,16 +239,41 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) |
| 239 | 239 | return State.hash(msg, key); |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | pub const Error = error{}; | |
| 243 | pub const Writer = std.io.Writer(*Self, Error, write); | |
| 242 | pub fn writer(self: *Self) std.io.Writer { | |
| 243 | return .{ | |
| 244 | .context = self, | |
| 245 | .vtable = &.{ | |
| 246 | .writeSplat = &writeSplat, | |
| 247 | .writeFile = &writeFile, | |
| 248 | }, | |
| 249 | }; | |
| 250 | } | |
| 244 | 251 | |
| 245 | fn write(self: *Self, bytes: []const u8) Error!usize { | |
| 246 | self.update(bytes); | |
| 247 | return bytes.len; | |
| 252 | fn writeSplat(ctx: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 253 | const self: *Self = @alignCast(@ptrCast(ctx)); | |
| 254 | var len: usize = 0; | |
| 255 | for (0..splat) |_| for (data) |slice| { | |
| 256 | self.update(slice); | |
| 257 | len += slice.len; | |
| 258 | }; | |
| 259 | return len; | |
| 248 | 260 | } |
| 249 | 261 | |
| 250 | pub fn writer(self: *Self) Writer { | |
| 251 | return .{ .context = self }; | |
| 262 | fn writeFile( | |
| 263 | ctx: ?*anyopaque, | |
| 264 | file: std.fs.File, | |
| 265 | offset: std.io.Writer.Offset, | |
| 266 | limit: std.io.Writer.Limit, | |
| 267 | headers_and_trailers: []const []const u8, | |
| 268 | headers_len: usize, | |
| 269 | ) anyerror!usize { | |
| 270 | _ = ctx; | |
| 271 | _ = file; | |
| 272 | _ = offset; | |
| 273 | _ = limit; | |
| 274 | _ = headers_and_trailers; | |
| 275 | _ = headers_len; | |
| 276 | return error.Unimplemented; | |
| 252 | 277 | } |
| 253 | 278 | }; |
| 254 | 279 | } |
lib/std/fs/Dir.zig+1-1| ... | ... | @@ -2052,7 +2052,7 @@ pub fn readFileIntoArrayList( |
| 2052 | 2052 | try list.ensureUnusedCapacity(gpa, std.math.cast(usize, size) orelse return error.FileTooBig); |
| 2053 | 2053 | } else |err| switch (err) { |
| 2054 | 2054 | // Ignore most errors; size hint is only an optimization. |
| 2055 | error.Unseekable, error.Unexpected, error.AccessDenied, error.PermissionDenied => {}, | |
| 2055 | error.Unexpected, error.AccessDenied, error.PermissionDenied => {}, | |
| 2056 | 2056 | else => |e| return e, |
| 2057 | 2057 | } |
| 2058 | 2058 |
lib/std/http/Client.zig+2-2| ... | ... | @@ -115,14 +115,14 @@ pub const ConnectionPool = struct { |
| 115 | 115 | /// |
| 116 | 116 | /// Threadsafe. |
| 117 | 117 | pub fn release(pool: *ConnectionPool, allocator: Allocator, connection: *Connection) void { |
| 118 | if (connection.closing) return connection.destroy(allocator); | |
| 118 | if (connection.closing) return connection.destroy(); | |
| 119 | 119 | |
| 120 | 120 | pool.mutex.lock(); |
| 121 | 121 | defer pool.mutex.unlock(); |
| 122 | 122 | |
| 123 | 123 | pool.used.remove(&connection.pool_node); |
| 124 | 124 | |
| 125 | if (pool.free_size == 0) return connection.destroy(allocator); | |
| 125 | if (pool.free_size == 0) return connection.destroy(); | |
| 126 | 126 | |
| 127 | 127 | if (pool.free_len >= pool.free_size) { |
| 128 | 128 | const popped: *Connection = @fieldParentPtr("pool_node", pool.free.popFirst().?); |
lib/std/http/Server.zig+42-30| ... | ... | @@ -21,6 +21,9 @@ out: *std.io.BufferedWriter, |
| 21 | 21 | state: State, |
| 22 | 22 | head_parse_err: Request.Head.ParseError, |
| 23 | 23 | |
| 24 | /// being deleted... | |
| 25 | next_request_start: usize = 0, | |
| 26 | ||
| 24 | 27 | pub const State = enum { |
| 25 | 28 | /// The connection is available to be used for the first time, or reused. |
| 26 | 29 | ready, |
| ... | ... | @@ -45,6 +48,7 @@ pub fn init(in: *std.io.BufferedReader, out: *std.io.BufferedWriter) Server { |
| 45 | 48 | .in = in, |
| 46 | 49 | .out = out, |
| 47 | 50 | .state = .ready, |
| 51 | .head_parse_err = undefined, | |
| 48 | 52 | }; |
| 49 | 53 | } |
| 50 | 54 | |
| ... | ... | @@ -63,7 +67,7 @@ pub const ReceiveHeadError = error{ |
| 63 | 67 | /// In other words, a keep-alive connection was finally closed. |
| 64 | 68 | HttpConnectionClosing, |
| 65 | 69 | /// Transitive error occurred reading from `in`. |
| 66 | ReadFailure, | |
| 70 | ReadFailed, | |
| 67 | 71 | }; |
| 68 | 72 | |
| 69 | 73 | /// The header bytes reference the internal storage of `in`, which are |
| ... | ... | @@ -73,7 +77,7 @@ pub fn receiveHead(s: *Server) ReceiveHeadError!Request { |
| 73 | 77 | s.state = .received_head; |
| 74 | 78 | errdefer s.state = .receiving_head; |
| 75 | 79 | |
| 76 | const in = &s.in; | |
| 80 | const in = s.in; | |
| 77 | 81 | var hp: http.HeadParser = .{}; |
| 78 | 82 | var head_end: usize = 0; |
| 79 | 83 | |
| ... | ... | @@ -84,7 +88,7 @@ pub fn receiveHead(s: *Server) ReceiveHeadError!Request { |
| 84 | 88 | 0 => return error.HttpConnectionClosing, |
| 85 | 89 | else => return error.HttpRequestTruncated, |
| 86 | 90 | }, |
| 87 | error.ReadFailure => return error.ReadFailure, | |
| 91 | error.ReadFailed => return error.ReadFailed, | |
| 88 | 92 | }; |
| 89 | 93 | head_end += hp.feed(buf[head_end..]); |
| 90 | 94 | if (hp.state == .finished) return .{ |
| ... | ... | @@ -279,7 +283,7 @@ pub const Request = struct { |
| 279 | 283 | }; |
| 280 | 284 | |
| 281 | 285 | pub fn iterateHeaders(r: *Request) http.HeaderIterator { |
| 282 | return http.HeaderIterator.init(r.in.bufferContents()[0..r.head_end]); | |
| 286 | return http.HeaderIterator.init(r.server.in.bufferContents()[0..r.head_end]); | |
| 283 | 287 | } |
| 284 | 288 | |
| 285 | 289 | test iterateHeaders { |
| ... | ... | @@ -398,8 +402,7 @@ pub const Request = struct { |
| 398 | 402 | h.appendSliceAssumeCapacity("HTTP/1.1 417 Expectation Failed\r\n"); |
| 399 | 403 | if (!keep_alive) h.appendSliceAssumeCapacity("connection: close\r\n"); |
| 400 | 404 | h.appendSliceAssumeCapacity("content-length: 0\r\n\r\n"); |
| 401 | var w = request.server.connection.stream.writer().unbuffered(); | |
| 402 | try w.writeAll(h.items); | |
| 405 | try request.server.out.writeAll(h.items); | |
| 403 | 406 | return; |
| 404 | 407 | } |
| 405 | 408 | h.printAssumeCapacity("{s} {d} {s}\r\n", .{ |
| ... | ... | @@ -472,8 +475,7 @@ pub const Request = struct { |
| 472 | 475 | } |
| 473 | 476 | } |
| 474 | 477 | |
| 475 | var w = request.server.connection.stream.writer().unbuffered(); | |
| 476 | try w.writevAll(iovecs[0..iovecs_len]); | |
| 478 | try request.server.out.writeVecAll(iovecs[0..iovecs_len]); | |
| 477 | 479 | } |
| 478 | 480 | |
| 479 | 481 | pub const RespondStreamingOptions = struct { |
| ... | ... | @@ -553,7 +555,7 @@ pub const Request = struct { |
| 553 | 555 | }; |
| 554 | 556 | |
| 555 | 557 | return .{ |
| 556 | .stream = request.server.connection.stream, | |
| 558 | .out = request.server.out, | |
| 557 | 559 | .send_buffer = options.send_buffer, |
| 558 | 560 | .send_buffer_start = 0, |
| 559 | 561 | .send_buffer_end = h.items.len, |
| ... | ... | @@ -577,7 +579,7 @@ pub const Request = struct { |
| 577 | 579 | ctx: ?*anyopaque, |
| 578 | 580 | bw: *std.io.BufferedWriter, |
| 579 | 581 | limit: std.io.Reader.Limit, |
| 580 | ) std.io.Reader.Error!std.io.Reader.Status { | |
| 582 | ) std.io.Reader.Error!usize { | |
| 581 | 583 | const request: *Request = @alignCast(@ptrCast(ctx)); |
| 582 | 584 | _ = request; |
| 583 | 585 | _ = bw; |
| ... | ... | @@ -585,13 +587,20 @@ pub const Request = struct { |
| 585 | 587 | @panic("TODO"); |
| 586 | 588 | } |
| 587 | 589 | |
| 588 | fn contentLengthReader_readv(ctx: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | |
| 590 | fn contentLengthReader_readVec(ctx: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | |
| 589 | 591 | const request: *Request = @alignCast(@ptrCast(ctx)); |
| 590 | 592 | _ = request; |
| 591 | 593 | _ = data; |
| 592 | 594 | @panic("TODO"); |
| 593 | 595 | } |
| 594 | 596 | |
| 597 | fn contentLengthReader_discard(ctx: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { | |
| 598 | const request: *Request = @alignCast(@ptrCast(ctx)); | |
| 599 | _ = request; | |
| 600 | _ = limit; | |
| 601 | @panic("TODO"); | |
| 602 | } | |
| 603 | ||
| 595 | 604 | fn chunkedReader_read( |
| 596 | 605 | ctx: ?*anyopaque, |
| 597 | 606 | bw: *std.io.BufferedWriter, |
| ... | ... | @@ -604,13 +613,20 @@ pub const Request = struct { |
| 604 | 613 | @panic("TODO"); |
| 605 | 614 | } |
| 606 | 615 | |
| 607 | fn chunkedReader_readv(ctx: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | |
| 616 | fn chunkedReader_readVec(ctx: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | |
| 608 | 617 | const request: *Request = @alignCast(@ptrCast(ctx)); |
| 609 | 618 | _ = request; |
| 610 | 619 | _ = data; |
| 611 | 620 | @panic("TODO"); |
| 612 | 621 | } |
| 613 | 622 | |
| 623 | fn chunkedReader_discard(ctx: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { | |
| 624 | const request: *Request = @alignCast(@ptrCast(ctx)); | |
| 625 | _ = request; | |
| 626 | _ = limit; | |
| 627 | @panic("TODO"); | |
| 628 | } | |
| 629 | ||
| 614 | 630 | fn read_cl(context: *const anyopaque, buffer: []u8) ReadError!usize { |
| 615 | 631 | const request: *Request = @alignCast(@ptrCast(context)); |
| 616 | 632 | const s = request.server; |
| ... | ... | @@ -751,8 +767,7 @@ pub const Request = struct { |
| 751 | 767 | |
| 752 | 768 | if (request.head.expect) |expect| { |
| 753 | 769 | if (mem.eql(u8, expect, "100-continue")) { |
| 754 | var w = request.server.connection.stream.writer().unbuffered(); | |
| 755 | try w.writeAll("HTTP/1.1 100 Continue\r\n\r\n"); | |
| 770 | try request.server.out.writeAll("HTTP/1.1 100 Continue\r\n\r\n"); | |
| 756 | 771 | request.head.expect = null; |
| 757 | 772 | } else { |
| 758 | 773 | return error.HttpExpectationFailed; |
| ... | ... | @@ -766,7 +781,8 @@ pub const Request = struct { |
| 766 | 781 | .context = request, |
| 767 | 782 | .vtable = &.{ |
| 768 | 783 | .read = &chunkedReader_read, |
| 769 | .readv = &chunkedReader_readv, | |
| 784 | .readVec = &chunkedReader_readVec, | |
| 785 | .discard = &chunkedReader_discard, | |
| 770 | 786 | }, |
| 771 | 787 | }; |
| 772 | 788 | }, |
| ... | ... | @@ -778,7 +794,8 @@ pub const Request = struct { |
| 778 | 794 | .context = request, |
| 779 | 795 | .vtable = &.{ |
| 780 | 796 | .read = &contentLengthReader_read, |
| 781 | .readv = &contentLengthReader_readv, | |
| 797 | .readVec = &contentLengthReader_readVec, | |
| 798 | .discard = &contentLengthReader_discard, | |
| 782 | 799 | }, |
| 783 | 800 | }; |
| 784 | 801 | }, |
| ... | ... | @@ -801,7 +818,7 @@ pub const Request = struct { |
| 801 | 818 | if (keep_alive and request.head.keep_alive) switch (s.state) { |
| 802 | 819 | .received_head => { |
| 803 | 820 | const r = request.reader() catch return false; |
| 804 | _ = r.discardUntilEnd() catch return false; | |
| 821 | _ = r.discardRemaining() catch return false; | |
| 805 | 822 | assert(s.state == .ready); |
| 806 | 823 | return true; |
| 807 | 824 | }, |
| ... | ... | @@ -819,7 +836,7 @@ pub const Request = struct { |
| 819 | 836 | }; |
| 820 | 837 | |
| 821 | 838 | pub const Response = struct { |
| 822 | stream: net.Stream, | |
| 839 | out: *std.io.BufferedWriter, | |
| 823 | 840 | send_buffer: []u8, |
| 824 | 841 | /// Index of the first byte in `send_buffer`. |
| 825 | 842 | /// This is 0 unless a short write happens in `write`. |
| ... | ... | @@ -909,7 +926,7 @@ pub const Response = struct { |
| 909 | 926 | _ = limit; |
| 910 | 927 | _ = headers_and_trailers; |
| 911 | 928 | _ = headers_len; |
| 912 | return error.Unimplemented; | |
| 929 | @panic("TODO"); | |
| 913 | 930 | } |
| 914 | 931 | |
| 915 | 932 | fn cl_write(context: ?*anyopaque, bytes: []const u8) std.io.Writer.Error!usize { |
| ... | ... | @@ -932,8 +949,7 @@ pub const Response = struct { |
| 932 | 949 | r.send_buffer[r.send_buffer_start..][0..send_buffer_len], |
| 933 | 950 | bytes, |
| 934 | 951 | }; |
| 935 | var w = r.stream.writer().unbuffered(); | |
| 936 | const n = try w.writev(&iovecs); | |
| 952 | const n = try r.out.writeVec(&iovecs); | |
| 937 | 953 | |
| 938 | 954 | if (n >= send_buffer_len) { |
| 939 | 955 | // It was enough to reset the buffer. |
| ... | ... | @@ -976,7 +992,7 @@ pub const Response = struct { |
| 976 | 992 | _ = limit; |
| 977 | 993 | _ = headers_and_trailers; |
| 978 | 994 | _ = headers_len; |
| 979 | return error.Unimplemented; // TODO lower to a call to writeFile on the output | |
| 995 | @panic("TODO"); // TODO lower to a call to writeFile on the output | |
| 980 | 996 | } |
| 981 | 997 | |
| 982 | 998 | fn chunked_write(context: ?*anyopaque, bytes: []const u8) std.io.Writer.Error!usize { |
| ... | ... | @@ -1001,8 +1017,7 @@ pub const Response = struct { |
| 1001 | 1017 | }; |
| 1002 | 1018 | // TODO make this writev instead of writevAll, which involves |
| 1003 | 1019 | // complicating the logic of this function. |
| 1004 | var w = r.stream.writer().unbuffered(); | |
| 1005 | try w.writevAll(&iovecs); | |
| 1020 | try r.out.writeVecAll(&iovecs); | |
| 1006 | 1021 | r.send_buffer_start = 0; |
| 1007 | 1022 | r.send_buffer_end = 0; |
| 1008 | 1023 | r.chunk_len = 0; |
| ... | ... | @@ -1036,8 +1051,7 @@ pub const Response = struct { |
| 1036 | 1051 | } |
| 1037 | 1052 | |
| 1038 | 1053 | fn flush_cl(r: *Response) std.io.Writer.Error!void { |
| 1039 | var w = r.stream.writer().unbuffered(); | |
| 1040 | try w.writeAll(r.send_buffer[r.send_buffer_start..r.send_buffer_end]); | |
| 1054 | try r.out.writeAll(r.send_buffer[r.send_buffer_start..r.send_buffer_end]); | |
| 1041 | 1055 | r.send_buffer_start = 0; |
| 1042 | 1056 | r.send_buffer_end = 0; |
| 1043 | 1057 | } |
| ... | ... | @@ -1050,8 +1064,7 @@ pub const Response = struct { |
| 1050 | 1064 | const http_headers = r.send_buffer[r.send_buffer_start .. r.send_buffer_end - r.chunk_len]; |
| 1051 | 1065 | |
| 1052 | 1066 | if (r.elide_body) { |
| 1053 | var w = r.stream.writer().unbuffered(); | |
| 1054 | try w.writeAll(http_headers); | |
| 1067 | try r.out.writeAll(http_headers); | |
| 1055 | 1068 | r.send_buffer_start = 0; |
| 1056 | 1069 | r.send_buffer_end = 0; |
| 1057 | 1070 | r.chunk_len = 0; |
| ... | ... | @@ -1102,8 +1115,7 @@ pub const Response = struct { |
| 1102 | 1115 | iovecs_len += 1; |
| 1103 | 1116 | } |
| 1104 | 1117 | |
| 1105 | var w = r.stream.writer().unbuffered(); | |
| 1106 | try w.writevAll(iovecs[0..iovecs_len]); | |
| 1118 | try r.out.writeVecAll(iovecs[0..iovecs_len]); | |
| 1107 | 1119 | r.send_buffer_start = 0; |
| 1108 | 1120 | r.send_buffer_end = 0; |
| 1109 | 1121 | r.chunk_len = 0; |
lib/std/http/WebSocket.zig+2-4| ... | ... | @@ -194,16 +194,14 @@ fn recvReadInt(ws: *WebSocket, comptime I: type) !I { |
| 194 | 194 | }; |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | pub const WriteError = std.http.Server.Response.WriteError; | |
| 198 | ||
| 199 | pub fn writeMessage(ws: *WebSocket, message: []const u8, opcode: Opcode) WriteError!void { | |
| 197 | pub fn writeMessage(ws: *WebSocket, message: []const u8, opcode: Opcode) std.io.Writer.Error!void { | |
| 200 | 198 | const iovecs: [1]std.posix.iovec_const = .{ |
| 201 | 199 | .{ .base = message.ptr, .len = message.len }, |
| 202 | 200 | }; |
| 203 | 201 | return writeMessagev(ws, &iovecs, opcode); |
| 204 | 202 | } |
| 205 | 203 | |
| 206 | pub fn writeMessagev(ws: *WebSocket, message: []const std.posix.iovec_const, opcode: Opcode) WriteError!void { | |
| 204 | pub fn writeMessagev(ws: *WebSocket, message: []const std.posix.iovec_const, opcode: Opcode) std.io.Writer.Error!void { | |
| 207 | 205 | const total_len = l: { |
| 208 | 206 | var total_len: u64 = 0; |
| 209 | 207 | for (message) |iovec| total_len += iovec.len; |
lib/std/io/AllocatingWriter.zig+2-3| ... | ... | @@ -93,9 +93,8 @@ pub fn toArrayList(aw: *AllocatingWriter) std.ArrayListUnmanaged(u8) { |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | pub fn toOwnedSlice(aw: *AllocatingWriter) error{OutOfMemory}![]u8 { |
| 96 | const gpa = aw.allocator; | |
| 97 | var list = toArrayList(aw); | |
| 98 | return list.toOwnedSlice(gpa); | |
| 96 | var list = aw.toArrayList(); | |
| 97 | return list.toOwnedSlice(aw.allocator); | |
| 99 | 98 | } |
| 100 | 99 | |
| 101 | 100 | pub fn toOwnedSliceSentinel(aw: *AllocatingWriter, comptime sentinel: u8) error{OutOfMemory}![:sentinel]u8 { |
lib/std/io/BufferedReader.zig+11-9| ... | ... | @@ -97,19 +97,20 @@ pub fn seekForwardBy(br: *BufferedReader, seek_by: u64) !void { |
| 97 | 97 | br.seek = seek; |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | /// Returns the next `n` bytes from `unbuffered_reader`, filling the buffer as | |
| 100 | /// Returns the next `len` bytes from `unbuffered_reader`, filling the buffer as | |
| 101 | 101 | /// necessary. |
| 102 | 102 | /// |
| 103 | 103 | /// Invalidates previously returned values from `peek`. |
| 104 | 104 | /// |
| 105 | 105 | /// Asserts that the `BufferedReader` was initialized with a buffer capacity at |
| 106 | /// least as big as `n`. | |
| 106 | /// least as big as `len`. | |
| 107 | 107 | /// |
| 108 | /// If there are fewer than `n` bytes left in the stream, `error.EndOfStream` | |
| 108 | /// If there are fewer than `len` bytes left in the stream, `error.EndOfStream` | |
| 109 | 109 | /// is returned instead. |
| 110 | 110 | /// |
| 111 | 111 | /// See also: |
| 112 | /// * `peekGreedy` | |
| 112 | /// * `peek` | |
| 113 | /// * `tryPeekArray` | |
| 113 | 114 | /// * `toss` |
| 114 | 115 | pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 { |
| 115 | 116 | const storage = &br.storage; |
| ... | ... | @@ -119,18 +120,19 @@ pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 { |
| 119 | 120 | } |
| 120 | 121 | |
| 121 | 122 | /// Returns all the next buffered bytes from `unbuffered_reader`, after filling |
| 122 | /// the buffer to ensure it contains at least `n` bytes. | |
| 123 | /// the buffer to ensure it contains at least `min_len` bytes. | |
| 123 | 124 | /// |
| 124 | 125 | /// Invalidates previously returned values from `peek` and `peekGreedy`. |
| 125 | 126 | /// |
| 126 | 127 | /// Asserts that the `BufferedReader` was initialized with a buffer capacity at |
| 127 | /// least as big as `n`. | |
| 128 | /// least as big as `min_len`. | |
| 128 | 129 | /// |
| 129 | /// If there are fewer than `n` bytes left in the stream, `error.EndOfStream` | |
| 130 | /// If there are fewer than `min_len` bytes left in the stream, `error.EndOfStream` | |
| 130 | 131 | /// is returned instead. |
| 131 | 132 | /// |
| 132 | 133 | /// See also: |
| 133 | 134 | /// * `peek` |
| 135 | /// * `tryPeekGreedy` | |
| 134 | 136 | /// * `toss` |
| 135 | 137 | pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 { |
| 136 | 138 | const storage = &br.storage; |
| ... | ... | @@ -214,7 +216,7 @@ pub fn discardShort(br: *BufferedReader, n: usize) Reader.ShortError!usize { |
| 214 | 216 | storage.end = 0; |
| 215 | 217 | br.seek = 0; |
| 216 | 218 | while (true) { |
| 217 | const discard_len = br.unbuffered_reader.discard(remaining, .unlimited) catch |err| switch (err) { | |
| 219 | const discard_len = br.unbuffered_reader.discard(.limited(remaining)) catch |err| switch (err) { | |
| 218 | 220 | error.EndOfStream => return n - remaining, |
| 219 | 221 | error.ReadFailed => return error.ReadFailed, |
| 220 | 222 | }; |
| ... | ... | @@ -564,7 +566,7 @@ pub inline fn takeStructEndian(br: *BufferedReader, comptime T: type, endian: st |
| 564 | 566 | /// it. Otherwise, returns `error.InvalidEnumTag`. |
| 565 | 567 | /// |
| 566 | 568 | /// Asserts the buffer was initialized with a capacity at least `@sizeOf(Enum)`. |
| 567 | pub fn takeEnum(br: *BufferedReader, comptime Enum: type, endian: std.builtin.Endian) Reader.Error!Enum { | |
| 569 | pub fn takeEnum(br: *BufferedReader, comptime Enum: type, endian: std.builtin.Endian) (Reader.Error || std.meta.IntToEnumError)!Enum { | |
| 568 | 570 | const Tag = @typeInfo(Enum).@"enum".tag_type; |
| 569 | 571 | const int = try br.takeInt(Tag, endian); |
| 570 | 572 | return std.meta.intToEnum(Enum, int); |
lib/std/io/BufferedWriter.zig+5| ... | ... | @@ -83,6 +83,11 @@ pub fn unusedCapacitySlice(bw: *const BufferedWriter) []u8 { |
| 83 | 83 | return bw.buffer[bw.end..]; |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | /// Asserts the provided buffer has total capacity enough for `len`. | |
| 87 | pub fn writableArray(bw: *BufferedWriter, comptime len: usize) anyerror!*[len]u8 { | |
| 88 | return (try bw.writableSlice(len))[0..len]; | |
| 89 | } | |
| 90 | ||
| 86 | 91 | /// Asserts the provided buffer has total capacity enough for `minimum_length`. |
| 87 | 92 | pub fn writableSlice(bw: *BufferedWriter, minimum_length: usize) Writer.Error![]u8 { |
| 88 | 93 | assert(bw.buffer.len >= minimum_length); |
lib/std/io/multi_writer.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ pub fn MultiWriter(comptime Writers: type) type { |
| 6 | 6 | comptime var ErrSet = error{}; |
| 7 | 7 | inline for (@typeInfo(Writers).@"struct".fields) |field| { |
| 8 | 8 | const StreamType = field.type; |
| 9 | ErrSet = ErrSet || StreamType.Error; | |
| 9 | ErrSet = ErrSet || if (@hasDecl(StreamType, "Error")) StreamType.Error else anyerror; | |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | 12 | return struct { |
lib/std/net.zig+251-212| ... | ... | @@ -1817,7 +1817,10 @@ pub const Stream = struct { |
| 1817 | 1817 | /// interchangeable with a file system file descriptor. |
| 1818 | 1818 | handle: Handle, |
| 1819 | 1819 | |
| 1820 | pub const Handle = if (native_os == .windows) windows.ws2_32.SOCKET else posix.fd_t; | |
| 1820 | pub const Handle = switch (native_os) { | |
| 1821 | .windows => windows.ws2_32.SOCKET, | |
| 1822 | else => posix.fd_t, | |
| 1823 | }; | |
| 1821 | 1824 | |
| 1822 | 1825 | pub fn close(s: Stream) void { |
| 1823 | 1826 | switch (native_os) { |
| ... | ... | @@ -1826,238 +1829,274 @@ pub const Stream = struct { |
| 1826 | 1829 | } |
| 1827 | 1830 | } |
| 1828 | 1831 | |
| 1829 | pub const ReadError = posix.ReadError; | |
| 1830 | pub const WriteError = posix.SendMsgError || error{ | |
| 1831 | ConnectionResetByPeer, | |
| 1832 | SocketNotBound, | |
| 1833 | MessageTooBig, | |
| 1834 | NetworkSubsystemFailed, | |
| 1835 | SystemResources, | |
| 1836 | SocketNotConnected, | |
| 1837 | Unexpected, | |
| 1838 | }; | |
| 1839 | ||
| 1840 | pub fn reader(stream: Stream) std.io.Reader { | |
| 1841 | return .{ | |
| 1842 | .context = handleToOpaque(stream.handle), | |
| 1843 | .vtable = switch (native_os) { | |
| 1844 | .windows => &.{ | |
| 1845 | .read = windows_read, | |
| 1846 | .readv = windows_readv, | |
| 1847 | }, | |
| 1848 | else => &.{ | |
| 1849 | .read = std.fs.File.streamRead, | |
| 1850 | .readv = std.fs.File.streamReadVec, | |
| 1851 | }, | |
| 1832 | pub const Reader = struct { | |
| 1833 | impl: switch (native_os) { | |
| 1834 | .windows => Stream, | |
| 1835 | else => struct { | |
| 1836 | fr: std.fs.File.Reader, | |
| 1837 | err: Error!void, | |
| 1852 | 1838 | }, |
| 1853 | }; | |
| 1854 | } | |
| 1839 | }, | |
| 1855 | 1840 | |
| 1856 | pub fn writer(stream: Stream) std.io.Writer { | |
| 1857 | return .{ | |
| 1858 | .context = handleToOpaque(stream.handle), | |
| 1859 | .vtable = switch (native_os) { | |
| 1860 | .windows => &.{ | |
| 1861 | .writeSplat = windows_writeSplat, | |
| 1862 | .writeFile = windows_writeFile, | |
| 1841 | pub const Error = posix.ReadError; | |
| 1842 | ||
| 1843 | pub fn interface(r: *Reader) std.io.Reader { | |
| 1844 | return switch (native_os) { | |
| 1845 | .windows => .{ | |
| 1846 | .context = r.impl.stream.handle, | |
| 1847 | .vtable = &.{ | |
| 1848 | .read = windows_read, | |
| 1849 | .readVec = windows_readVec, | |
| 1850 | .discard = windows_discard, | |
| 1851 | }, | |
| 1863 | 1852 | }, |
| 1864 | else => &.{ | |
| 1865 | .writeSplat = posix_writeSplat, | |
| 1866 | .writeFile = std.fs.File.writeFile, | |
| 1867 | }, | |
| 1868 | }, | |
| 1869 | }; | |
| 1870 | } | |
| 1853 | else => r.interface(), | |
| 1854 | }; | |
| 1855 | } | |
| 1871 | 1856 | |
| 1872 | fn windows_read( | |
| 1873 | context: ?*anyopaque, | |
| 1874 | bw: *std.io.BufferedWriter, | |
| 1875 | limit: std.io.Reader.Limit, | |
| 1876 | ) std.io.Reader.Error!usize { | |
| 1877 | const buf = limit.slice(try bw.writableSlice(1)); | |
| 1878 | const status = try windows_readv(context, &.{buf}); | |
| 1879 | bw.advance(status.len); | |
| 1880 | return status; | |
| 1881 | } | |
| 1857 | fn windows_read( | |
| 1858 | context: ?*anyopaque, | |
| 1859 | bw: *std.io.BufferedWriter, | |
| 1860 | limit: std.io.Reader.Limit, | |
| 1861 | ) std.io.Reader.Error!usize { | |
| 1862 | const buf = limit.slice(try bw.writableSlice(1)); | |
| 1863 | const status = try windows_readVec(context, &.{buf}); | |
| 1864 | bw.advance(status.len); | |
| 1865 | return status; | |
| 1866 | } | |
| 1882 | 1867 | |
| 1883 | fn windows_readv(context: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | |
| 1884 | var iovecs: [max_buffers_len]windows.WSABUF = undefined; | |
| 1885 | var iovecs_i: usize = 0; | |
| 1886 | for (data) |d| { | |
| 1887 | // In case Windows checks pointer address before length, we must omit | |
| 1888 | // length-zero vectors. | |
| 1889 | if (d.len == 0) continue; | |
| 1890 | iovecs[iovecs_i] = .{ .buf = d.ptr, .len = d.len }; | |
| 1891 | iovecs_i += 1; | |
| 1892 | if (iovecs_i >= iovecs.len) break; | |
| 1868 | fn windows_readVec(context: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | |
| 1869 | var iovecs: [max_buffers_len]windows.WSABUF = undefined; | |
| 1870 | var iovecs_i: usize = 0; | |
| 1871 | for (data) |d| { | |
| 1872 | // In case Windows checks pointer address before length, we must omit | |
| 1873 | // length-zero vectors. | |
| 1874 | if (d.len == 0) continue; | |
| 1875 | iovecs[iovecs_i] = .{ .buf = d.ptr, .len = d.len }; | |
| 1876 | iovecs_i += 1; | |
| 1877 | if (iovecs_i >= iovecs.len) break; | |
| 1878 | } | |
| 1879 | const bufs = iovecs[0..iovecs_i]; | |
| 1880 | if (bufs.len == 0) return .{}; // Prevent false positive end detection on empty `data`. | |
| 1881 | var n: u32 = undefined; | |
| 1882 | var flags: u32 = 0; | |
| 1883 | const rc = windows.ws2_32.WSARecvFrom(context, bufs.ptr, bufs.len, &n, &flags, null, null, null, null); | |
| 1884 | if (rc != 0) switch (windows.ws2_32.WSAGetLastError()) { | |
| 1885 | .WSAECONNRESET => return error.ConnectionResetByPeer, | |
| 1886 | .WSAEFAULT => unreachable, // a pointer is not completely contained in user address space. | |
| 1887 | .WSAEINPROGRESS, .WSAEINTR => unreachable, // deprecated and removed in WSA 2.2 | |
| 1888 | .WSAEINVAL => return error.SocketNotBound, | |
| 1889 | .WSAEMSGSIZE => return error.MessageTooBig, | |
| 1890 | .WSAENETDOWN => return error.NetworkSubsystemFailed, | |
| 1891 | .WSAENETRESET => return error.ConnectionResetByPeer, | |
| 1892 | .WSAENOTCONN => return error.SocketNotConnected, | |
| 1893 | .WSAEWOULDBLOCK => return error.WouldBlock, | |
| 1894 | .WSANOTINITIALISED => unreachable, // WSAStartup must be called before this function | |
| 1895 | .WSA_IO_PENDING => unreachable, // not using overlapped I/O | |
| 1896 | .WSA_OPERATION_ABORTED => unreachable, // not using overlapped I/O | |
| 1897 | else => |err| return windows.unexpectedWSAError(err), | |
| 1898 | }; | |
| 1899 | return .{ .len = n, .end = n == 0 }; | |
| 1893 | 1900 | } |
| 1894 | const bufs = iovecs[0..iovecs_i]; | |
| 1895 | if (bufs.len == 0) return .{}; // Prevent false positive end detection on empty `data`. | |
| 1896 | const handle = opaqueToHandle(context); | |
| 1897 | var n: u32 = undefined; | |
| 1898 | var flags: u32 = 0; | |
| 1899 | const rc = windows.ws2_32.WSARecvFrom(handle, bufs.ptr, bufs.len, &n, &flags, null, null, null, null); | |
| 1900 | if (rc != 0) switch (windows.ws2_32.WSAGetLastError()) { | |
| 1901 | .WSAECONNRESET => return error.ConnectionResetByPeer, | |
| 1902 | .WSAEFAULT => unreachable, // a pointer is not completely contained in user address space. | |
| 1903 | .WSAEINPROGRESS, .WSAEINTR => unreachable, // deprecated and removed in WSA 2.2 | |
| 1904 | .WSAEINVAL => return error.SocketNotBound, | |
| 1905 | .WSAEMSGSIZE => return error.MessageTooBig, | |
| 1906 | .WSAENETDOWN => return error.NetworkSubsystemFailed, | |
| 1907 | .WSAENETRESET => return error.ConnectionResetByPeer, | |
| 1908 | .WSAENOTCONN => return error.SocketNotConnected, | |
| 1909 | .WSAEWOULDBLOCK => return error.WouldBlock, | |
| 1910 | .WSANOTINITIALISED => unreachable, // WSAStartup must be called before this function | |
| 1911 | .WSA_IO_PENDING => unreachable, // not using overlapped I/O | |
| 1912 | .WSA_OPERATION_ABORTED => unreachable, // not using overlapped I/O | |
| 1913 | else => |err| return windows.unexpectedWSAError(err), | |
| 1914 | }; | |
| 1915 | return .{ .len = n, .end = n == 0 }; | |
| 1916 | } | |
| 1917 | 1901 | |
| 1918 | fn windows_writeSplat(context: *anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 1919 | comptime assert(native_os == .windows); | |
| 1920 | if (data.len == 1 and splat == 0) return 0; | |
| 1921 | var splat_buffer: [256]u8 = undefined; | |
| 1922 | var iovecs: [max_buffers_len]windows.WSABUF = undefined; | |
| 1923 | var len: u32 = @min(iovecs.len, data.len); | |
| 1924 | for (iovecs[0..len], data[0..len]) |*v, d| v.* = .{ | |
| 1925 | .buf = if (d.len == 0) "" else d.ptr, // TODO: does Windows allow ptr=undefined len=0 ? | |
| 1926 | .len = d.len, | |
| 1927 | }; | |
| 1928 | switch (splat) { | |
| 1929 | 0 => len -= 1, | |
| 1930 | 1 => {}, | |
| 1931 | else => { | |
| 1932 | const pattern = data[data.len - 1]; | |
| 1933 | if (pattern.len == 1) { | |
| 1934 | const memset_len = @min(splat_buffer.len, splat); | |
| 1935 | const buf = splat_buffer[0..memset_len]; | |
| 1936 | @memset(buf, pattern[0]); | |
| 1937 | iovecs[len - 1] = .{ .base = buf.ptr, .len = buf.len }; | |
| 1938 | var remaining_splat = splat - buf.len; | |
| 1939 | while (remaining_splat > splat_buffer.len and len < iovecs.len) { | |
| 1940 | iovecs[len] = .{ .base = &splat_buffer, .len = splat_buffer.len }; | |
| 1941 | remaining_splat -= splat_buffer.len; | |
| 1942 | len += 1; | |
| 1943 | } | |
| 1944 | if (remaining_splat > 0 and len < iovecs.len) { | |
| 1945 | iovecs[len] = .{ .base = &splat_buffer, .len = remaining_splat }; | |
| 1946 | len += 1; | |
| 1947 | } | |
| 1948 | } | |
| 1949 | }, | |
| 1902 | fn windows_discard(context: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { | |
| 1903 | _ = context; | |
| 1904 | _ = limit; | |
| 1905 | @panic("TODO"); | |
| 1950 | 1906 | } |
| 1951 | const handle = opaqueToHandle(context); | |
| 1952 | var n: u32 = undefined; | |
| 1953 | const rc = windows.ws2_32.WSASend(handle, &iovecs, len, &n, 0, null, null); | |
| 1954 | if (rc == windows.ws2_32.SOCKET_ERROR) switch (windows.ws2_32.WSAGetLastError()) { | |
| 1955 | .WSAECONNABORTED => return error.ConnectionResetByPeer, | |
| 1956 | .WSAECONNRESET => return error.ConnectionResetByPeer, | |
| 1957 | .WSAEFAULT => unreachable, // a pointer is not completely contained in user address space. | |
| 1958 | .WSAEINPROGRESS, .WSAEINTR => unreachable, // deprecated and removed in WSA 2.2 | |
| 1959 | .WSAEINVAL => return error.SocketNotBound, | |
| 1960 | .WSAEMSGSIZE => return error.MessageTooBig, | |
| 1961 | .WSAENETDOWN => return error.NetworkSubsystemFailed, | |
| 1962 | .WSAENETRESET => return error.ConnectionResetByPeer, | |
| 1963 | .WSAENOBUFS => return error.SystemResources, | |
| 1964 | .WSAENOTCONN => return error.SocketNotConnected, | |
| 1965 | .WSAENOTSOCK => unreachable, // not a socket | |
| 1966 | .WSAEOPNOTSUPP => unreachable, // only for message-oriented sockets | |
| 1967 | .WSAESHUTDOWN => unreachable, // cannot send on a socket after write shutdown | |
| 1968 | .WSAEWOULDBLOCK => return error.WouldBlock, | |
| 1969 | .WSANOTINITIALISED => unreachable, // WSAStartup must be called before this function | |
| 1970 | .WSA_IO_PENDING => unreachable, // not using overlapped I/O | |
| 1971 | .WSA_OPERATION_ABORTED => unreachable, // not using overlapped I/O | |
| 1972 | else => |err| return windows.unexpectedWSAError(err), | |
| 1973 | }; | |
| 1974 | return n; | |
| 1975 | } | |
| 1907 | }; | |
| 1908 | ||
| 1909 | pub const Writer = struct { | |
| 1910 | impl: switch (native_os) { | |
| 1911 | .windows => Stream, | |
| 1912 | else => PosixImpl, | |
| 1913 | }, | |
| 1976 | 1914 | |
| 1977 | fn posix_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 1978 | const sock_fd = opaqueToHandle(context); | |
| 1979 | comptime assert(native_os != .windows); | |
| 1980 | var splat_buffer: [256]u8 = undefined; | |
| 1981 | var iovecs: [max_buffers_len]std.posix.iovec_const = undefined; | |
| 1982 | var len: usize = @min(iovecs.len, data.len); | |
| 1983 | for (iovecs[0..len], data[0..len]) |*v, d| v.* = .{ | |
| 1984 | .base = if (d.len == 0) "" else d.ptr, // OS sadly checks ptr addr before length. | |
| 1985 | .len = d.len, | |
| 1915 | const PosixImpl = struct { | |
| 1916 | fw: std.fs.File.Writer, | |
| 1917 | err: Error!void, | |
| 1986 | 1918 | }; |
| 1987 | var msg: posix.msghdr_const = .{ | |
| 1988 | .name = null, | |
| 1989 | .namelen = 0, | |
| 1990 | .iov = &iovecs, | |
| 1991 | .iovlen = len, | |
| 1992 | .control = null, | |
| 1993 | .controllen = 0, | |
| 1994 | .flags = 0, | |
| 1919 | ||
| 1920 | pub const Error = posix.SendMsgError || error{ | |
| 1921 | ConnectionResetByPeer, | |
| 1922 | SocketNotBound, | |
| 1923 | MessageTooBig, | |
| 1924 | NetworkSubsystemFailed, | |
| 1925 | SystemResources, | |
| 1926 | SocketNotConnected, | |
| 1927 | Unexpected, | |
| 1995 | 1928 | }; |
| 1996 | switch (splat) { | |
| 1997 | 0 => msg.iovlen = len - 1, | |
| 1998 | 1 => {}, | |
| 1999 | else => { | |
| 2000 | const pattern = data[data.len - 1]; | |
| 2001 | if (pattern.len == 1) { | |
| 2002 | const memset_len = @min(splat_buffer.len, splat); | |
| 2003 | const buf = splat_buffer[0..memset_len]; | |
| 2004 | @memset(buf, pattern[0]); | |
| 2005 | iovecs[len - 1] = .{ .base = buf.ptr, .len = buf.len }; | |
| 2006 | var remaining_splat = splat - buf.len; | |
| 2007 | while (remaining_splat > splat_buffer.len and len < iovecs.len) { | |
| 2008 | iovecs[len] = .{ .base = &splat_buffer, .len = splat_buffer.len }; | |
| 2009 | remaining_splat -= splat_buffer.len; | |
| 2010 | len += 1; | |
| 2011 | } | |
| 2012 | if (remaining_splat > 0 and len < iovecs.len) { | |
| 2013 | iovecs[len] = .{ .base = &splat_buffer, .len = remaining_splat }; | |
| 2014 | len += 1; | |
| 1929 | ||
| 1930 | pub fn interface(w: *Writer) std.io.Writer { | |
| 1931 | return switch (native_os) { | |
| 1932 | .windows => .{ | |
| 1933 | .context = w.impl.stream.handle, | |
| 1934 | .vtable = &.{ | |
| 1935 | .writeSplat = windows_writeSplat, | |
| 1936 | .writeFile = windows_writeFile, | |
| 1937 | }, | |
| 1938 | }, | |
| 1939 | else => .{ | |
| 1940 | .context = &w.impl, | |
| 1941 | .vtable = &.{ | |
| 1942 | .writeSplat = posix_writeSplat, | |
| 1943 | .writeFile = std.fs.File.Writer.writeFile, | |
| 1944 | }, | |
| 1945 | }, | |
| 1946 | }; | |
| 1947 | } | |
| 1948 | ||
| 1949 | fn windows_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 1950 | comptime assert(native_os == .windows); | |
| 1951 | if (data.len == 1 and splat == 0) return 0; | |
| 1952 | var splat_buffer: [256]u8 = undefined; | |
| 1953 | var iovecs: [max_buffers_len]windows.WSABUF = undefined; | |
| 1954 | var len: u32 = @min(iovecs.len, data.len); | |
| 1955 | for (iovecs[0..len], data[0..len]) |*v, d| v.* = .{ | |
| 1956 | .buf = if (d.len == 0) "" else d.ptr, // TODO: does Windows allow ptr=undefined len=0 ? | |
| 1957 | .len = d.len, | |
| 1958 | }; | |
| 1959 | switch (splat) { | |
| 1960 | 0 => len -= 1, | |
| 1961 | 1 => {}, | |
| 1962 | else => { | |
| 1963 | const pattern = data[data.len - 1]; | |
| 1964 | if (pattern.len == 1) { | |
| 1965 | const memset_len = @min(splat_buffer.len, splat); | |
| 1966 | const buf = splat_buffer[0..memset_len]; | |
| 1967 | @memset(buf, pattern[0]); | |
| 1968 | iovecs[len - 1] = .{ .base = buf.ptr, .len = buf.len }; | |
| 1969 | var remaining_splat = splat - buf.len; | |
| 1970 | while (remaining_splat > splat_buffer.len and len < iovecs.len) { | |
| 1971 | iovecs[len] = .{ .base = &splat_buffer, .len = splat_buffer.len }; | |
| 1972 | remaining_splat -= splat_buffer.len; | |
| 1973 | len += 1; | |
| 1974 | } | |
| 1975 | if (remaining_splat > 0 and len < iovecs.len) { | |
| 1976 | iovecs[len] = .{ .base = &splat_buffer, .len = remaining_splat }; | |
| 1977 | len += 1; | |
| 1978 | } | |
| 2015 | 1979 | } |
| 2016 | msg.iovlen = len; | |
| 2017 | } | |
| 2018 | }, | |
| 1980 | }, | |
| 1981 | } | |
| 1982 | var n: u32 = undefined; | |
| 1983 | const rc = windows.ws2_32.WSASend(context, &iovecs, len, &n, 0, null, null); | |
| 1984 | if (rc == windows.ws2_32.SOCKET_ERROR) switch (windows.ws2_32.WSAGetLastError()) { | |
| 1985 | .WSAECONNABORTED => return error.ConnectionResetByPeer, | |
| 1986 | .WSAECONNRESET => return error.ConnectionResetByPeer, | |
| 1987 | .WSAEFAULT => unreachable, // a pointer is not completely contained in user address space. | |
| 1988 | .WSAEINPROGRESS, .WSAEINTR => unreachable, // deprecated and removed in WSA 2.2 | |
| 1989 | .WSAEINVAL => return error.SocketNotBound, | |
| 1990 | .WSAEMSGSIZE => return error.MessageTooBig, | |
| 1991 | .WSAENETDOWN => return error.NetworkSubsystemFailed, | |
| 1992 | .WSAENETRESET => return error.ConnectionResetByPeer, | |
| 1993 | .WSAENOBUFS => return error.SystemResources, | |
| 1994 | .WSAENOTCONN => return error.SocketNotConnected, | |
| 1995 | .WSAENOTSOCK => unreachable, // not a socket | |
| 1996 | .WSAEOPNOTSUPP => unreachable, // only for message-oriented sockets | |
| 1997 | .WSAESHUTDOWN => unreachable, // cannot send on a socket after write shutdown | |
| 1998 | .WSAEWOULDBLOCK => return error.WouldBlock, | |
| 1999 | .WSANOTINITIALISED => unreachable, // WSAStartup must be called before this function | |
| 2000 | .WSA_IO_PENDING => unreachable, // not using overlapped I/O | |
| 2001 | .WSA_OPERATION_ABORTED => unreachable, // not using overlapped I/O | |
| 2002 | else => |err| return windows.unexpectedWSAError(err), | |
| 2003 | }; | |
| 2004 | return n; | |
| 2019 | 2005 | } |
| 2020 | const flags = posix.MSG.NOSIGNAL; | |
| 2021 | return std.posix.sendmsg(sock_fd, &msg, flags); | |
| 2022 | } | |
| 2023 | 2006 | |
| 2024 | fn windows_writeFile( | |
| 2025 | context: *anyopaque, | |
| 2026 | in_file: std.fs.File, | |
| 2027 | in_offset: u64, | |
| 2028 | in_len: std.io.Writer.FileLen, | |
| 2029 | headers_and_trailers: []const []const u8, | |
| 2030 | headers_len: usize, | |
| 2031 | ) std.io.Writer.FileError!usize { | |
| 2032 | const len_int = switch (in_len) { | |
| 2033 | .zero => return windows_writeSplat(context, headers_and_trailers, 1), | |
| 2034 | .entire_file => std.math.maxInt(usize), | |
| 2035 | else => in_len.int(), | |
| 2036 | }; | |
| 2037 | if (headers_len > 0) return windows_writeSplat(context, headers_and_trailers[0..headers_len], 1); | |
| 2038 | var file_contents_buffer: [4096]u8 = undefined; | |
| 2039 | const read_buffer = file_contents_buffer[0..@min(file_contents_buffer.len, len_int)]; | |
| 2040 | const n = try windows.ReadFile(in_file.handle, read_buffer, in_offset); | |
| 2041 | return windows_writeSplat(context, &.{read_buffer[0..n]}, 1); | |
| 2042 | } | |
| 2007 | fn posix_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | |
| 2008 | const fw: *std.fs.File.Writer = @alignCast(@ptrCast(context)); | |
| 2009 | const impl: *PosixImpl = @fieldParentPtr("fw", fw); | |
| 2010 | comptime assert(native_os != .windows); | |
| 2011 | var splat_buffer: [256]u8 = undefined; | |
| 2012 | var iovecs: [max_buffers_len]std.posix.iovec_const = undefined; | |
| 2013 | var len: usize = @min(iovecs.len, data.len); | |
| 2014 | for (iovecs[0..len], data[0..len]) |*v, d| v.* = .{ | |
| 2015 | .base = if (d.len == 0) "" else d.ptr, // OS sadly checks ptr addr before length. | |
| 2016 | .len = d.len, | |
| 2017 | }; | |
| 2018 | var msg: posix.msghdr_const = .{ | |
| 2019 | .name = null, | |
| 2020 | .namelen = 0, | |
| 2021 | .iov = &iovecs, | |
| 2022 | .iovlen = len, | |
| 2023 | .control = null, | |
| 2024 | .controllen = 0, | |
| 2025 | .flags = 0, | |
| 2026 | }; | |
| 2027 | switch (splat) { | |
| 2028 | 0 => msg.iovlen = len - 1, | |
| 2029 | 1 => {}, | |
| 2030 | else => { | |
| 2031 | const pattern = data[data.len - 1]; | |
| 2032 | if (pattern.len == 1) { | |
| 2033 | const memset_len = @min(splat_buffer.len, splat); | |
| 2034 | const buf = splat_buffer[0..memset_len]; | |
| 2035 | @memset(buf, pattern[0]); | |
| 2036 | iovecs[len - 1] = .{ .base = buf.ptr, .len = buf.len }; | |
| 2037 | var remaining_splat = splat - buf.len; | |
| 2038 | while (remaining_splat > splat_buffer.len and len < iovecs.len) { | |
| 2039 | iovecs[len] = .{ .base = &splat_buffer, .len = splat_buffer.len }; | |
| 2040 | remaining_splat -= splat_buffer.len; | |
| 2041 | len += 1; | |
| 2042 | } | |
| 2043 | if (remaining_splat > 0 and len < iovecs.len) { | |
| 2044 | iovecs[len] = .{ .base = &splat_buffer, .len = remaining_splat }; | |
| 2045 | len += 1; | |
| 2046 | } | |
| 2047 | msg.iovlen = len; | |
| 2048 | } | |
| 2049 | }, | |
| 2050 | } | |
| 2051 | const flags = posix.MSG.NOSIGNAL; | |
| 2052 | return std.posix.sendmsg(fw.file.handle, &msg, flags) catch |err| { | |
| 2053 | impl.err = err; | |
| 2054 | return error.WriteFailed; | |
| 2055 | }; | |
| 2056 | } | |
| 2043 | 2057 | |
| 2044 | const max_buffers_len = 8; | |
| 2058 | fn windows_writeFile( | |
| 2059 | context: *anyopaque, | |
| 2060 | in_file: std.fs.File, | |
| 2061 | in_offset: u64, | |
| 2062 | in_len: std.io.Writer.FileLen, | |
| 2063 | headers_and_trailers: []const []const u8, | |
| 2064 | headers_len: usize, | |
| 2065 | ) std.io.Writer.FileError!usize { | |
| 2066 | const len_int = switch (in_len) { | |
| 2067 | .zero => return windows_writeSplat(context, headers_and_trailers, 1), | |
| 2068 | .entire_file => std.math.maxInt(usize), | |
| 2069 | else => in_len.int(), | |
| 2070 | }; | |
| 2071 | if (headers_len > 0) return windows_writeSplat(context, headers_and_trailers[0..headers_len], 1); | |
| 2072 | var file_contents_buffer: [4096]u8 = undefined; | |
| 2073 | const read_buffer = file_contents_buffer[0..@min(file_contents_buffer.len, len_int)]; | |
| 2074 | const n = try windows.ReadFile(in_file.handle, read_buffer, in_offset); | |
| 2075 | return windows_writeSplat(context, &.{read_buffer[0..n]}, 1); | |
| 2076 | } | |
| 2077 | }; | |
| 2045 | 2078 | |
| 2046 | fn handleToOpaque(handle: Handle) ?*anyopaque { | |
| 2047 | return switch (@typeInfo(Handle)) { | |
| 2048 | .pointer => @ptrCast(handle), | |
| 2049 | .int => @ptrFromInt(@as(u32, @bitCast(handle))), | |
| 2050 | else => @compileError("unhandled"), | |
| 2079 | pub fn reader(stream: Stream) Reader { | |
| 2080 | return switch (native_os) { | |
| 2081 | .windows => .{ .impl = stream }, | |
| 2082 | else => .{ .impl = .{ | |
| 2083 | .fr = std.fs.File.reader(.{ .handle = stream.handle }), | |
| 2084 | .err = {}, | |
| 2085 | } }, | |
| 2051 | 2086 | }; |
| 2052 | 2087 | } |
| 2053 | 2088 | |
| 2054 | fn opaqueToHandle(userdata: ?*anyopaque) Handle { | |
| 2055 | return switch (@typeInfo(Handle)) { | |
| 2056 | .pointer => @ptrCast(userdata), | |
| 2057 | .int => @intCast(@intFromPtr(userdata)), | |
| 2058 | else => @compileError("unhandled"), | |
| 2089 | pub fn writer(stream: Stream) Writer { | |
| 2090 | return switch (native_os) { | |
| 2091 | .windows => .{ .impl = stream }, | |
| 2092 | else => .{ .impl = .{ | |
| 2093 | .fw = std.fs.File.writer(.{ .handle = stream.handle }), | |
| 2094 | .err = {}, | |
| 2095 | } }, | |
| 2059 | 2096 | }; |
| 2060 | 2097 | } |
| 2098 | ||
| 2099 | const max_buffers_len = 8; | |
| 2061 | 2100 | }; |
| 2062 | 2101 | |
| 2063 | 2102 | pub const Server = struct { |
lib/std/process.zig+6-6| ... | ... | @@ -1895,7 +1895,7 @@ pub fn createEnvironFromMap( |
| 1895 | 1895 | var i: usize = 0; |
| 1896 | 1896 | |
| 1897 | 1897 | if (zig_progress_action == .add) { |
| 1898 | envp_buf[i] = try std.fmt.allocPrintZ(arena, "ZIG_PROGRESS={d}", .{options.zig_progress_fd.?}); | |
| 1898 | envp_buf[i] = try std.fmt.allocPrintSentinel(arena, "ZIG_PROGRESS={d}", .{options.zig_progress_fd.?}, 0); | |
| 1899 | 1899 | i += 1; |
| 1900 | 1900 | } |
| 1901 | 1901 | |
| ... | ... | @@ -1906,16 +1906,16 @@ pub fn createEnvironFromMap( |
| 1906 | 1906 | .add => unreachable, |
| 1907 | 1907 | .delete => continue, |
| 1908 | 1908 | .edit => { |
| 1909 | envp_buf[i] = try std.fmt.allocPrintZ(arena, "{s}={d}", .{ | |
| 1909 | envp_buf[i] = try std.fmt.allocPrintSentinel(arena, "{s}={d}", .{ | |
| 1910 | 1910 | pair.key_ptr.*, options.zig_progress_fd.?, |
| 1911 | }); | |
| 1911 | }, 0); | |
| 1912 | 1912 | i += 1; |
| 1913 | 1913 | continue; |
| 1914 | 1914 | }, |
| 1915 | 1915 | .nothing => {}, |
| 1916 | 1916 | }; |
| 1917 | 1917 | |
| 1918 | envp_buf[i] = try std.fmt.allocPrintZ(arena, "{s}={s}", .{ pair.key_ptr.*, pair.value_ptr.* }); | |
| 1918 | envp_buf[i] = try std.fmt.allocPrintSentinel(arena, "{s}={s}", .{ pair.key_ptr.*, pair.value_ptr.* }, 0); | |
| 1919 | 1919 | i += 1; |
| 1920 | 1920 | } |
| 1921 | 1921 | } |
| ... | ... | @@ -1965,7 +1965,7 @@ pub fn createEnvironFromExisting( |
| 1965 | 1965 | var existing_index: usize = 0; |
| 1966 | 1966 | |
| 1967 | 1967 | if (zig_progress_action == .add) { |
| 1968 | envp_buf[i] = try std.fmt.allocPrintZ(arena, "ZIG_PROGRESS={d}", .{options.zig_progress_fd.?}); | |
| 1968 | envp_buf[i] = try std.fmt.allocPrintSentinel(arena, "ZIG_PROGRESS={d}", .{options.zig_progress_fd.?}, 0); | |
| 1969 | 1969 | i += 1; |
| 1970 | 1970 | } |
| 1971 | 1971 | |
| ... | ... | @@ -1974,7 +1974,7 @@ pub fn createEnvironFromExisting( |
| 1974 | 1974 | .add => unreachable, |
| 1975 | 1975 | .delete => continue, |
| 1976 | 1976 | .edit => { |
| 1977 | envp_buf[i] = try std.fmt.allocPrintZ(arena, "ZIG_PROGRESS={d}", .{options.zig_progress_fd.?}); | |
| 1977 | envp_buf[i] = try std.fmt.allocPrintSentinel(arena, "ZIG_PROGRESS={d}", .{options.zig_progress_fd.?}, 0); | |
| 1978 | 1978 | i += 1; |
| 1979 | 1979 | continue; |
| 1980 | 1980 | }, |
lib/std/process/Child.zig+7-7| ... | ... | @@ -1003,18 +1003,18 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { |
| 1003 | 1003 | } |
| 1004 | 1004 | |
| 1005 | 1005 | fn writeIntFd(fd: i32, value: ErrInt) !void { |
| 1006 | const file: File = .{ .handle = fd }; | |
| 1006 | var fw = std.fs.File.writer(.{ .handle = fd }); | |
| 1007 | 1007 | var buffer: [8]u8 = undefined; |
| 1008 | std.mem.writeInt(u64, &buffer, @intCast(value), .little); | |
| 1009 | file.writeAll(&buffer) catch return error.SystemResorces; | |
| 1008 | var bw = fw.interface().buffered(&buffer); | |
| 1009 | bw.writeInt(u64, value, .little) catch return error.SystemResources; | |
| 1010 | 1010 | } |
| 1011 | 1011 | |
| 1012 | 1012 | fn readIntFd(fd: i32) !ErrInt { |
| 1013 | const file: File = .{ .handle = fd }; | |
| 1013 | var fr = std.fs.File.reader(.{ .handle = fd }); | |
| 1014 | 1014 | var buffer: [8]u8 = undefined; |
| 1015 | const n = file.readAll(&buffer) catch return error.SystemResources; | |
| 1016 | if (n != buffer.len) return error.SystemResources; | |
| 1017 | return @intCast(std.mem.readInt(u64, &buffer, .little)); | |
| 1015 | var br: std.io.BufferedReader = undefined; | |
| 1016 | br.init(fr.interface(), &buffer); | |
| 1017 | return @intCast(br.takeInt(u64, .little) catch return error.SystemResources); | |
| 1018 | 1018 | } |
| 1019 | 1019 | |
| 1020 | 1020 | const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); |
lib/std/zig/ErrorBundle.zig+2-2| ... | ... | @@ -163,7 +163,7 @@ pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void { |
| 163 | 163 | renderToWriter(eb, options, bw) catch return; |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { | |
| 166 | pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) (std.io.Writer.Error || std.posix.UnexpectedError)!void { | |
| 167 | 167 | if (eb.extra.len == 0) return; |
| 168 | 168 | for (eb.getMessages()) |err_msg| { |
| 169 | 169 | try renderErrorMessageToWriter(eb, options, err_msg, bw, "error", .red, 0); |
| ... | ... | @@ -186,7 +186,7 @@ fn renderErrorMessageToWriter( |
| 186 | 186 | kind: []const u8, |
| 187 | 187 | color: std.io.tty.Color, |
| 188 | 188 | indent: usize, |
| 189 | ) std.io.Writer.Error!void { | |
| 189 | ) (std.io.Writer.Error || std.posix.UnexpectedError)!void { | |
| 190 | 190 | const ttyconf = options.ttyconf; |
| 191 | 191 | const err_msg = eb.getErrorMessage(err_msg_index); |
| 192 | 192 | const prefix_start = bw.count; |
src/Package/Fetch.zig+1-4| ... | ... | @@ -1367,10 +1367,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U |
| 1367 | 1367 | const index_prog_node = f.prog_node.start("Index pack", 0); |
| 1368 | 1368 | defer index_prog_node.end(); |
| 1369 | 1369 | var buffer: [4096]u8 = undefined; |
| 1370 | var index_buffered_writer: std.io.BufferedWriter = .{ | |
| 1371 | .unbuffered_writer = index_file.writer(), | |
| 1372 | .buffer = &buffer, | |
| 1373 | }; | |
| 1370 | var index_buffered_writer: std.io.BufferedWriter = index_file.writer().buffered(&buffer); | |
| 1374 | 1371 | try git.indexPack(gpa, object_format, pack_file, &index_buffered_writer); |
| 1375 | 1372 | try index_buffered_writer.flush(); |
| 1376 | 1373 | try index_file.sync(); |
src/dev.zig+4| ... | ... | @@ -78,6 +78,7 @@ pub const Env = enum { |
| 78 | 78 | .ast_gen, |
| 79 | 79 | .sema, |
| 80 | 80 | .legalize, |
| 81 | .c_compiler, | |
| 81 | 82 | .llvm_backend, |
| 82 | 83 | .c_backend, |
| 83 | 84 | .wasm_backend, |
| ... | ... | @@ -127,6 +128,7 @@ pub const Env = enum { |
| 127 | 128 | .clang_command, |
| 128 | 129 | .cc_command, |
| 129 | 130 | .translate_c_command, |
| 131 | .c_compiler, | |
| 130 | 132 | => true, |
| 131 | 133 | else => false, |
| 132 | 134 | }, |
| ... | ... | @@ -248,6 +250,8 @@ pub const Feature = enum { |
| 248 | 250 | sema, |
| 249 | 251 | legalize, |
| 250 | 252 | |
| 253 | c_compiler, | |
| 254 | ||
| 251 | 255 | llvm_backend, |
| 252 | 256 | c_backend, |
| 253 | 257 | wasm_backend, |
src/link/Elf/Atom.zig+14-17| ... | ... | @@ -1388,10 +1388,7 @@ const x86_64 = struct { |
| 1388 | 1388 | .{ .imm = .s(-129) }, |
| 1389 | 1389 | }, t) catch return false; |
| 1390 | 1390 | var buf: [std.atomic.cache_line]u8 = undefined; |
| 1391 | var bw: std.io.BufferedWriter = .{ | |
| 1392 | .unbuffered_writer = .null, | |
| 1393 | .buffer = &buf, | |
| 1394 | }; | |
| 1391 | var bw = std.io.Writer.null.buffered(&buf); | |
| 1395 | 1392 | inst.encode(&bw, .{}) catch return false; |
| 1396 | 1393 | return true; |
| 1397 | 1394 | }, |
| ... | ... | @@ -1599,7 +1596,7 @@ const aarch64 = struct { |
| 1599 | 1596 | const diags = &elf_file.base.comp.link_diags; |
| 1600 | 1597 | const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type()); |
| 1601 | 1598 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; |
| 1602 | const code = (try bw.writableSlice(4))[0..4]; | |
| 1599 | const code = try bw.writableArray(4); | |
| 1603 | 1600 | const file_ptr = atom.file(elf_file).?; |
| 1604 | 1601 | |
| 1605 | 1602 | const P, const A, const S, const GOT, const G, const TP, const DTP = args; |
| ... | ... | @@ -1626,7 +1623,7 @@ const aarch64 = struct { |
| 1626 | 1623 | const S_ = th.targetAddress(target_index, elf_file); |
| 1627 | 1624 | break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow; |
| 1628 | 1625 | }; |
| 1629 | aarch64_util.writeBranchImm(disp, (try bw.writableSlice(4))[0..4]); | |
| 1626 | aarch64_util.writeBranchImm(disp, code); | |
| 1630 | 1627 | }, |
| 1631 | 1628 | |
| 1632 | 1629 | .PREL32 => { |
| ... | ... | @@ -1897,26 +1894,26 @@ const riscv = struct { |
| 1897 | 1894 | |
| 1898 | 1895 | .HI20 => { |
| 1899 | 1896 | const value: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow); |
| 1900 | riscv_util.writeInstU((try bw.writableSlice(4))[0..4], value); | |
| 1897 | riscv_util.writeInstU(try bw.writableArray(4), value); | |
| 1901 | 1898 | }, |
| 1902 | 1899 | |
| 1903 | 1900 | .GOT_HI20 => { |
| 1904 | 1901 | assert(target.flags.has_got); |
| 1905 | 1902 | const disp: u32 = @bitCast(math.cast(i32, G + GOT + A - P) orelse return error.Overflow); |
| 1906 | riscv_util.writeInstU((try bw.writableSlice(4))[0..4], disp); | |
| 1903 | riscv_util.writeInstU(try bw.writableArray(4), disp); | |
| 1907 | 1904 | }, |
| 1908 | 1905 | |
| 1909 | 1906 | .CALL_PLT => { |
| 1910 | 1907 | // TODO: relax |
| 1911 | 1908 | const disp: u32 = @bitCast(math.cast(i32, S + A - P) orelse return error.Overflow); |
| 1912 | const code = (try bw.writableSlice(8))[0..8]; | |
| 1909 | const code = try bw.writableArray(8); | |
| 1913 | 1910 | riscv_util.writeInstU(code[0..4], disp); // auipc |
| 1914 | 1911 | riscv_util.writeInstI(code[4..8], disp); // jalr |
| 1915 | 1912 | }, |
| 1916 | 1913 | |
| 1917 | 1914 | .PCREL_HI20 => { |
| 1918 | 1915 | const disp: u32 = @bitCast(math.cast(i32, S + A - P) orelse return error.Overflow); |
| 1919 | riscv_util.writeInstU((try bw.writableSlice(4))[0..4], disp); | |
| 1916 | riscv_util.writeInstU(try bw.writableArray(4), disp); | |
| 1920 | 1917 | }, |
| 1921 | 1918 | |
| 1922 | 1919 | .PCREL_LO12_I, |
| ... | ... | @@ -1954,8 +1951,8 @@ const riscv = struct { |
| 1954 | 1951 | }; |
| 1955 | 1952 | relocs_log.debug(" [{x} => {x}]", .{ P_, disp + P_ }); |
| 1956 | 1953 | switch (r_type) { |
| 1957 | .PCREL_LO12_I => riscv_util.writeInstI((try bw.writableSlice(4))[0..4], @bitCast(disp)), | |
| 1958 | .PCREL_LO12_S => riscv_util.writeInstS((try bw.writableSlice(4))[0..4], @bitCast(disp)), | |
| 1954 | .PCREL_LO12_I => riscv_util.writeInstI(try bw.writableArray(4), @bitCast(disp)), | |
| 1955 | .PCREL_LO12_S => riscv_util.writeInstS(try bw.writableArray(4), @bitCast(disp)), | |
| 1959 | 1956 | else => unreachable, |
| 1960 | 1957 | } |
| 1961 | 1958 | }, |
| ... | ... | @@ -1965,8 +1962,8 @@ const riscv = struct { |
| 1965 | 1962 | => { |
| 1966 | 1963 | const disp: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow); |
| 1967 | 1964 | switch (r_type) { |
| 1968 | .LO12_I => riscv_util.writeInstI((try bw.writableSlice(4))[0..4], disp), | |
| 1969 | .LO12_S => riscv_util.writeInstS((try bw.writableSlice(4))[0..4], disp), | |
| 1965 | .LO12_I => riscv_util.writeInstI(try bw.writableArray(4), disp), | |
| 1966 | .LO12_S => riscv_util.writeInstS(try bw.writableArray(4), disp), | |
| 1970 | 1967 | else => unreachable, |
| 1971 | 1968 | } |
| 1972 | 1969 | }, |
| ... | ... | @@ -1974,7 +1971,7 @@ const riscv = struct { |
| 1974 | 1971 | .TPREL_HI20 => { |
| 1975 | 1972 | const target_addr: u32 = @intCast(target.address(.{}, elf_file)); |
| 1976 | 1973 | const val: i32 = @intCast(S + A - target_addr); |
| 1977 | riscv_util.writeInstU((try bw.writableSlice(4))[0..4], @bitCast(val)); | |
| 1974 | riscv_util.writeInstU(try bw.writableArray(4), @bitCast(val)); | |
| 1978 | 1975 | }, |
| 1979 | 1976 | |
| 1980 | 1977 | .TPREL_LO12_I, |
| ... | ... | @@ -1983,8 +1980,8 @@ const riscv = struct { |
| 1983 | 1980 | const target_addr: u32 = @intCast(target.address(.{}, elf_file)); |
| 1984 | 1981 | const val: i32 = @intCast(S + A - target_addr); |
| 1985 | 1982 | switch (r_type) { |
| 1986 | .TPREL_LO12_I => riscv_util.writeInstI((try bw.writableSlice(4))[0..4], @bitCast(val)), | |
| 1987 | .TPREL_LO12_S => riscv_util.writeInstS((try bw.writableSlice(4))[0..4], @bitCast(val)), | |
| 1983 | .TPREL_LO12_I => riscv_util.writeInstI(try bw.writableArray(4), @bitCast(val)), | |
| 1984 | .TPREL_LO12_S => riscv_util.writeInstS(try bw.writableArray(4), @bitCast(val)), | |
| 1988 | 1985 | else => unreachable, |
| 1989 | 1986 | } |
| 1990 | 1987 | }, |
src/link/MachO/dyld_info/Trie.zig+1-4| ... | ... | @@ -185,10 +185,7 @@ const FinalizeNodeResult = struct { |
| 185 | 185 | /// Updates offset of this node in the output byte stream. |
| 186 | 186 | fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult { |
| 187 | 187 | var buf: [1024]u8 = undefined; |
| 188 | var bw: std.io.BufferedWriter = .{ | |
| 189 | .unbuffered_writer = .null, | |
| 190 | .buffer = &buf, | |
| 191 | }; | |
| 188 | var bw = std.io.Writer.null.buffered(&buf); | |
| 192 | 189 | const slice = self.nodes.slice(); |
| 193 | 190 | |
| 194 | 191 | var node_size: u32 = 0; |
src/link/riscv.zig+3-3| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { |
| 2 | 2 | const mask: u8 = 0b11_000000; |
| 3 | 3 | const actual: i8 = @truncate(addend); |
| 4 | const old_value = (try bw.writableSlice(1))[0]; | |
| 4 | const old_value = (try bw.writableArray(1))[0]; | |
| 5 | 5 | const new_value = (old_value & mask) | (@as(u8, switch (op) { |
| 6 | 6 | .set => @bitCast(actual), |
| 7 | 7 | .sub => @bitCast(@as(i8, @bitCast(old_value)) -| actual), |
| ... | ... | @@ -14,7 +14,7 @@ pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io. |
| 14 | 14 | .set => try overwriteUleb(@intCast(addend), bw), |
| 15 | 15 | .sub => { |
| 16 | 16 | var br: std.io.BufferedReader = undefined; |
| 17 | br.initFixed(try bw.writableSlice(1)); | |
| 17 | br.initFixed(try bw.writableArray(1)); | |
| 18 | 18 | const old_value = try br.takeLeb128(u64); |
| 19 | 19 | try overwriteUleb(old_value -% @as(u64, @intCast(addend)), bw); |
| 20 | 20 | }, |
| ... | ... | @@ -24,7 +24,7 @@ pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io. |
| 24 | 24 | fn overwriteUleb(new_value: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void { |
| 25 | 25 | var value: u64 = new_value; |
| 26 | 26 | while (true) { |
| 27 | const byte = (try bw.writableSlice(1))[0]; | |
| 27 | const byte = (try bw.writableArray(1))[0]; | |
| 28 | 28 | try bw.writeByte((byte & 0x80) | @as(u7, @truncate(value))); |
| 29 | 29 | if (byte & 0x80 == 0) break; |
| 30 | 30 | value >>= 7; |
src/main.zig+13-2| ... | ... | @@ -1808,6 +1808,7 @@ fn buildOutputType( |
| 1808 | 1808 | } else manifest_file = arg; |
| 1809 | 1809 | }, |
| 1810 | 1810 | .assembly, .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .ll, .bc, .m, .mm => { |
| 1811 | dev.check(.c_compiler); | |
| 1811 | 1812 | try create_module.c_source_files.append(arena, .{ |
| 1812 | 1813 | // Populated after module creation. |
| 1813 | 1814 | .owner = undefined, |
| ... | ... | @@ -1818,6 +1819,7 @@ fn buildOutputType( |
| 1818 | 1819 | }); |
| 1819 | 1820 | }, |
| 1820 | 1821 | .rc => { |
| 1822 | dev.check(.win32_resource); | |
| 1821 | 1823 | try create_module.rc_source_files.append(arena, .{ |
| 1822 | 1824 | // Populated after module creation. |
| 1823 | 1825 | .owner = undefined, |
| ... | ... | @@ -3303,6 +3305,7 @@ fn buildOutputType( |
| 3303 | 3305 | defer thread_pool.deinit(); |
| 3304 | 3306 | |
| 3305 | 3307 | for (create_module.c_source_files.items) |*src| { |
| 3308 | dev.check(.c_compiler); | |
| 3306 | 3309 | if (!mem.eql(u8, src.src_path, "-")) continue; |
| 3307 | 3310 | |
| 3308 | 3311 | const ext = src.ext orelse |
| ... | ... | @@ -5008,7 +5011,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5008 | 5011 | var http_client: if (dev.env.supports(.fetch_command)) std.http.Client else struct { |
| 5009 | 5012 | allocator: Allocator, |
| 5010 | 5013 | fn deinit(_: @This()) void {} |
| 5011 | } = .{ .allocator = gpa }; | |
| 5014 | } = .{ | |
| 5015 | .allocator = gpa, | |
| 5016 | .read_buffer_size = 0x4000, | |
| 5017 | .write_buffer_size = 0x4000, | |
| 5018 | }; | |
| 5012 | 5019 | defer http_client.deinit(); |
| 5013 | 5020 | |
| 5014 | 5021 | var unlazy_set: Package.Fetch.JobQueue.UnlazySet = .{}; |
| ... | ... | @@ -6815,7 +6822,11 @@ fn cmdFetch( |
| 6815 | 6822 | try thread_pool.init(.{ .allocator = gpa }); |
| 6816 | 6823 | defer thread_pool.deinit(); |
| 6817 | 6824 | |
| 6818 | var http_client: std.http.Client = .{ .allocator = gpa }; | |
| 6825 | var http_client: std.http.Client = .{ | |
| 6826 | .allocator = gpa, | |
| 6827 | .read_buffer_size = 0x4000, | |
| 6828 | .write_buffer_size = 0x4000, | |
| 6829 | }; | |
| 6819 | 6830 | defer http_client.deinit(); |
| 6820 | 6831 | |
| 6821 | 6832 | try http_client.initDefaultProxies(arena); |