diff --git a/lib/std/build.zig b/lib/std/build.zig index 59e6c4e87c..bc8b8acba0 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -926,11 +926,9 @@ pub const Builder = struct { try child.spawn(); - var stdout = std.Buffer.initNull(self.allocator); - defer std.Buffer.deinit(&stdout); - var stdout_file_in_stream = child.stdout.?.inStream(); - try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); + const stdout = try stdout_file_in_stream.stream.readAllAlloc(self.allocator, max_output_size); + errdefer self.allocator.free(stdout); const term = try child.wait(); switch (term) { @@ -939,7 +937,7 @@ pub const Builder = struct { out_code.* = @truncate(u8, code); return error.ExitCodeFailure; } - return stdout.toOwnedSlice(); + return stdout; }, .Signal, .Stopped, .Unknown => |code| { out_code.* = @truncate(u8, code); diff --git a/lib/std/build/run.zig b/lib/std/build/run.zig index eacf408ba9..dc4e0df898 100644 --- a/lib/std/build/run.zig +++ b/lib/std/build/run.zig @@ -169,26 +169,33 @@ pub const RunStep = struct { return err; }; - var stdout = Buffer.initNull(self.builder.allocator); - var stderr = Buffer.initNull(self.builder.allocator); - // TODO need to poll to read these streams to prevent a deadlock (or rely on evented I/O). + var stdout: []const u8 = undefined; switch (self.stdout_action) { .expect_exact, .expect_matches => { var stdout_file_in_stream = child.stdout.?.inStream(); - stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size) catch unreachable; + stdout = stdout_file_in_stream.stream.readAllAlloc(self.builder.allocator, max_stdout_size) catch unreachable; }, .inherit, .ignore => {}, } + defer switch (self.stdout_action) { + .expect_exact, .expect_matches => self.builder.allocator.free(stdout), + .inherit, .ignore => {}, + }; - switch (self.stdout_action) { + var stderr: []const u8 = undefined; + switch (self.stdout_behavior) { .expect_exact, .expect_matches => { var stderr_file_in_stream = child.stderr.?.inStream(); - stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size) catch unreachable; + stderr = stderr_file_in_stream.stream.readAllAlloc(self.builder.allocator, max_stdout_size) catch unreachable; }, .inherit, .ignore => {}, } + defer switch (self.stderr_action) { + .expect_exact, .expect_matches => self.builder.allocator.free(stderr), + .inherit, .ignore => {}, + }; const term = child.wait() catch |err| { warn("Unable to spawn {}: {}\n", .{ argv[0], @errorName(err) }); @@ -216,7 +223,7 @@ pub const RunStep = struct { switch (self.stderr_action) { .inherit, .ignore => {}, .expect_exact => |expected_bytes| { - if (!mem.eql(u8, expected_bytes, stderr.toSliceConst())) { + if (!mem.eql(u8, expected_bytes, stderr)) { warn( \\ \\========= Expected this stderr: ========= @@ -224,13 +231,13 @@ pub const RunStep = struct { \\========= But found: ==================== \\{} \\ - , .{ expected_bytes, stderr.toSliceConst() }); + , .{ expected_bytes, stderr }); printCmd(cwd, argv); return error.TestFailed; } }, .expect_matches => |matches| for (matches) |match| { - if (mem.indexOf(u8, stderr.toSliceConst(), match) == null) { + if (mem.indexOf(u8, stderr, match) == null) { warn( \\ \\========= Expected to find in stderr: ========= @@ -238,7 +245,7 @@ pub const RunStep = struct { \\========= But stderr does not contain it: ===== \\{} \\ - , .{ match, stderr.toSliceConst() }); + , .{ match, stderr }); printCmd(cwd, argv); return error.TestFailed; } @@ -248,7 +255,7 @@ pub const RunStep = struct { switch (self.stdout_action) { .inherit, .ignore => {}, .expect_exact => |expected_bytes| { - if (!mem.eql(u8, expected_bytes, stdout.toSliceConst())) { + if (!mem.eql(u8, expected_bytes, stdout)) { warn( \\ \\========= Expected this stdout: ========= @@ -256,13 +263,13 @@ pub const RunStep = struct { \\========= But found: ==================== \\{} \\ - , .{ expected_bytes, stdout.toSliceConst() }); + , .{ expected_bytes, stdout }); printCmd(cwd, argv); return error.TestFailed; } }, .expect_matches => |matches| for (matches) |match| { - if (mem.indexOf(u8, stdout.toSliceConst(), match) == null) { + if (mem.indexOf(u8, stdout, match) == null) { warn( \\ \\========= Expected to find in stdout: ========= @@ -270,7 +277,7 @@ pub const RunStep = struct { \\========= But stdout does not contain it: ===== \\{} \\ - , .{ match, stdout.toSliceConst() }); + , .{ match, stdout }); printCmd(cwd, argv); return error.TestFailed; } diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index d5e914b286..4f5fc2b496 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -217,21 +217,19 @@ pub const ChildProcess = struct { try child.spawn(); - var stdout = Buffer.initNull(args.allocator); - var stderr = Buffer.initNull(args.allocator); - defer Buffer.deinit(&stdout); - defer Buffer.deinit(&stderr); - var stdout_file_in_stream = child.stdout.?.inStream(); var stderr_file_in_stream = child.stderr.?.inStream(); - try stdout_file_in_stream.stream.readAllBuffer(&stdout, args.max_output_bytes); - try stderr_file_in_stream.stream.readAllBuffer(&stderr, args.max_output_bytes); + // TODO need to poll to read these streams to prevent a deadlock (or rely on evented I/O). + const stdout = try stdout_file_in_stream.stream.readAllAlloc(args.allocator, args.max_output_bytes); + errdefer args.allocator.free(stdout); + const stderr = try stderr_file_in_stream.stream.readAllAlloc(args.allocator, args.max_output_bytes); + errdefer args.allocator.free(stderr); return ExecResult{ .term = try child.wait(), - .stdout = stdout.toOwnedSlice(), - .stderr = stderr.toOwnedSlice(), + .stdout = stdout, + .stderr = stderr, }; } diff --git a/test/tests.zig b/test/tests.zig index 9cf4e7bd98..e324902579 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -566,14 +566,13 @@ pub const StackTracesContext = struct { } child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", .{ full_exe_path, @errorName(err) }); - var stdout = Buffer.initNull(b.allocator); - var stderr = Buffer.initNull(b.allocator); - var stdout_file_in_stream = child.stdout.?.inStream(); var stderr_file_in_stream = child.stderr.?.inStream(); - stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size) catch unreachable; - stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size) catch unreachable; + const stdout = stdout_file_in_stream.stream.readAllAlloc(b.allocator, max_stdout_size) catch unreachable; + defer b.allocator.free(stdout); + const stderr = stderr_file_in_stream.stream.readAllAlloc(b.allocator, max_stdout_size) catch unreachable; + defer b.allocator.free(stderr); const term = child.wait() catch |err| { debug.panic("Unable to spawn {}: {}\n", .{ full_exe_path, @errorName(err) }); @@ -616,11 +615,8 @@ pub const StackTracesContext = struct { const got: []const u8 = got_result: { var buf = try Buffer.initSize(b.allocator, 0); defer buf.deinit(); - const bytes = if (stderr.endsWith("\n")) - stderr.toSliceConst()[0 .. stderr.len() - 1] - else - stderr.toSliceConst()[0..stderr.len()]; - var it = mem.separate(bytes, "\n"); + if (stderr.len != 0 and stderr[stderr.len - 1] == '\n') stderr = stderr[0 .. stderr.len - 1]; + var it = mem.separate(stderr, "\n"); process_lines: while (it.next()) |line| { if (line.len == 0) continue; const delims = [_][]const u8{ ":", ":", ":", " in " };