layout: use fork/execve instead of ChildProcess
This keeps things simpler, and we will need this control anyways in order to enforce a timeout.
This commit is contained in:
parent
05557086e6
commit
845fcad9e6
1 changed files with 20 additions and 18 deletions
|
@ -232,32 +232,34 @@ fn layoutExternal(self: *Self, visible_count: u32) !void {
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
|
|
||||||
// Assemble command
|
// Assemble command
|
||||||
const layout_command = std.fmt.allocPrint(&arena.allocator, "{} {} {} {d} {} {}", .{
|
const layout_command = try std.fmt.allocPrint0(&arena.allocator, "{} {} {} {d} {} {}", .{
|
||||||
self.layout,
|
self.layout,
|
||||||
visible_count,
|
visible_count,
|
||||||
self.master_count,
|
self.master_count,
|
||||||
self.master_factor,
|
self.master_factor,
|
||||||
layout_width,
|
layout_width,
|
||||||
layout_height,
|
layout_height,
|
||||||
}) catch @panic("Out of memory.");
|
});
|
||||||
const cmd = [_][]const u8{ "/bin/sh", "-c", layout_command };
|
const cmd = [_:null]?[*:0]const u8{ "/bin/sh", "-c", layout_command, null };
|
||||||
|
const stdout_pipe = try std.os.pipe();
|
||||||
|
|
||||||
// Execute layout executable
|
const pid = try std.os.fork();
|
||||||
// TODO abort after 1 second
|
if (pid == 0) {
|
||||||
const child = try std.ChildProcess.init(&cmd, &arena.allocator);
|
std.os.dup2(stdout_pipe[1], std.os.STDOUT_FILENO) catch c._exit(1);
|
||||||
child.stdin_behavior = .Ignore;
|
std.os.close(stdout_pipe[0]);
|
||||||
child.stdout_behavior = .Pipe;
|
std.os.close(stdout_pipe[1]);
|
||||||
try std.ChildProcess.spawn(child);
|
std.os.execveZ("/bin/sh", &cmd, std.c.environ) catch c._exit(1);
|
||||||
const max_output_size = 400 * 1024;
|
}
|
||||||
const buffer = try child.stdout.?.inStream().readAllAlloc(&arena.allocator, max_output_size);
|
std.os.close(stdout_pipe[1]);
|
||||||
const term = try child.wait();
|
const stdout = std.fs.File{ .handle = stdout_pipe[0], .io_mode = std.io.mode };
|
||||||
switch (term) {
|
defer stdout.close();
|
||||||
.Exited, .Signal, .Stopped, .Unknown => |code| {
|
|
||||||
if (code != 0) {
|
// TODO abort after a timeout
|
||||||
|
const status = std.os.waitpid(pid, 0);
|
||||||
|
if (!std.os.WIFEXITED(status) or std.os.WEXITSTATUS(status) != 0)
|
||||||
return LayoutError.BadExitCode;
|
return LayoutError.BadExitCode;
|
||||||
}
|
|
||||||
},
|
const buffer = try stdout.inStream().readAllAlloc(&arena.allocator, 1024);
|
||||||
}
|
|
||||||
|
|
||||||
// Parse layout command output
|
// Parse layout command output
|
||||||
var view_boxen = std.ArrayList(Box).init(&arena.allocator);
|
var view_boxen = std.ArrayList(Box).init(&arena.allocator);
|
||||||
|
|
Loading…
Reference in a new issue