mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-31 13:57:31 +03:00
core: handle SIGUSR2 as a signal to reload the config
This PR adds the infrastructure to handle POSIX signals. The only signal currently handled is SIGUSR2, which will reload the config. SIGPIPE is set up to be ignored in the global state and should not be changed as macOS relies on SIGPIPE being ignored for proper operation. Note that any signal not configured by Ghostty will generally result in termination of the process. Fixes #7747
This commit is contained in:
12
src/App.zig
12
src/App.zig
@ -20,6 +20,7 @@ const font = @import("font/main.zig");
|
||||
const internal_os = @import("os/main.zig");
|
||||
const macos = @import("macos");
|
||||
const objc = @import("objc");
|
||||
const Signals = @import("Signals.zig");
|
||||
|
||||
const log = std.log.scoped(.app);
|
||||
|
||||
@ -74,6 +75,9 @@ config_conditional_state: configpkg.ConditionalState,
|
||||
/// if they are the first surface.
|
||||
first: bool = true,
|
||||
|
||||
/// Structure for managing POSIX signal handlers.
|
||||
signals: Signals = .init,
|
||||
|
||||
pub const CreateError = Allocator.Error || font.SharedGridSet.InitError;
|
||||
|
||||
/// Create a new app instance. This returns a stable pointer to the app
|
||||
@ -104,7 +108,11 @@ pub fn init(
|
||||
.mailbox = .{},
|
||||
.font_grid_set = font_grid_set,
|
||||
.config_conditional_state = .{},
|
||||
.signals = .init,
|
||||
};
|
||||
|
||||
// Start handling POSIX signals (this is a no-op on non-POSIX systems).
|
||||
self.signals.start(self);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *App) void {
|
||||
@ -257,6 +265,7 @@ fn drainMailbox(self: *App, rt_app: *apprt.App) !void {
|
||||
log.debug("mailbox message={s}", .{@tagName(message)});
|
||||
switch (message) {
|
||||
.open_config => try self.performAction(rt_app, .open_config),
|
||||
.reload_config => try self.performAction(rt_app, .reload_config),
|
||||
.new_window => |msg| try self.newWindow(rt_app, msg),
|
||||
.close => |surface| self.closeSurface(surface),
|
||||
.surface_message => |msg| try self.surfaceMessage(msg.surface, msg.message),
|
||||
@ -518,6 +527,9 @@ pub const Message = union(enum) {
|
||||
// Open the configuration file
|
||||
open_config: void,
|
||||
|
||||
// Reload the configuration file
|
||||
reload_config: void,
|
||||
|
||||
/// Create a new terminal window.
|
||||
new_window: NewWindow,
|
||||
|
||||
|
52
src/Signals.zig
Normal file
52
src/Signals.zig
Normal file
@ -0,0 +1,52 @@
|
||||
//! Structure for managing POSIX signal handlers.
|
||||
const Signals = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const posix = std.posix;
|
||||
|
||||
const App = @import("./App.zig");
|
||||
|
||||
const log = std.log.scoped(.signals);
|
||||
|
||||
/// Global variable to store core app. This needs to be
|
||||
/// a global since it needs to be accessed from a POSIX
|
||||
/// signal handler.
|
||||
var _app: ?*App = null;
|
||||
|
||||
pub const init: Signals = .{};
|
||||
|
||||
// Start handling POSIX signals. This _should not_ modify the handler for
|
||||
// SIGPIPE as that's handled in the global state initialization.
|
||||
pub fn start(_: *Signals, app: *App) void {
|
||||
// Only posix systems.
|
||||
if (comptime builtin.os.tag == .windows) return;
|
||||
|
||||
_app = app;
|
||||
|
||||
var sa: posix.Sigaction = .{
|
||||
.handler = .{ .handler = handler },
|
||||
.mask = posix.empty_sigset,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
// SIGUSR2 => reload config
|
||||
posix.sigaction(posix.SIG.USR2, &sa, null);
|
||||
}
|
||||
|
||||
/// POSIX signal handler. This must follow all the rules for POSIX signal
|
||||
/// handlers. In general it's best to send a message that's handled by other
|
||||
/// threads.
|
||||
fn handler(signal: c_int) callconv(.c) void {
|
||||
// Failsafe in case we get called on a non-POSIX system.
|
||||
const app = _app orelse return;
|
||||
|
||||
log.info("POSIX signal received: {d}", .{signal});
|
||||
|
||||
switch (signal) {
|
||||
posix.SIG.USR2 => {
|
||||
_ = app.mailbox.push(.reload_config, .instant);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user