mirror of https://github.com/fairyglade/ly.git
clean up child processes on SIGTERM
This commit is contained in:
parent
365933e39e
commit
713578e2ed
|
@ -42,4 +42,4 @@ session_index = 0
|
||||||
+ X Server PID is fetched from /tmp/X{d}.lock to be able to kill the process since it detaches.
|
+ X Server PID is fetched from /tmp/X{d}.lock to be able to kill the process since it detaches.
|
||||||
+ Non .desktop files are now ignored in sessions directory.
|
+ Non .desktop files are now ignored in sessions directory.
|
||||||
+ PAM auth is now done in a child process. (Fixes some issues with logging out and back in).
|
+ PAM auth is now done in a child process. (Fixes some issues with logging out and back in).
|
||||||
+ When ly receives SIGTERM, the terminal is now cleared.
|
+ When ly receives SIGTERM, the terminal is now cleared and existing child processes are cleaned up.
|
||||||
|
|
51
src/auth.zig
51
src/auth.zig
|
@ -10,6 +10,19 @@ const utmp = interop.utmp;
|
||||||
const Utmp = utmp.utmp;
|
const Utmp = utmp.utmp;
|
||||||
const SharedError = @import("SharedError.zig");
|
const SharedError = @import("SharedError.zig");
|
||||||
|
|
||||||
|
var child_pid: std.os.pid_t = 0;
|
||||||
|
var xorg_pid: std.os.pid_t = 0;
|
||||||
|
|
||||||
|
pub fn xorgSignalHandler(i: c_int) callconv(.C) void {
|
||||||
|
if (xorg_pid > 0)
|
||||||
|
_ = std.c.kill(xorg_pid, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sessionSignalHandler(i: c_int) callconv(.C) void {
|
||||||
|
if (child_pid > 0)
|
||||||
|
_ = std.c.kill(child_pid, i);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, login: Text, password: *Text) !void {
|
pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, login: Text, password: *Text) !void {
|
||||||
var tty_buffer: [2]u8 = undefined;
|
var tty_buffer: [2]u8 = undefined;
|
||||||
const tty_str = try std.fmt.bufPrintZ(&tty_buffer, "{d}", .{config.tty});
|
const tty_str = try std.fmt.bufPrintZ(&tty_buffer, "{d}", .{config.tty});
|
||||||
|
@ -86,8 +99,8 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
|
||||||
var shared_err = try SharedError.init();
|
var shared_err = try SharedError.init();
|
||||||
defer shared_err.deinit();
|
defer shared_err.deinit();
|
||||||
|
|
||||||
const pid = try std.os.fork();
|
child_pid = try std.os.fork();
|
||||||
if (pid == 0) {
|
if (child_pid == 0) {
|
||||||
// Set the user information
|
// Set the user information
|
||||||
status = interop.initgroups(pwd.pw_name, pwd.pw_gid);
|
status = interop.initgroups(pwd.pw_name, pwd.pw_gid);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
|
@ -159,10 +172,18 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
|
||||||
}
|
}
|
||||||
|
|
||||||
var entry: Utmp = std.mem.zeroes(Utmp);
|
var entry: Utmp = std.mem.zeroes(Utmp);
|
||||||
addUtmpEntry(&entry, pwd.pw_name, pid) catch {};
|
addUtmpEntry(&entry, pwd.pw_name, child_pid) catch {};
|
||||||
|
|
||||||
|
// If we receive SIGTERM, forward it to child_pid
|
||||||
|
const act = std.os.Sigaction{
|
||||||
|
.handler = .{ .handler = &sessionSignalHandler },
|
||||||
|
.mask = std.os.empty_sigset,
|
||||||
|
.flags = 0,
|
||||||
|
};
|
||||||
|
try std.os.sigaction(std.os.SIG.TERM, &act, null);
|
||||||
|
|
||||||
// Wait for the session to stop
|
// Wait for the session to stop
|
||||||
_ = std.os.waitpid(pid, 0);
|
_ = std.os.waitpid(child_pid, 0);
|
||||||
|
|
||||||
removeUtmpEntry(&entry);
|
removeUtmpEntry(&entry);
|
||||||
|
|
||||||
|
@ -400,20 +421,21 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, config: Config, de
|
||||||
std.os.exit(0);
|
std.os.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var status: c_int = 0;
|
||||||
var ok: c_int = undefined;
|
var ok: c_int = undefined;
|
||||||
var xcb: ?*interop.xcb.xcb_connection_t = null;
|
var xcb: ?*interop.xcb.xcb_connection_t = null;
|
||||||
while (ok != 0) {
|
while (ok != 0) {
|
||||||
xcb = interop.xcb.xcb_connect(null, null);
|
xcb = interop.xcb.xcb_connect(null, null);
|
||||||
ok = interop.xcb.xcb_connection_has_error(xcb);
|
ok = interop.xcb.xcb_connection_has_error(xcb);
|
||||||
_ = std.c.kill(pid, 0);
|
status = std.c.kill(pid, 0);
|
||||||
if (std.c._errno().* == interop.ESRCH and ok != 0) return;
|
if (std.os.errno(status) == .SRCH and ok != 0) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// X Server detaches from the process.
|
// X Server detaches from the process.
|
||||||
// PID can be fetched from /tmp/X{d}.lock
|
// PID can be fetched from /tmp/X{d}.lock
|
||||||
const x_pid = try getXPid(display_num);
|
const x_pid = try getXPid(display_num);
|
||||||
|
|
||||||
const xorg_pid = try std.os.fork();
|
xorg_pid = try std.os.fork();
|
||||||
if (xorg_pid == 0) {
|
if (xorg_pid == 0) {
|
||||||
var cmd_buffer: [1024]u8 = undefined;
|
var cmd_buffer: [1024]u8 = undefined;
|
||||||
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} {s}", .{ config.x_cmd_setup, desktop_cmd }) catch std.os.exit(1);
|
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} {s}", .{ config.x_cmd_setup, desktop_cmd }) catch std.os.exit(1);
|
||||||
|
@ -421,13 +443,20 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, config: Config, de
|
||||||
std.os.exit(0);
|
std.os.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var status: c_int = 0;
|
// If we receive SIGTERM, clean up by killing the xorg_pid process
|
||||||
|
const act = std.os.Sigaction{
|
||||||
|
.handler = .{ .handler = &xorgSignalHandler },
|
||||||
|
.mask = std.os.empty_sigset,
|
||||||
|
.flags = 0,
|
||||||
|
};
|
||||||
|
try std.os.sigaction(std.os.SIG.TERM, &act, null);
|
||||||
|
|
||||||
_ = std.os.waitpid(xorg_pid, 0);
|
_ = std.os.waitpid(xorg_pid, 0);
|
||||||
interop.xcb.xcb_disconnect(xcb);
|
interop.xcb.xcb_disconnect(xcb);
|
||||||
|
|
||||||
_ = std.c.kill(x_pid, 0);
|
status = std.c.kill(x_pid, 0);
|
||||||
if (std.c._errno().* != interop.ESRCH) {
|
if (std.os.errno(status) != .SRCH) {
|
||||||
_ = std.c.kill(x_pid, interop.SIGTERM);
|
_ = std.c.kill(x_pid, std.os.SIG.TERM);
|
||||||
_ = std.c.waitpid(x_pid, &status, 0);
|
_ = std.c.waitpid(x_pid, &status, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ const enums = @import("../enums.zig");
|
||||||
const Animation = enums.Animation;
|
const Animation = enums.Animation;
|
||||||
const Input = enums.Input;
|
const Input = enums.Input;
|
||||||
|
|
||||||
const Config = @This();
|
|
||||||
|
|
||||||
animation: Animation = .none,
|
animation: Animation = .none,
|
||||||
asterisk: u8 = '*',
|
asterisk: u8 = '*',
|
||||||
bg: u8 = 0,
|
bg: u8 = 0,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
const Lang = @This();
|
|
||||||
|
|
||||||
capslock: []const u8 = "capslock",
|
capslock: []const u8 = "capslock",
|
||||||
err_alloc: []const u8 = "failed memory allocation",
|
err_alloc: []const u8 = "failed memory allocation",
|
||||||
err_bounds: []const u8 = "out-of-bounds index",
|
err_bounds: []const u8 = "out-of-bounds index",
|
||||||
|
|
|
@ -44,9 +44,6 @@ pub const passwd = extern struct {
|
||||||
pw_shell: [*:0]u8,
|
pw_shell: [*:0]u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SIGTERM: c_int = 15;
|
|
||||||
pub const ESRCH: c_int = 3;
|
|
||||||
|
|
||||||
pub const _POSIX_HOST_NAME_MAX: c_int = 0xFF;
|
pub const _POSIX_HOST_NAME_MAX: c_int = 0xFF;
|
||||||
pub const _SC_HOST_NAME_MAX: c_int = 0xB4;
|
pub const _SC_HOST_NAME_MAX: c_int = 0xB4;
|
||||||
|
|
||||||
|
|
13
src/main.zig
13
src/main.zig
|
@ -23,7 +23,17 @@ const utils = @import("tui/utils.zig");
|
||||||
const Ini = ini.Ini;
|
const Ini = ini.Ini;
|
||||||
const termbox = interop.termbox;
|
const termbox = interop.termbox;
|
||||||
|
|
||||||
|
var session_pid: std.os.pid_t = -1;
|
||||||
pub fn signalHandler(i: c_int) callconv(.C) void {
|
pub fn signalHandler(i: c_int) callconv(.C) void {
|
||||||
|
if (session_pid == 0) return;
|
||||||
|
|
||||||
|
// Forward signal to session to clean up
|
||||||
|
if (session_pid > 0) {
|
||||||
|
_ = std.c.kill(session_pid, i);
|
||||||
|
var status: c_int = 0;
|
||||||
|
_ = std.c.waitpid(-1, &status, 0);
|
||||||
|
}
|
||||||
|
|
||||||
termbox.tb_shutdown();
|
termbox.tb_shutdown();
|
||||||
std.c.exit(i);
|
std.c.exit(i);
|
||||||
}
|
}
|
||||||
|
@ -532,7 +542,7 @@ pub fn main() !void {
|
||||||
var shared_err = try SharedError.init();
|
var shared_err = try SharedError.init();
|
||||||
defer shared_err.deinit();
|
defer shared_err.deinit();
|
||||||
|
|
||||||
const session_pid = try std.os.fork();
|
session_pid = try std.os.fork();
|
||||||
if (session_pid == 0) {
|
if (session_pid == 0) {
|
||||||
auth.authenticate(allocator, config, desktop, login, &password) catch |err| {
|
auth.authenticate(allocator, config, desktop, login, &password) catch |err| {
|
||||||
shared_err.writeError(err);
|
shared_err.writeError(err);
|
||||||
|
@ -542,6 +552,7 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = std.os.waitpid(session_pid, 0);
|
_ = std.os.waitpid(session_pid, 0);
|
||||||
|
session_pid = -1;
|
||||||
|
|
||||||
var auth_err = shared_err.readError();
|
var auth_err = shared_err.readError();
|
||||||
if (auth_err) |err| {
|
if (auth_err) |err| {
|
||||||
|
|
Loading…
Reference in New Issue