authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-17 12:29:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:27-07:00
logffb0e283d7aaaa896cd3db32ca11460ea63c8855
treec12b079906590b17d1edd0394b92ee4aa10c4ba7
parent3b390e4f139220ed11918524288238c289ce0c6d

build_runner: fix compile errors


27 files changed, 463 insertions(+), 362 deletions(-)

lib/compiler/build_runner.zig+15-17
......@@ -379,9 +379,11 @@ pub fn main() !void {
379379 validateSystemLibraryOptions(builder);
380380
381381 {
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);
385387 }
386388
387389 var run: Run = .{
......@@ -694,16 +696,13 @@ fn runStepNames(
694696 const ttyconf = run.ttyconf;
695697
696698 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();
702701
703702 const total_count = success_count + failure_count + pending_count + skipped_count;
704 ttyconf.setColor(&bw, .cyan) catch {};
703 ttyconf.setColor(bw, .cyan) catch {};
705704 bw.writeAll("Build Summary:") catch {};
706 ttyconf.setColor(&bw, .reset) catch {};
705 ttyconf.setColor(bw, .reset) catch {};
707706 bw.print(" {d}/{d} steps succeeded", .{ success_count, total_count }) catch {};
708707 if (skipped_count > 0) bw.print("; {d} skipped", .{skipped_count}) catch {};
709708 if (failure_count > 0) bw.print("; {d} failed", .{failure_count}) catch {};
......@@ -713,8 +712,6 @@ fn runStepNames(
713712 if (test_fail_count > 0) bw.print("; {d} failed", .{test_fail_count}) catch {};
714713 if (test_leak_count > 0) bw.print("; {d} leaked", .{test_leak_count}) catch {};
715714
716 bw.writeByte('\n') catch {};
717
718715 // Print a fancy tree with build results.
719716 var step_stack_copy = try step_stack.clone(gpa);
720717 defer step_stack_copy.deinit(gpa);
......@@ -722,7 +719,7 @@ fn runStepNames(
722719 var print_node: PrintNode = .{ .parent = null };
723720 if (step_names.len == 0) {
724721 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 {};
726723 } else {
727724 const last_index = if (run.summary == .all) b.top_level_steps.count() else blk: {
728725 var i: usize = step_names.len;
......@@ -741,9 +738,10 @@ fn runStepNames(
741738 for (step_names, 0..) |step_name, i| {
742739 const tls = b.top_level_steps.get(step_name).?;
743740 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 {};
745742 }
746743 }
744 bw.writeByte('\n') catch {};
747745 }
748746
749747 if (failure_count == 0) {
......@@ -1129,11 +1127,11 @@ fn workerMakeOneStep(
11291127 const show_stderr = s.result_stderr.len > 0;
11301128
11311129 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();
11341132
11351133 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 {};
11371135 }
11381136
11391137 handle_result: {
lib/std/Build.zig+11-11
......@@ -2766,7 +2766,7 @@ fn dumpBadDirnameHelp(
27662766 comptime msg: []const u8,
27672767 args: anytype,
27682768) anyerror!void {
2769 const w = debug.lockStderrWriter();
2769 const w = debug.lockStderrWriter(&.{});
27702770 defer debug.unlockStderrWriter();
27712771
27722772 const stderr: fs.File = .stderr();
......@@ -2802,9 +2802,9 @@ pub fn dumpBadGetPathHelp(
28022802 src_builder: *Build,
28032803 asking_step: ?*Step,
28042804) 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(
28082808 \\getPath() was called on a GeneratedFile that wasn't built yet.
28092809 \\ source package path: {s}
28102810 \\ Is there a missing Step dependency on step '{s}'?
......@@ -2815,21 +2815,21 @@ pub fn dumpBadGetPathHelp(
28152815 });
28162816
28172817 const tty_config = std.io.tty.detectConfig(stderr);
2818 tty_config.setColor(w, .red) catch {};
2818 tty_config.setColor(&bw, .red) catch {};
28192819 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 {};
28212821
28222822 s.dump(stderr);
28232823 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 {};
28272827
28282828 as.dump(stderr);
28292829 }
2830 tty_config.setColor(w, .red) catch {};
2830 tty_config.setColor(&bw, .red) catch {};
28312831 try stderr.writeAll(" Hope that helps. Proceeding to panic.\n");
2832 tty_config.setColor(w, .reset) catch {};
2832 tty_config.setColor(&bw, .reset) catch {};
28332833}
28342834
28352835pub const InstallDir = union(enum) {
lib/std/Build/Cache.zig+4-3
......@@ -68,7 +68,7 @@ const PrefixedPath = struct {
6868
6969fn findPrefix(cache: *const Cache, file_path: []const u8) !PrefixedPath {
7070 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});
7272 errdefer gpa.free(resolved_path);
7373 return findPrefixResolved(cache, resolved_path);
7474}
......@@ -132,7 +132,7 @@ pub const Hasher = crypto.auth.siphash.SipHash128(1, 3);
132132/// Initial state with random bytes, that can be copied.
133133/// Refresh this with new random bytes when the manifest
134134/// format is modified in a non-backwards-compatible way.
135pub const hasher_init: Hasher = Hasher.init(&[_]u8{
135pub const hasher_init: Hasher = Hasher.init(&.{
136136 0x33, 0x52, 0xa2, 0x84,
137137 0xcf, 0x17, 0x56, 0x57,
138138 0x01, 0xbb, 0xcd, 0xe4,
......@@ -1143,7 +1143,8 @@ pub const Manifest = struct {
11431143 }
11441144
11451145 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);
11471148 }
11481149
11491150 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
124124 const show_stderr = compile.step.result_stderr.len > 0;
125125
126126 if (show_error_msgs or show_compile_errors or show_stderr) {
127 const bw = std.debug.lockStderrWriter();
127 const bw = std.debug.lockStderrWriter(&.{});
128128 defer std.debug.unlockStderrWriter();
129129 build_runner.printErrorMessages(gpa, &compile.step, .{ .ttyconf = ttyconf }, bw, false) catch {};
130130 }
......@@ -151,7 +151,7 @@ fn fuzzWorkerRun(
151151
152152 run.rerunInFuzzMode(web_server, unit_test_index, prog_node) catch |err| switch (err) {
153153 error.MakeFailed => {
154 const bw = std.debug.lockStderrWriter();
154 const bw = std.debug.lockStderrWriter(&.{});
155155 defer std.debug.unlockStderrWriter();
156156 build_runner.printErrorMessages(gpa, &run.step, .{ .ttyconf = ttyconf }, bw, false) catch {};
157157 return;
lib/std/Build/Fuzz/WebServer.zig+10-2
......@@ -98,8 +98,16 @@ fn now(s: *const WebServer) i64 {
9898fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {
9999 defer connection.stream.close();
100100
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);
103111 var web_socket: std.http.WebSocket = undefined;
104112 var send_buffer: [0x4000]u8 = undefined;
105113 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 {
287287
288288/// For debugging purposes, prints identifying information about this Step.
289289pub 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();
291292 const tty_config = std.io.tty.detectConfig(file);
292293 const debug_info = std.debug.getSelfDebugInfo() catch |err| {
293294 bw.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{
......@@ -469,7 +470,7 @@ pub fn evalZigProcess(
469470 // This is intentionally printed for failure on the first build but not for
470471 // subsequent rebuilds.
471472 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}", .{
473474 s.result_error_bundle.errorMessageCount(),
474475 try allocPrintCmd(arena, null, argv),
475476 });
......@@ -689,7 +690,7 @@ pub inline fn handleChildProcUnsupported(
689690) error{ OutOfMemory, MakeFailed }!void {
690691 if (!std.process.can_spawn) {
691692 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}",
693694 .{try allocPrintCmd(s.owner.allocator, opt_cwd, argv)},
694695 );
695696 }
......@@ -706,14 +707,14 @@ pub fn handleChildProcessTerm(
706707 .Exited => |code| {
707708 if (code != 0) {
708709 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}",
710711 .{ code, try allocPrintCmd(arena, opt_cwd, argv) },
711712 );
712713 }
713714 },
714715 .Signal, .Stopped, .Unknown => {
715716 return s.fail(
716 "the following command terminated unexpectedly:\n{s}\n",
717 "the following command terminated unexpectedly:\n{s}",
717718 .{try allocPrintCmd(arena, opt_cwd, argv)},
718719 );
719720 },
lib/std/Build/Step/CheckObject.zig+1-1
......@@ -1791,7 +1791,7 @@ const ElfDumper = struct {
17911791 .p64 => @sizeOf(u64),
17921792 };
17931793 try br.discard(num * ptr_size);
1794 const strtab = try br.peekAll(0);
1794 const strtab = try br.peekGreedy(0);
17951795
17961796 assert(ctx.symtab.len == 0);
17971797 ctx.symtab = try ctx.gpa.alloc(ArSymtabEntry, num);
lib/std/Build/Step/Run.zig+14-7
......@@ -73,9 +73,12 @@ skip_foreign_checks: bool,
7373/// external executor (such as qemu) but not fail if the executor is unavailable.
7474failing_to_execute_foreign_is_an_error: bool,
7575
76/// Deprecated for `stdio_limit`.
77max_stdio_size: usize,
78
7679/// If stderr or stdout exceeds this amount, the child process is killed and
7780/// the step fails.
78max_stdio_size: usize,
81stdio_limit: std.io.Reader.Limit,
7982
8083captured_stdout: ?*Output,
8184captured_stderr: ?*Output,
......@@ -186,6 +189,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
186189 .skip_foreign_checks = false,
187190 .failing_to_execute_foreign_is_an_error = true,
188191 .max_stdio_size = 10 * 1024 * 1024,
192 .stdio_limit = .unlimited,
189193 .captured_stdout = null,
190194 .captured_stderr = null,
191195 .dep_output_file = null,
......@@ -1772,6 +1776,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
17721776 var stdout_bytes: ?[]const u8 = null;
17731777 var stderr_bytes: ?[]const u8 = null;
17741778
1779 run.stdio_limit = .limited(run.stdio_limit.min(run.max_stdio_size));
17751780 if (child.stdout) |stdout| {
17761781 if (child.stderr) |stderr| {
17771782 var poller = std.io.poll(arena, enum { stdout, stderr }, .{
......@@ -1781,19 +1786,21 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
17811786 defer poller.deinit();
17821787
17831788 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 }
17881795 }
17891796
17901797 stdout_bytes = try poller.fifo(.stdout).toOwnedSlice();
17911798 stderr_bytes = try poller.fifo(.stderr).toOwnedSlice();
17921799 } else {
1793 stdout_bytes = try stdout.reader().readAlloc(arena, run.max_stdio_size);
1800 stdout_bytes = try stdout.readToEndAlloc(arena, run.stdio_limit);
17941801 }
17951802 } 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);
17971804 }
17981805
17991806 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)
239239 return State.hash(msg, key);
240240 }
241241
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 }
244251
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;
248260 }
249261
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;
252277 }
253278 };
254279}
lib/std/fs/Dir.zig+1-1
......@@ -2052,7 +2052,7 @@ pub fn readFileIntoArrayList(
20522052 try list.ensureUnusedCapacity(gpa, std.math.cast(usize, size) orelse return error.FileTooBig);
20532053 } else |err| switch (err) {
20542054 // 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 => {},
20562056 else => |e| return e,
20572057 }
20582058
lib/std/http/Client.zig+2-2
......@@ -115,14 +115,14 @@ pub const ConnectionPool = struct {
115115 ///
116116 /// Threadsafe.
117117 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();
119119
120120 pool.mutex.lock();
121121 defer pool.mutex.unlock();
122122
123123 pool.used.remove(&connection.pool_node);
124124
125 if (pool.free_size == 0) return connection.destroy(allocator);
125 if (pool.free_size == 0) return connection.destroy();
126126
127127 if (pool.free_len >= pool.free_size) {
128128 const popped: *Connection = @fieldParentPtr("pool_node", pool.free.popFirst().?);
lib/std/http/Server.zig+42-30
......@@ -21,6 +21,9 @@ out: *std.io.BufferedWriter,
2121state: State,
2222head_parse_err: Request.Head.ParseError,
2323
24/// being deleted...
25next_request_start: usize = 0,
26
2427pub const State = enum {
2528 /// The connection is available to be used for the first time, or reused.
2629 ready,
......@@ -45,6 +48,7 @@ pub fn init(in: *std.io.BufferedReader, out: *std.io.BufferedWriter) Server {
4548 .in = in,
4649 .out = out,
4750 .state = .ready,
51 .head_parse_err = undefined,
4852 };
4953}
5054
......@@ -63,7 +67,7 @@ pub const ReceiveHeadError = error{
6367 /// In other words, a keep-alive connection was finally closed.
6468 HttpConnectionClosing,
6569 /// Transitive error occurred reading from `in`.
66 ReadFailure,
70 ReadFailed,
6771};
6872
6973/// The header bytes reference the internal storage of `in`, which are
......@@ -73,7 +77,7 @@ pub fn receiveHead(s: *Server) ReceiveHeadError!Request {
7377 s.state = .received_head;
7478 errdefer s.state = .receiving_head;
7579
76 const in = &s.in;
80 const in = s.in;
7781 var hp: http.HeadParser = .{};
7882 var head_end: usize = 0;
7983
......@@ -84,7 +88,7 @@ pub fn receiveHead(s: *Server) ReceiveHeadError!Request {
8488 0 => return error.HttpConnectionClosing,
8589 else => return error.HttpRequestTruncated,
8690 },
87 error.ReadFailure => return error.ReadFailure,
91 error.ReadFailed => return error.ReadFailed,
8892 };
8993 head_end += hp.feed(buf[head_end..]);
9094 if (hp.state == .finished) return .{
......@@ -279,7 +283,7 @@ pub const Request = struct {
279283 };
280284
281285 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]);
283287 }
284288
285289 test iterateHeaders {
......@@ -398,8 +402,7 @@ pub const Request = struct {
398402 h.appendSliceAssumeCapacity("HTTP/1.1 417 Expectation Failed\r\n");
399403 if (!keep_alive) h.appendSliceAssumeCapacity("connection: close\r\n");
400404 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);
403406 return;
404407 }
405408 h.printAssumeCapacity("{s} {d} {s}\r\n", .{
......@@ -472,8 +475,7 @@ pub const Request = struct {
472475 }
473476 }
474477
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]);
477479 }
478480
479481 pub const RespondStreamingOptions = struct {
......@@ -553,7 +555,7 @@ pub const Request = struct {
553555 };
554556
555557 return .{
556 .stream = request.server.connection.stream,
558 .out = request.server.out,
557559 .send_buffer = options.send_buffer,
558560 .send_buffer_start = 0,
559561 .send_buffer_end = h.items.len,
......@@ -577,7 +579,7 @@ pub const Request = struct {
577579 ctx: ?*anyopaque,
578580 bw: *std.io.BufferedWriter,
579581 limit: std.io.Reader.Limit,
580 ) std.io.Reader.Error!std.io.Reader.Status {
582 ) std.io.Reader.Error!usize {
581583 const request: *Request = @alignCast(@ptrCast(ctx));
582584 _ = request;
583585 _ = bw;
......@@ -585,13 +587,20 @@ pub const Request = struct {
585587 @panic("TODO");
586588 }
587589
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 {
589591 const request: *Request = @alignCast(@ptrCast(ctx));
590592 _ = request;
591593 _ = data;
592594 @panic("TODO");
593595 }
594596
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
595604 fn chunkedReader_read(
596605 ctx: ?*anyopaque,
597606 bw: *std.io.BufferedWriter,
......@@ -604,13 +613,20 @@ pub const Request = struct {
604613 @panic("TODO");
605614 }
606615
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 {
608617 const request: *Request = @alignCast(@ptrCast(ctx));
609618 _ = request;
610619 _ = data;
611620 @panic("TODO");
612621 }
613622
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
614630 fn read_cl(context: *const anyopaque, buffer: []u8) ReadError!usize {
615631 const request: *Request = @alignCast(@ptrCast(context));
616632 const s = request.server;
......@@ -751,8 +767,7 @@ pub const Request = struct {
751767
752768 if (request.head.expect) |expect| {
753769 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");
756771 request.head.expect = null;
757772 } else {
758773 return error.HttpExpectationFailed;
......@@ -766,7 +781,8 @@ pub const Request = struct {
766781 .context = request,
767782 .vtable = &.{
768783 .read = &chunkedReader_read,
769 .readv = &chunkedReader_readv,
784 .readVec = &chunkedReader_readVec,
785 .discard = &chunkedReader_discard,
770786 },
771787 };
772788 },
......@@ -778,7 +794,8 @@ pub const Request = struct {
778794 .context = request,
779795 .vtable = &.{
780796 .read = &contentLengthReader_read,
781 .readv = &contentLengthReader_readv,
797 .readVec = &contentLengthReader_readVec,
798 .discard = &contentLengthReader_discard,
782799 },
783800 };
784801 },
......@@ -801,7 +818,7 @@ pub const Request = struct {
801818 if (keep_alive and request.head.keep_alive) switch (s.state) {
802819 .received_head => {
803820 const r = request.reader() catch return false;
804 _ = r.discardUntilEnd() catch return false;
821 _ = r.discardRemaining() catch return false;
805822 assert(s.state == .ready);
806823 return true;
807824 },
......@@ -819,7 +836,7 @@ pub const Request = struct {
819836};
820837
821838pub const Response = struct {
822 stream: net.Stream,
839 out: *std.io.BufferedWriter,
823840 send_buffer: []u8,
824841 /// Index of the first byte in `send_buffer`.
825842 /// This is 0 unless a short write happens in `write`.
......@@ -909,7 +926,7 @@ pub const Response = struct {
909926 _ = limit;
910927 _ = headers_and_trailers;
911928 _ = headers_len;
912 return error.Unimplemented;
929 @panic("TODO");
913930 }
914931
915932 fn cl_write(context: ?*anyopaque, bytes: []const u8) std.io.Writer.Error!usize {
......@@ -932,8 +949,7 @@ pub const Response = struct {
932949 r.send_buffer[r.send_buffer_start..][0..send_buffer_len],
933950 bytes,
934951 };
935 var w = r.stream.writer().unbuffered();
936 const n = try w.writev(&iovecs);
952 const n = try r.out.writeVec(&iovecs);
937953
938954 if (n >= send_buffer_len) {
939955 // It was enough to reset the buffer.
......@@ -976,7 +992,7 @@ pub const Response = struct {
976992 _ = limit;
977993 _ = headers_and_trailers;
978994 _ = 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
980996 }
981997
982998 fn chunked_write(context: ?*anyopaque, bytes: []const u8) std.io.Writer.Error!usize {
......@@ -1001,8 +1017,7 @@ pub const Response = struct {
10011017 };
10021018 // TODO make this writev instead of writevAll, which involves
10031019 // complicating the logic of this function.
1004 var w = r.stream.writer().unbuffered();
1005 try w.writevAll(&iovecs);
1020 try r.out.writeVecAll(&iovecs);
10061021 r.send_buffer_start = 0;
10071022 r.send_buffer_end = 0;
10081023 r.chunk_len = 0;
......@@ -1036,8 +1051,7 @@ pub const Response = struct {
10361051 }
10371052
10381053 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]);
10411055 r.send_buffer_start = 0;
10421056 r.send_buffer_end = 0;
10431057 }
......@@ -1050,8 +1064,7 @@ pub const Response = struct {
10501064 const http_headers = r.send_buffer[r.send_buffer_start .. r.send_buffer_end - r.chunk_len];
10511065
10521066 if (r.elide_body) {
1053 var w = r.stream.writer().unbuffered();
1054 try w.writeAll(http_headers);
1067 try r.out.writeAll(http_headers);
10551068 r.send_buffer_start = 0;
10561069 r.send_buffer_end = 0;
10571070 r.chunk_len = 0;
......@@ -1102,8 +1115,7 @@ pub const Response = struct {
11021115 iovecs_len += 1;
11031116 }
11041117
1105 var w = r.stream.writer().unbuffered();
1106 try w.writevAll(iovecs[0..iovecs_len]);
1118 try r.out.writeVecAll(iovecs[0..iovecs_len]);
11071119 r.send_buffer_start = 0;
11081120 r.send_buffer_end = 0;
11091121 r.chunk_len = 0;
lib/std/http/WebSocket.zig+2-4
......@@ -194,16 +194,14 @@ fn recvReadInt(ws: *WebSocket, comptime I: type) !I {
194194 };
195195}
196196
197pub const WriteError = std.http.Server.Response.WriteError;
198
199pub fn writeMessage(ws: *WebSocket, message: []const u8, opcode: Opcode) WriteError!void {
197pub fn writeMessage(ws: *WebSocket, message: []const u8, opcode: Opcode) std.io.Writer.Error!void {
200198 const iovecs: [1]std.posix.iovec_const = .{
201199 .{ .base = message.ptr, .len = message.len },
202200 };
203201 return writeMessagev(ws, &iovecs, opcode);
204202}
205203
206pub fn writeMessagev(ws: *WebSocket, message: []const std.posix.iovec_const, opcode: Opcode) WriteError!void {
204pub fn writeMessagev(ws: *WebSocket, message: []const std.posix.iovec_const, opcode: Opcode) std.io.Writer.Error!void {
207205 const total_len = l: {
208206 var total_len: u64 = 0;
209207 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) {
9393}
9494
9595pub 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);
9998}
10099
101100pub 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 {
9797 br.seek = seek;
9898}
9999
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
101101/// necessary.
102102///
103103/// Invalidates previously returned values from `peek`.
104104///
105105/// Asserts that the `BufferedReader` was initialized with a buffer capacity at
106/// least as big as `n`.
106/// least as big as `len`.
107107///
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`
109109/// is returned instead.
110110///
111111/// See also:
112/// * `peekGreedy`
112/// * `peek`
113/// * `tryPeekArray`
113114/// * `toss`
114115pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {
115116 const storage = &br.storage;
......@@ -119,18 +120,19 @@ pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {
119120}
120121
121122/// 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.
123124///
124125/// Invalidates previously returned values from `peek` and `peekGreedy`.
125126///
126127/// Asserts that the `BufferedReader` was initialized with a buffer capacity at
127/// least as big as `n`.
128/// least as big as `min_len`.
128129///
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`
130131/// is returned instead.
131132///
132133/// See also:
133134/// * `peek`
135/// * `tryPeekGreedy`
134136/// * `toss`
135137pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {
136138 const storage = &br.storage;
......@@ -214,7 +216,7 @@ pub fn discardShort(br: *BufferedReader, n: usize) Reader.ShortError!usize {
214216 storage.end = 0;
215217 br.seek = 0;
216218 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) {
218220 error.EndOfStream => return n - remaining,
219221 error.ReadFailed => return error.ReadFailed,
220222 };
......@@ -564,7 +566,7 @@ pub inline fn takeStructEndian(br: *BufferedReader, comptime T: type, endian: st
564566/// it. Otherwise, returns `error.InvalidEnumTag`.
565567///
566568/// Asserts the buffer was initialized with a capacity at least `@sizeOf(Enum)`.
567pub fn takeEnum(br: *BufferedReader, comptime Enum: type, endian: std.builtin.Endian) Reader.Error!Enum {
569pub fn takeEnum(br: *BufferedReader, comptime Enum: type, endian: std.builtin.Endian) (Reader.Error || std.meta.IntToEnumError)!Enum {
568570 const Tag = @typeInfo(Enum).@"enum".tag_type;
569571 const int = try br.takeInt(Tag, endian);
570572 return std.meta.intToEnum(Enum, int);
lib/std/io/BufferedWriter.zig+5
......@@ -83,6 +83,11 @@ pub fn unusedCapacitySlice(bw: *const BufferedWriter) []u8 {
8383 return bw.buffer[bw.end..];
8484}
8585
86/// Asserts the provided buffer has total capacity enough for `len`.
87pub fn writableArray(bw: *BufferedWriter, comptime len: usize) anyerror!*[len]u8 {
88 return (try bw.writableSlice(len))[0..len];
89}
90
8691/// Asserts the provided buffer has total capacity enough for `minimum_length`.
8792pub fn writableSlice(bw: *BufferedWriter, minimum_length: usize) Writer.Error![]u8 {
8893 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 {
66 comptime var ErrSet = error{};
77 inline for (@typeInfo(Writers).@"struct".fields) |field| {
88 const StreamType = field.type;
9 ErrSet = ErrSet || StreamType.Error;
9 ErrSet = ErrSet || if (@hasDecl(StreamType, "Error")) StreamType.Error else anyerror;
1010 }
1111
1212 return struct {
lib/std/net.zig+251-212
......@@ -1817,7 +1817,10 @@ pub const Stream = struct {
18171817 /// interchangeable with a file system file descriptor.
18181818 handle: Handle,
18191819
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 };
18211824
18221825 pub fn close(s: Stream) void {
18231826 switch (native_os) {
......@@ -1826,238 +1829,274 @@ pub const Stream = struct {
18261829 }
18271830 }
18281831
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,
18521838 },
1853 };
1854 }
1839 },
18551840
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 },
18631852 },
1864 else => &.{
1865 .writeSplat = posix_writeSplat,
1866 .writeFile = std.fs.File.writeFile,
1867 },
1868 },
1869 };
1870 }
1853 else => r.interface(),
1854 };
1855 }
18711856
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 }
18821867
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 };
18931900 }
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 }
19171901
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");
19501906 }
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 },
19761914
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,
19861918 };
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,
19951928 };
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 }
20151979 }
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;
20192005 }
2020 const flags = posix.MSG.NOSIGNAL;
2021 return std.posix.sendmsg(sock_fd, &msg, flags);
2022 }
20232006
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 }
20432057
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 };
20452078
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 } },
20512086 };
20522087 }
20532088
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 } },
20592096 };
20602097 }
2098
2099 const max_buffers_len = 8;
20612100};
20622101
20632102pub const Server = struct {
lib/std/process.zig+6-6
......@@ -1895,7 +1895,7 @@ pub fn createEnvironFromMap(
18951895 var i: usize = 0;
18961896
18971897 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);
18991899 i += 1;
19001900 }
19011901
......@@ -1906,16 +1906,16 @@ pub fn createEnvironFromMap(
19061906 .add => unreachable,
19071907 .delete => continue,
19081908 .edit => {
1909 envp_buf[i] = try std.fmt.allocPrintZ(arena, "{s}={d}", .{
1909 envp_buf[i] = try std.fmt.allocPrintSentinel(arena, "{s}={d}", .{
19101910 pair.key_ptr.*, options.zig_progress_fd.?,
1911 });
1911 }, 0);
19121912 i += 1;
19131913 continue;
19141914 },
19151915 .nothing => {},
19161916 };
19171917
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);
19191919 i += 1;
19201920 }
19211921 }
......@@ -1965,7 +1965,7 @@ pub fn createEnvironFromExisting(
19651965 var existing_index: usize = 0;
19661966
19671967 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);
19691969 i += 1;
19701970 }
19711971
......@@ -1974,7 +1974,7 @@ pub fn createEnvironFromExisting(
19741974 .add => unreachable,
19751975 .delete => continue,
19761976 .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);
19781978 i += 1;
19791979 continue;
19801980 },
lib/std/process/Child.zig+7-7
......@@ -1003,18 +1003,18 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
10031003}
10041004
10051005fn writeIntFd(fd: i32, value: ErrInt) !void {
1006 const file: File = .{ .handle = fd };
1006 var fw = std.fs.File.writer(.{ .handle = fd });
10071007 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;
10101010}
10111011
10121012fn readIntFd(fd: i32) !ErrInt {
1013 const file: File = .{ .handle = fd };
1013 var fr = std.fs.File.reader(.{ .handle = fd });
10141014 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);
10181018}
10191019
10201020const 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 {
163163 renderToWriter(eb, options, bw) catch return;
164164}
165165
166pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
166pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) (std.io.Writer.Error || std.posix.UnexpectedError)!void {
167167 if (eb.extra.len == 0) return;
168168 for (eb.getMessages()) |err_msg| {
169169 try renderErrorMessageToWriter(eb, options, err_msg, bw, "error", .red, 0);
......@@ -186,7 +186,7 @@ fn renderErrorMessageToWriter(
186186 kind: []const u8,
187187 color: std.io.tty.Color,
188188 indent: usize,
189) std.io.Writer.Error!void {
189) (std.io.Writer.Error || std.posix.UnexpectedError)!void {
190190 const ttyconf = options.ttyconf;
191191 const err_msg = eb.getErrorMessage(err_msg_index);
192192 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
13671367 const index_prog_node = f.prog_node.start("Index pack", 0);
13681368 defer index_prog_node.end();
13691369 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);
13741371 try git.indexPack(gpa, object_format, pack_file, &index_buffered_writer);
13751372 try index_buffered_writer.flush();
13761373 try index_file.sync();
src/dev.zig+4
......@@ -78,6 +78,7 @@ pub const Env = enum {
7878 .ast_gen,
7979 .sema,
8080 .legalize,
81 .c_compiler,
8182 .llvm_backend,
8283 .c_backend,
8384 .wasm_backend,
......@@ -127,6 +128,7 @@ pub const Env = enum {
127128 .clang_command,
128129 .cc_command,
129130 .translate_c_command,
131 .c_compiler,
130132 => true,
131133 else => false,
132134 },
......@@ -248,6 +250,8 @@ pub const Feature = enum {
248250 sema,
249251 legalize,
250252
253 c_compiler,
254
251255 llvm_backend,
252256 c_backend,
253257 wasm_backend,
src/link/Elf/Atom.zig+14-17
......@@ -1388,10 +1388,7 @@ const x86_64 = struct {
13881388 .{ .imm = .s(-129) },
13891389 }, t) catch return false;
13901390 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);
13951392 inst.encode(&bw, .{}) catch return false;
13961393 return true;
13971394 },
......@@ -1599,7 +1596,7 @@ const aarch64 = struct {
15991596 const diags = &elf_file.base.comp.link_diags;
16001597 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
16011598 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);
16031600 const file_ptr = atom.file(elf_file).?;
16041601
16051602 const P, const A, const S, const GOT, const G, const TP, const DTP = args;
......@@ -1626,7 +1623,7 @@ const aarch64 = struct {
16261623 const S_ = th.targetAddress(target_index, elf_file);
16271624 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;
16281625 };
1629 aarch64_util.writeBranchImm(disp, (try bw.writableSlice(4))[0..4]);
1626 aarch64_util.writeBranchImm(disp, code);
16301627 },
16311628
16321629 .PREL32 => {
......@@ -1897,26 +1894,26 @@ const riscv = struct {
18971894
18981895 .HI20 => {
18991896 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);
19011898 },
19021899
19031900 .GOT_HI20 => {
19041901 assert(target.flags.has_got);
19051902 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);
19071904 },
19081905
19091906 .CALL_PLT => {
19101907 // TODO: relax
19111908 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);
19131910 riscv_util.writeInstU(code[0..4], disp); // auipc
19141911 riscv_util.writeInstI(code[4..8], disp); // jalr
19151912 },
19161913
19171914 .PCREL_HI20 => {
19181915 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);
19201917 },
19211918
19221919 .PCREL_LO12_I,
......@@ -1954,8 +1951,8 @@ const riscv = struct {
19541951 };
19551952 relocs_log.debug(" [{x} => {x}]", .{ P_, disp + P_ });
19561953 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)),
19591956 else => unreachable,
19601957 }
19611958 },
......@@ -1965,8 +1962,8 @@ const riscv = struct {
19651962 => {
19661963 const disp: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow);
19671964 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),
19701967 else => unreachable,
19711968 }
19721969 },
......@@ -1974,7 +1971,7 @@ const riscv = struct {
19741971 .TPREL_HI20 => {
19751972 const target_addr: u32 = @intCast(target.address(.{}, elf_file));
19761973 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));
19781975 },
19791976
19801977 .TPREL_LO12_I,
......@@ -1983,8 +1980,8 @@ const riscv = struct {
19831980 const target_addr: u32 = @intCast(target.address(.{}, elf_file));
19841981 const val: i32 = @intCast(S + A - target_addr);
19851982 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)),
19881985 else => unreachable,
19891986 }
19901987 },
src/link/MachO/dyld_info/Trie.zig+1-4
......@@ -185,10 +185,7 @@ const FinalizeNodeResult = struct {
185185/// Updates offset of this node in the output byte stream.
186186fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult {
187187 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);
192189 const slice = self.nodes.slice();
193190
194191 var node_size: u32 = 0;
src/link/riscv.zig+3-3
......@@ -1,7 +1,7 @@
11pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
22 const mask: u8 = 0b11_000000;
33 const actual: i8 = @truncate(addend);
4 const old_value = (try bw.writableSlice(1))[0];
4 const old_value = (try bw.writableArray(1))[0];
55 const new_value = (old_value & mask) | (@as(u8, switch (op) {
66 .set => @bitCast(actual),
77 .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.
1414 .set => try overwriteUleb(@intCast(addend), bw),
1515 .sub => {
1616 var br: std.io.BufferedReader = undefined;
17 br.initFixed(try bw.writableSlice(1));
17 br.initFixed(try bw.writableArray(1));
1818 const old_value = try br.takeLeb128(u64);
1919 try overwriteUleb(old_value -% @as(u64, @intCast(addend)), bw);
2020 },
......@@ -24,7 +24,7 @@ pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io.
2424fn overwriteUleb(new_value: u64, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
2525 var value: u64 = new_value;
2626 while (true) {
27 const byte = (try bw.writableSlice(1))[0];
27 const byte = (try bw.writableArray(1))[0];
2828 try bw.writeByte((byte & 0x80) | @as(u7, @truncate(value)));
2929 if (byte & 0x80 == 0) break;
3030 value >>= 7;
src/main.zig+13-2
......@@ -1808,6 +1808,7 @@ fn buildOutputType(
18081808 } else manifest_file = arg;
18091809 },
18101810 .assembly, .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .ll, .bc, .m, .mm => {
1811 dev.check(.c_compiler);
18111812 try create_module.c_source_files.append(arena, .{
18121813 // Populated after module creation.
18131814 .owner = undefined,
......@@ -1818,6 +1819,7 @@ fn buildOutputType(
18181819 });
18191820 },
18201821 .rc => {
1822 dev.check(.win32_resource);
18211823 try create_module.rc_source_files.append(arena, .{
18221824 // Populated after module creation.
18231825 .owner = undefined,
......@@ -3303,6 +3305,7 @@ fn buildOutputType(
33033305 defer thread_pool.deinit();
33043306
33053307 for (create_module.c_source_files.items) |*src| {
3308 dev.check(.c_compiler);
33063309 if (!mem.eql(u8, src.src_path, "-")) continue;
33073310
33083311 const ext = src.ext orelse
......@@ -5008,7 +5011,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
50085011 var http_client: if (dev.env.supports(.fetch_command)) std.http.Client else struct {
50095012 allocator: Allocator,
50105013 fn deinit(_: @This()) void {}
5011 } = .{ .allocator = gpa };
5014 } = .{
5015 .allocator = gpa,
5016 .read_buffer_size = 0x4000,
5017 .write_buffer_size = 0x4000,
5018 };
50125019 defer http_client.deinit();
50135020
50145021 var unlazy_set: Package.Fetch.JobQueue.UnlazySet = .{};
......@@ -6815,7 +6822,11 @@ fn cmdFetch(
68156822 try thread_pool.init(.{ .allocator = gpa });
68166823 defer thread_pool.deinit();
68176824
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 };
68196830 defer http_client.deinit();
68206831
68216832 try http_client.initDefaultProxies(arena);