summaryrefslogtreecommitdiff
path: root/src/host_io.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/host_io.zig')
-rw-r--r--src/host_io.zig15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/host_io.zig b/src/host_io.zig
index 10a85d8f..1db0dac9 100644
--- a/src/host_io.zig
+++ b/src/host_io.zig
@@ -25,6 +25,9 @@ pub const Host = struct {
pty_signal: ?*const fn (ctx: ?*anyopaque, pane: u8, sig: pardes.PtySignal) void = null,
close_pty: ?*const fn (ctx: ?*anyopaque, pane: u8) void = null,
tty_taken: ?*const fn (ctx: ?*anyopaque, pane: u8) bool = null,
+ /// The name of the program holding the tty, when it is not the
+ /// shell (host_io.foregroundName), in `buf`.
+ fg_name: ?*const fn (ctx: ?*anyopaque, pane: u8, buf: []u8) ?[]const u8 = null,
/// Answered at once, not queued as an effect: Kill asks while the
/// job it saw running is still the one in the tty (host_io.killJob).
kill_job: ?*const fn (ctx: ?*anyopaque, pane: u8) bool = null,
@@ -1751,6 +1754,18 @@ pub fn killJob(shell_pid: libc.pid_t, master_fd: c_int) bool {
return libc.kill(-fg, libc.SIG.TERM) == 0;
}
+/// The command name of the tty's foreground job, when that is not the
+/// shell: what `pty/run` says is running. Linux only (/proc/<pgrp>/comm).
+pub fn foregroundName(shell_pid: libc.pid_t, master_fd: c_int, buf: []u8) ?[]const u8 {
+ if (comptime builtin.os.tag != .linux) return null;
+ const fg = tcgetpgrp(master_fd);
+ if (fg <= 0 or fg == shell_pid) return null;
+ var name: [64:0]u8 = undefined;
+ const path = std.fmt.bufPrintSentinel(&name, "/proc/{d}/comm", .{@as(u32, @intCast(fg))}, 0) catch return null;
+ const comm = std.mem.trimEnd(u8, readProc(path, buf) orelse return null, "\n");
+ return if (comm.len > 0) comm else null;
+}
+
fn readProc(path: [*:0]const u8, buf: []u8) ?[]const u8 {
const fd = libc.open(path, .{ .ACCMODE = .RDONLY });
if (fd < 0) return null;