mirror of https://github.com/fairyglade/ly.git
Clean up when SIGTERM is received (#597)
* clean up child processes on SIGTERM * small code improvement * consistency.. i guess?
This commit is contained in:
parent
365933e39e
commit
7c71dee3db
|
@ -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.
|
||||
+ 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).
|
||||
+ 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.
|
||||
|
|
48
src/auth.zig
48
src/auth.zig
|
@ -10,6 +10,16 @@ const utmp = interop.utmp;
|
|||
const Utmp = utmp.utmp;
|
||||
const SharedError = @import("SharedError.zig");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
var child_pid: std.os.pid_t = 0;
|
||||
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 {
|
||||
var tty_buffer: [2]u8 = undefined;
|
||||
const tty_str = try std.fmt.bufPrintZ(&tty_buffer, "{d}", .{config.tty});
|
||||
|
@ -86,8 +96,8 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
|
|||
var shared_err = try SharedError.init();
|
||||
defer shared_err.deinit();
|
||||
|
||||
const pid = try std.os.fork();
|
||||
if (pid == 0) {
|
||||
child_pid = try std.os.fork();
|
||||
if (child_pid == 0) {
|
||||
// Set the user information
|
||||
status = interop.initgroups(pwd.pw_name, pwd.pw_gid);
|
||||
if (status != 0) {
|
||||
|
@ -159,10 +169,18 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
|
|||
}
|
||||
|
||||
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
|
||||
_ = std.os.waitpid(pid, 0);
|
||||
_ = std.os.waitpid(child_pid, 0);
|
||||
|
||||
removeUtmpEntry(&entry);
|
||||
|
||||
|
@ -400,20 +418,21 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, config: Config, de
|
|||
std.os.exit(0);
|
||||
}
|
||||
|
||||
var status: c_int = 0;
|
||||
var ok: c_int = undefined;
|
||||
var xcb: ?*interop.xcb.xcb_connection_t = null;
|
||||
while (ok != 0) {
|
||||
xcb = interop.xcb.xcb_connect(null, null);
|
||||
ok = interop.xcb.xcb_connection_has_error(xcb);
|
||||
_ = std.c.kill(pid, 0);
|
||||
if (std.c._errno().* == interop.ESRCH and ok != 0) return;
|
||||
status = std.c.kill(pid, 0);
|
||||
if (std.os.errno(status) == .SRCH and ok != 0) return;
|
||||
}
|
||||
|
||||
// X Server detaches from the process.
|
||||
// PID can be fetched from /tmp/X{d}.lock
|
||||
const x_pid = try getXPid(display_num);
|
||||
|
||||
const xorg_pid = try std.os.fork();
|
||||
xorg_pid = try std.os.fork();
|
||||
if (xorg_pid == 0) {
|
||||
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);
|
||||
|
@ -421,13 +440,20 @@ fn executeX11Cmd(shell: [*:0]const u8, pw_dir: [*:0]const u8, config: Config, de
|
|||
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);
|
||||
interop.xcb.xcb_disconnect(xcb);
|
||||
|
||||
_ = std.c.kill(x_pid, 0);
|
||||
if (std.c._errno().* != interop.ESRCH) {
|
||||
_ = std.c.kill(x_pid, interop.SIGTERM);
|
||||
status = std.c.kill(x_pid, 0);
|
||||
if (std.os.errno(status) != .SRCH) {
|
||||
_ = std.c.kill(x_pid, std.os.SIG.TERM);
|
||||
_ = std.c.waitpid(x_pid, &status, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ const enums = @import("../enums.zig");
|
|||
const Animation = enums.Animation;
|
||||
const Input = enums.Input;
|
||||
|
||||
const Config = @This();
|
||||
|
||||
animation: Animation = .none,
|
||||
asterisk: u8 = '*',
|
||||
bg: u8 = 0,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
const Lang = @This();
|
||||
|
||||
capslock: []const u8 = "capslock",
|
||||
err_alloc: []const u8 = "failed memory allocation",
|
||||
err_bounds: []const u8 = "out-of-bounds index",
|
||||
|
|
|
@ -44,9 +44,6 @@ pub const passwd = extern struct {
|
|||
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 _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 termbox = interop.termbox;
|
||||
|
||||
var session_pid: std.os.pid_t = -1;
|
||||
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(session_pid, &status, 0);
|
||||
}
|
||||
|
||||
termbox.tb_shutdown();
|
||||
std.c.exit(i);
|
||||
}
|
||||
|
@ -532,7 +542,7 @@ pub fn main() !void {
|
|||
var shared_err = try SharedError.init();
|
||||
defer shared_err.deinit();
|
||||
|
||||
const session_pid = try std.os.fork();
|
||||
session_pid = try std.os.fork();
|
||||
if (session_pid == 0) {
|
||||
auth.authenticate(allocator, config, desktop, login, &password) catch |err| {
|
||||
shared_err.writeError(err);
|
||||
|
@ -542,6 +552,7 @@ pub fn main() !void {
|
|||
}
|
||||
|
||||
_ = std.os.waitpid(session_pid, 0);
|
||||
session_pid = -1;
|
||||
|
||||
var auth_err = shared_err.readError();
|
||||
if (auth_err) |err| {
|
||||
|
|
Loading…
Reference in New Issue