termio: implement kill command for flatpak

This commit is contained in:
Mitchell Hashimoto
2023-02-27 11:44:18 -08:00
parent 25bde8a351
commit 83a1d783b1
2 changed files with 57 additions and 4 deletions

View File

@ -1,5 +1,6 @@
const std = @import("std"); const std = @import("std");
const assert = std.debug.assert; const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const builtin = @import("builtin"); const builtin = @import("builtin");
const log = std.log.scoped(.flatpak); const log = std.log.scoped(.flatpak);
@ -25,7 +26,6 @@ pub fn isFlatpak() bool {
/// ///
/// Requires GIO, GLib to be available and linked. /// Requires GIO, GLib to be available and linked.
pub const FlatpakHostCommand = struct { pub const FlatpakHostCommand = struct {
const Allocator = std.mem.Allocator;
const fd_t = std.os.fd_t; const fd_t = std.os.fd_t;
const EnvMap = std.process.EnvMap; const EnvMap = std.process.EnvMap;
const c = @cImport({ const c = @cImport({
@ -134,6 +134,51 @@ pub const FlatpakHostCommand = struct {
} }
} }
/// Send a signal to the started command. This does nothing if the
/// command is not in the started state.
pub fn signal(self: *FlatpakHostCommand, sig: u8, pg: bool) !void {
const pid = pid: {
self.state_mutex.lock();
defer self.state_mutex.unlock();
switch (self.state) {
.started => |v| break :pid v.pid,
else => return,
}
};
// Get our bus connection.
var g_err: [*c]c.GError = null;
const bus = c.g_bus_get_sync(c.G_BUS_TYPE_SESSION, null, &g_err) orelse {
log.warn("signal error getting bus: {s}", .{g_err.*.message});
return Error.FlatpakSetupFail;
};
defer c.g_object_unref(bus);
const reply = c.g_dbus_connection_call_sync(
bus,
"org.freedesktop.Flatpak",
"/org/freedesktop/Flatpak/Development",
"org.freedesktop.Flatpak.Development",
"HostCommandSignal",
c.g_variant_new(
"(uub)",
pid,
sig,
@intCast(c_int, @boolToInt(pg)),
),
c.G_VARIANT_TYPE("()"),
c.G_DBUS_CALL_FLAGS_NONE,
c.G_MAXINT,
null,
&g_err,
);
if (g_err != null) {
log.warn("signal send error: {s}", .{g_err.*.message});
return;
}
defer c.g_variant_unref(reply);
}
fn threadMain(self: *FlatpakHostCommand, alloc: Allocator) void { fn threadMain(self: *FlatpakHostCommand, alloc: Allocator) void {
// Create a new thread-local context so that all our sources go // Create a new thread-local context so that all our sources go
// to this context and we can run our loop correctly. // to this context and we can run our loop correctly.

View File

@ -490,6 +490,11 @@ const Subprocess = struct {
pid, pid,
}); });
// Once started, we can close the pty child side. We do this after
// wait right now but that is fine too. This lets us read the
// parent and detect EOF.
_ = std.os.close(pty.slave);
return pty.master; return pty.master;
} }
@ -601,9 +606,10 @@ const Subprocess = struct {
} }
} }
/// Kill the underlying process started via Flatpak host command.
/// This sends a signal via the Flatpak API.
fn killCommandFlatpak(command: *FlatpakHostCommand) !void { fn killCommandFlatpak(command: *FlatpakHostCommand) !void {
// TODO try command.signal(c.SIGHUP, true);
_ = command;
} }
}; };
@ -628,7 +634,9 @@ const ReadThread = struct {
switch (err) { switch (err) {
// This means our pty is closed. We're probably // This means our pty is closed. We're probably
// gracefully shutting down. // gracefully shutting down.
error.NotOpenForReading => log.info("io reader exiting", .{}), error.NotOpenForReading,
error.InputOutput,
=> log.info("io reader exiting", .{}),
else => { else => {
log.err("io reader error err={}", .{err}); log.err("io reader error err={}", .{err});