app: Use std.process.Child instead of POSIX calls
This commit is contained in:
parent
e620d8f759
commit
5d06c618f1
1 changed files with 46 additions and 57 deletions
103
app/Builder.zig
103
app/Builder.zig
|
|
@ -34,13 +34,15 @@ const Status = union(enum) {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn run(self: *Builder) !void {
|
pub fn run(self: *Builder) !void {
|
||||||
|
var child = try self.runZigBuild(.Inherit);
|
||||||
|
switch (try child.wait()) {
|
||||||
|
.Exited => |code| {
|
||||||
|
if (code != 0) std.os.exit(code);
|
||||||
|
},
|
||||||
|
else => std.os.exit(1),
|
||||||
|
}
|
||||||
|
|
||||||
if (self.serve) {
|
if (self.serve) {
|
||||||
const child_pid = try std.os.fork();
|
|
||||||
if (child_pid == 0) try self.exec();
|
|
||||||
|
|
||||||
const wait_res = std.os.waitpid(child_pid, 0);
|
|
||||||
if (wait_res.status != 0) std.os.exit(1);
|
|
||||||
|
|
||||||
var out_dir = std.fs.cwd().openIterableDir(out_dir_path, .{}) catch |err| {
|
var out_dir = std.fs.cwd().openIterableDir(out_dir_path, .{}) catch |err| {
|
||||||
std.log.err("cannot open '{s}': {s}", .{ out_dir_path, @errorName(err) });
|
std.log.err("cannot open '{s}': {s}", .{ out_dir_path, @errorName(err) });
|
||||||
std.os.exit(1);
|
std.os.exit(1);
|
||||||
|
|
@ -88,48 +90,46 @@ pub fn run(self: *Builder) !void {
|
||||||
const conn = try server.accept();
|
const conn = try server.accept();
|
||||||
try pool.spawn(handleConn, .{ self, conn });
|
try pool.spawn(handleConn, .{ self, conn });
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
try self.exec();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec(self: Builder) !void {
|
fn runZigBuild(self: Builder, stderr_behavior: std.process.Child.StdIo) !std.process.Child {
|
||||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
var args_arena = std.heap.ArenaAllocator.init(allocator);
|
||||||
defer arena.deinit();
|
defer args_arena.deinit();
|
||||||
const argv = try self.buildArgs(arena.allocator());
|
|
||||||
|
|
||||||
return std.os.execvpeZ(
|
const args = try self.buildArgs(args_arena.allocator());
|
||||||
argv[0].?,
|
|
||||||
@ptrCast([*:null]const ?[*:0]const u8, argv),
|
var child = std.process.Child.init(args, allocator);
|
||||||
@ptrCast([*:null]const ?[*:0]const u8, std.os.environ.ptr),
|
child.stderr_behavior = stderr_behavior;
|
||||||
);
|
|
||||||
|
try child.spawn();
|
||||||
|
|
||||||
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buildArgs(self: Builder, arena: std.mem.Allocator) ![*:null]const ?[*:0]const u8 {
|
fn buildArgs(self: Builder, arena: std.mem.Allocator) ![]const []const u8 {
|
||||||
var argv = std.ArrayList(?[*:0]const u8).init(arena);
|
var argv = std.ArrayList([]const u8).init(arena);
|
||||||
try argv.ensureTotalCapacity(self.steps.len + self.zig_build_args.len + 7);
|
try argv.ensureTotalCapacity(self.steps.len + self.zig_build_args.len + 6);
|
||||||
|
|
||||||
argv.appendAssumeCapacity(try arena.dupeZ(u8, self.zig_path));
|
argv.appendAssumeCapacity(try arena.dupe(u8, self.zig_path));
|
||||||
argv.appendAssumeCapacity("build");
|
argv.appendAssumeCapacity("build");
|
||||||
|
|
||||||
for (self.steps) |step| {
|
for (self.steps) |step| {
|
||||||
argv.appendAssumeCapacity(try arena.dupeZ(u8, step));
|
argv.appendAssumeCapacity(try arena.dupe(u8, step));
|
||||||
}
|
}
|
||||||
|
|
||||||
argv.appendAssumeCapacity("--color");
|
argv.appendAssumeCapacity("--color");
|
||||||
argv.appendAssumeCapacity("on");
|
argv.appendAssumeCapacity("on");
|
||||||
argv.appendAssumeCapacity(try std.fmt.allocPrintZ(arena, "-Doptimize={s}", .{@tagName(self.optimize)}));
|
argv.appendAssumeCapacity(try std.fmt.allocPrint(arena, "-Doptimize={s}", .{@tagName(self.optimize)}));
|
||||||
if (self.target) |target| {
|
if (self.target) |target| {
|
||||||
argv.appendAssumeCapacity(try std.fmt.allocPrintZ(arena, "-Dtarget={s}", .{try target.toZigTriple()}));
|
argv.appendAssumeCapacity(try std.fmt.allocPrint(arena, "-Dtarget={s}", .{try target.toZigTriple()}));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (self.zig_build_args) |arg| {
|
for (self.zig_build_args) |arg| {
|
||||||
argv.appendAssumeCapacity(try arena.dupeZ(u8, arg));
|
argv.appendAssumeCapacity(try arena.dupe(u8, arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
argv.appendAssumeCapacity(null);
|
return try argv.toOwnedSlice();
|
||||||
|
|
||||||
return @ptrCast([*:null]const ?[*:0]const u8, try argv.toOwnedSlice());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn watch(self: *Builder) void {
|
fn watch(self: *Builder) void {
|
||||||
|
|
@ -319,40 +319,29 @@ fn notify(self: *Builder, stream: std.net.Stream) void {
|
||||||
fn compile(self: *Builder) void {
|
fn compile(self: *Builder) void {
|
||||||
std.log.info("building...", .{});
|
std.log.info("building...", .{});
|
||||||
|
|
||||||
var pipes = std.os.pipe() catch unreachable;
|
var child = self.runZigBuild(.Pipe) catch unreachable;
|
||||||
const child_pid = std.os.fork() catch unreachable;
|
|
||||||
|
|
||||||
if (child_pid == 0) {
|
const stderr = child.stderr.?.reader().readAllAlloc(
|
||||||
std.os.close(pipes[0]);
|
allocator,
|
||||||
std.os.dup2(pipes[1], std.os.STDERR_FILENO) catch @panic("OOM");
|
std.math.maxInt(usize),
|
||||||
std.os.close(pipes[1]);
|
) catch @panic("OOM");
|
||||||
return self.exec() catch unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
std.os.close(pipes[1]);
|
|
||||||
const wait_result = std.os.waitpid(child_pid, 0);
|
|
||||||
|
|
||||||
const stderr_file = std.fs.File{ .handle = pipes[0] };
|
|
||||||
const stderr = stderr_file.reader().readAllAlloc(allocator, std.math.maxInt(usize)) catch @panic("OOM");
|
|
||||||
|
|
||||||
std.io.getStdErr().writeAll(stderr) catch unreachable;
|
std.io.getStdErr().writeAll(stderr) catch unreachable;
|
||||||
|
|
||||||
switch (wait_result.status) {
|
const term = child.wait() catch unreachable;
|
||||||
0 => {
|
if (term == .Exited and term.Exited == 0) {
|
||||||
allocator.free(stderr);
|
allocator.free(stderr);
|
||||||
self.status = .built;
|
self.status = .built;
|
||||||
std.log.info("built", .{});
|
std.log.info("built", .{});
|
||||||
},
|
} else if (term == .Exited and term.Exited == 1) {
|
||||||
1 => {
|
std.log.warn("compile error", .{});
|
||||||
std.log.warn("compile error", .{});
|
self.status = .{ .compile_error = stderr };
|
||||||
self.status = .{ .compile_error = stderr };
|
} else {
|
||||||
},
|
allocator.free(stderr);
|
||||||
else => {
|
self.status = .stopped;
|
||||||
allocator.free(stderr);
|
std.log.warn("the build process has stopped unexpectedly", .{});
|
||||||
self.status = .stopped;
|
|
||||||
std.log.warn("the build process has stopped unexpectedly", .{});
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (self.subscribers.items) |sub| {
|
for (self.subscribers.items) |sub| {
|
||||||
self.notify(sub);
|
self.notify(sub);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue