mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:44:43 +01:00
compiler: update for std.Io.File.MultiReader API
This commit is contained in:
parent
dd0153b91b
commit
372e8e54d3
6 changed files with 59 additions and 22 deletions
|
|
@ -539,6 +539,7 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.
|
|||
if (!watch) try sendMessage(io, zp.child.stdin.?, .exit);
|
||||
|
||||
var result: ?Path = null;
|
||||
var eos_err: error{EndOfStream}!void = {};
|
||||
|
||||
const stdout = zp.multi_reader.fileReader(0);
|
||||
|
||||
|
|
@ -549,7 +550,13 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.
|
|||
error.ReadFailed => return stdout.err.?,
|
||||
};
|
||||
const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) {
|
||||
error.EndOfStream => |e| return e,
|
||||
error.EndOfStream => |e| {
|
||||
// Better to report the crash with stderr below, but we set
|
||||
// this in case the child exits successfully while violating
|
||||
// this protocol.
|
||||
eos_err = e;
|
||||
break;
|
||||
},
|
||||
error.ReadFailed => return stdout.err.?,
|
||||
};
|
||||
switch (header.tag) {
|
||||
|
|
@ -647,6 +654,8 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool, web_server: ?*Build.
|
|||
try s.result_error_msgs.append(arena, try arena.dupe(u8, stderr_contents));
|
||||
}
|
||||
|
||||
try eos_err;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,14 @@ pub fn fill(mr: *MultiReader, unused_capacity: usize, timeout: Io.Timeout) FillE
|
|||
if (!any_completed) return error.EndOfStream;
|
||||
}
|
||||
|
||||
/// Wait until all streams fail or reach the end.
|
||||
pub fn fillRemaining(mr: *MultiReader, timeout: Io.Timeout) Io.Batch.WaitError!void {
|
||||
while (fill(mr, 1, timeout)) |_| {} else |err| switch (err) {
|
||||
error.EndOfStream => return,
|
||||
else => |e| return e,
|
||||
}
|
||||
}
|
||||
|
||||
fn rebaseGrowing(mr: *MultiReader, context: *Context, capacity: usize) Allocator.Error!void {
|
||||
const gpa = mr.gpa;
|
||||
const r = &context.fr.interface;
|
||||
|
|
|
|||
|
|
@ -488,6 +488,7 @@ pub const RunOptions = struct {
|
|||
create_no_window: bool = true,
|
||||
/// Darwin-only. Disable ASLR for the child process.
|
||||
disable_aslr: bool = false,
|
||||
timeout: Io.Timeout = .none,
|
||||
};
|
||||
|
||||
pub const RunResult = struct {
|
||||
|
|
@ -529,6 +530,7 @@ pub fn run(gpa: Allocator, io: Io, options: RunOptions) RunError!RunResult {
|
|||
.stderr = &stderr,
|
||||
.stdout_limit = options.stdout_limit,
|
||||
.stderr_limit = options.stderr_limit,
|
||||
.timeout = options.timeout,
|
||||
});
|
||||
|
||||
const term = try child.wait(io);
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ pub const CollectOutputOptions = struct {
|
|||
allocator: ?Allocator = null,
|
||||
stdout_limit: Io.Limit = .unlimited,
|
||||
stderr_limit: Io.Limit = .unlimited,
|
||||
timeout: Io.Timeout = .none,
|
||||
};
|
||||
|
||||
/// Collect the output from the process's stdout and stderr. Will return once
|
||||
|
|
@ -173,7 +174,7 @@ pub fn collectOutput(child: *const Child, io: Io, options: CollectOutputOptions)
|
|||
remaining += 1;
|
||||
}
|
||||
while (remaining > 0) {
|
||||
try batch.wait(io, .none);
|
||||
try batch.wait(io, options.timeout);
|
||||
while (batch.next()) |op| {
|
||||
const n = try reads[op].file_read_streaming.status.result;
|
||||
if (n == 0) {
|
||||
|
|
|
|||
|
|
@ -268,7 +268,8 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
|
|||
});
|
||||
|
||||
const run_res = std.process.run(gpa, io, .{
|
||||
.max_output_bytes = 1024 * 1024,
|
||||
.stdout_limit = .limited(1024 * 1024),
|
||||
.stderr_limit = .limited(1024 * 1024),
|
||||
.argv = argv.items,
|
||||
.environ_map = &environ_map,
|
||||
// Some C compilers, such as Clang, are known to rely on argv[0] to find the path
|
||||
|
|
@ -584,7 +585,8 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![]u8 {
|
|||
try argv.append(arg1);
|
||||
|
||||
const run_res = std.process.run(gpa, io, .{
|
||||
.max_output_bytes = 1024 * 1024,
|
||||
.stdout_limit = .limited(1024 * 1024),
|
||||
.stderr_limit = .limited(1024 * 1024),
|
||||
.argv = argv.items,
|
||||
.environ_map = &environ_map,
|
||||
// Some C compilers, such as Clang, are known to rely on argv[0] to find the path
|
||||
|
|
|
|||
|
|
@ -6873,6 +6873,7 @@ fn spawnZigRc(
|
|||
child_progress_node: std.Progress.Node,
|
||||
) !void {
|
||||
const io = comp.io;
|
||||
const gpa = comp.gpa;
|
||||
var node_name: std.ArrayList(u8) = .empty;
|
||||
defer node_name.deinit(arena);
|
||||
|
||||
|
|
@ -6887,55 +6888,69 @@ fn spawnZigRc(
|
|||
});
|
||||
defer child.kill(io);
|
||||
|
||||
var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{
|
||||
.stdout = child.stdout.?,
|
||||
.stderr = child.stderr.?,
|
||||
});
|
||||
defer poller.deinit();
|
||||
var multi_reader_buffer: Io.File.MultiReader.Buffer(2) = undefined;
|
||||
var multi_reader: Io.File.MultiReader = undefined;
|
||||
multi_reader.init(gpa, io, multi_reader_buffer.toStreams(), &.{ child.stdout.?, child.stderr.? });
|
||||
defer multi_reader.deinit();
|
||||
|
||||
const stdout = poller.reader(.stdout);
|
||||
const stdout = multi_reader.fileReader(0);
|
||||
const MessageHeader = std.zig.Server.Message.Header;
|
||||
|
||||
poll: while (true) {
|
||||
const MessageHeader = std.zig.Server.Message.Header;
|
||||
while (stdout.buffered().len < @sizeOf(MessageHeader)) if (!try poller.poll()) break :poll;
|
||||
const header = stdout.takeStruct(MessageHeader, .little) catch unreachable;
|
||||
while (stdout.buffered().len < header.bytes_len) if (!try poller.poll()) break :poll;
|
||||
const body = stdout.take(header.bytes_len) catch unreachable;
|
||||
var eos_err: error{EndOfStream}!void = {};
|
||||
|
||||
while (true) {
|
||||
const header = stdout.interface.takeStruct(MessageHeader, .little) catch |err| switch (err) {
|
||||
error.EndOfStream => break,
|
||||
error.ReadFailed => return stdout.err.?,
|
||||
};
|
||||
const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) {
|
||||
error.EndOfStream => |e| {
|
||||
// Better to report the crash with stderr below, but we set
|
||||
// this in case the child exits successfully while violating
|
||||
// this protocol.
|
||||
eos_err = e;
|
||||
break;
|
||||
},
|
||||
error.ReadFailed => return stdout.err.?,
|
||||
};
|
||||
switch (header.tag) {
|
||||
// We expect exactly one ErrorBundle, and if any error_bundle header is
|
||||
// sent then it's a fatal error.
|
||||
.error_bundle => {
|
||||
const error_bundle = try std.zig.Server.allocErrorBundle(comp.gpa, body);
|
||||
const error_bundle = try std.zig.Server.allocErrorBundle(gpa, body);
|
||||
return comp.failWin32ResourceWithOwnedBundle(win32_resource, error_bundle);
|
||||
},
|
||||
else => {}, // ignore other messages
|
||||
}
|
||||
}
|
||||
|
||||
// Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace)
|
||||
const stderr = poller.reader(.stderr);
|
||||
try multi_reader.fillRemaining(.none);
|
||||
|
||||
// Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace)
|
||||
const term = child.wait(io) catch |err| {
|
||||
return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {t}", .{ argv[0], err });
|
||||
};
|
||||
|
||||
const stderr = multi_reader.reader(1).buffered();
|
||||
|
||||
switch (term) {
|
||||
.exited => |code| {
|
||||
if (code != 0) {
|
||||
log.err("zig rc failed with stderr:\n{s}", .{stderr.buffered()});
|
||||
log.err("zig rc failed with stderr:\n{s}", .{stderr});
|
||||
return comp.failWin32Resource(win32_resource, "zig rc exited with code {d}", .{code});
|
||||
}
|
||||
},
|
||||
.signal => |sig| {
|
||||
log.err("zig rc signaled {t} with stderr:\n{s}", .{ sig, stderr.buffered() });
|
||||
log.err("zig rc signaled {t} with stderr:\n{s}", .{ sig, stderr });
|
||||
return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});
|
||||
},
|
||||
else => {
|
||||
log.err("zig rc terminated with stderr:\n{s}", .{stderr.buffered()});
|
||||
log.err("zig rc terminated with stderr:\n{s}", .{stderr});
|
||||
return comp.failWin32Resource(win32_resource, "zig rc terminated unexpectedly", .{});
|
||||
},
|
||||
}
|
||||
|
||||
try eos_err;
|
||||
}
|
||||
|
||||
pub fn tmpFilePath(comp: Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue