mirror of
https://github.com/swaywm/sway.git
synced 2025-10-29 05:40:18 -04:00
Use pthread_atfork() to restore signals and NOFILE limit
This ensures these functions are always called (even when a library such as wlroots or libc perform the fork) and removes the need to manually call them.
This commit is contained in:
parent
86ff19fade
commit
0e19d85d37
7 changed files with 23 additions and 28 deletions
|
|
@ -164,9 +164,6 @@ void server_fini(struct sway_server *server);
|
||||||
bool server_start(struct sway_server *server);
|
bool server_start(struct sway_server *server);
|
||||||
void server_run(struct sway_server *server);
|
void server_run(struct sway_server *server);
|
||||||
|
|
||||||
void restore_nofile_limit(void);
|
|
||||||
void restore_signals(void);
|
|
||||||
|
|
||||||
void handle_new_output(struct wl_listener *listener, void *data);
|
void handle_new_output(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ libudev = wlroots_features['libinput_backend'] ? dependency('libudev') : null_de
|
||||||
math = cc.find_library('m')
|
math = cc.find_library('m')
|
||||||
rt = cc.find_library('rt')
|
rt = cc.find_library('rt')
|
||||||
xcb_icccm = wlroots_features['xwayland'] ? dependency('xcb-icccm') : null_dep
|
xcb_icccm = wlroots_features['xwayland'] ? dependency('xcb-icccm') : null_dep
|
||||||
threads = dependency('threads') # for pthread_setschedparam
|
threads = dependency('threads') # for pthread_setschedparam and pthread_atfork
|
||||||
|
|
||||||
if get_option('sd-bus-provider') == 'auto'
|
if get_option('sd-bus-provider') == 'auto'
|
||||||
if not get_option('tray').disabled()
|
if not get_option('tray').disabled()
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,6 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
|
||||||
// Fork process
|
// Fork process
|
||||||
pid_t child = fork();
|
pid_t child = fork();
|
||||||
if (child == 0) {
|
if (child == 0) {
|
||||||
restore_nofile_limit();
|
|
||||||
restore_signals();
|
|
||||||
setsid();
|
setsid();
|
||||||
|
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
|
|
|
||||||
|
|
@ -213,8 +213,6 @@ static void invoke_swaybar(struct bar_config *bar) {
|
||||||
sway_log(SWAY_ERROR, "Failed to create fork for swaybar");
|
sway_log(SWAY_ERROR, "Failed to create fork for swaybar");
|
||||||
return;
|
return;
|
||||||
} else if (pid == 0) {
|
} else if (pid == 0) {
|
||||||
restore_nofile_limit();
|
|
||||||
restore_signals();
|
|
||||||
if (!sway_set_cloexec(sockets[1], false)) {
|
if (!sway_set_cloexec(sockets[1], false)) {
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1060,8 +1060,6 @@ static bool _spawn_swaybg(char **command) {
|
||||||
sway_log_errno(SWAY_ERROR, "fork failed");
|
sway_log_errno(SWAY_ERROR, "fork failed");
|
||||||
return false;
|
return false;
|
||||||
} else if (pid == 0) {
|
} else if (pid == 0) {
|
||||||
restore_nofile_limit();
|
|
||||||
restore_signals();
|
|
||||||
if (!sway_set_cloexec(sockets[1], false)) {
|
if (!sway_set_cloexec(sockets[1], false)) {
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
sway/main.c
38
sway/main.c
|
|
@ -1,5 +1,6 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -121,6 +122,16 @@ static bool detect_suid(void) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void restore_nofile_limit(void) {
|
||||||
|
if (original_nofile_rlimit.rlim_cur == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (setrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "Failed to restore max open files limit: "
|
||||||
|
"setrlimit(NOFILE) failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void increase_nofile_limit(void) {
|
static void increase_nofile_limit(void) {
|
||||||
if (getrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
|
if (getrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
|
||||||
sway_log_errno(SWAY_ERROR, "Failed to bump max open files limit: "
|
sway_log_errno(SWAY_ERROR, "Failed to bump max open files limit: "
|
||||||
|
|
@ -135,17 +146,10 @@ static void increase_nofile_limit(void) {
|
||||||
"setrlimit(NOFILE) failed");
|
"setrlimit(NOFILE) failed");
|
||||||
sway_log(SWAY_INFO, "Running with %d max open files",
|
sway_log(SWAY_INFO, "Running with %d max open files",
|
||||||
(int)original_nofile_rlimit.rlim_cur);
|
(int)original_nofile_rlimit.rlim_cur);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void restore_nofile_limit(void) {
|
|
||||||
if (original_nofile_rlimit.rlim_cur == 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (setrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
|
|
||||||
sway_log_errno(SWAY_ERROR, "Failed to restore max open files limit: "
|
pthread_atfork(NULL, NULL, restore_nofile_limit);
|
||||||
"setrlimit(NOFILE) failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int term_signal(int signal, void *data) {
|
static int term_signal(int signal, void *data) {
|
||||||
|
|
@ -153,6 +157,14 @@ static int term_signal(int signal, void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void restore_signals(void) {
|
||||||
|
sigset_t set;
|
||||||
|
sigemptyset(&set);
|
||||||
|
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||||
|
signal(SIGCHLD, SIG_DFL);
|
||||||
|
signal(SIGPIPE, SIG_DFL);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_signals(void) {
|
static void init_signals(void) {
|
||||||
wl_event_loop_add_signal(server.wl_event_loop, SIGTERM, term_signal, NULL);
|
wl_event_loop_add_signal(server.wl_event_loop, SIGTERM, term_signal, NULL);
|
||||||
wl_event_loop_add_signal(server.wl_event_loop, SIGINT, term_signal, NULL);
|
wl_event_loop_add_signal(server.wl_event_loop, SIGINT, term_signal, NULL);
|
||||||
|
|
@ -162,14 +174,8 @@ static void init_signals(void) {
|
||||||
|
|
||||||
// prevent ipc write errors from crashing sway
|
// prevent ipc write errors from crashing sway
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
}
|
|
||||||
|
|
||||||
void restore_signals(void) {
|
pthread_atfork(NULL, NULL, restore_signals);
|
||||||
sigset_t set;
|
|
||||||
sigemptyset(&set);
|
|
||||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
|
||||||
signal(SIGCHLD, SIG_DFL);
|
|
||||||
signal(SIGPIPE, SIG_DFL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_debug_flag(const char *flag) {
|
void enable_debug_flag(const char *flag) {
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ bool swaynag_spawn(const char *swaynag_command,
|
||||||
sway_log(SWAY_ERROR, "Failed to create fork for swaynag");
|
sway_log(SWAY_ERROR, "Failed to create fork for swaynag");
|
||||||
goto failed;
|
goto failed;
|
||||||
} else if (pid == 0) {
|
} else if (pid == 0) {
|
||||||
restore_nofile_limit();
|
|
||||||
if (!sway_set_cloexec(sockets[1], false)) {
|
if (!sway_set_cloexec(sockets[1], false)) {
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
@ -148,4 +147,3 @@ void swaynag_show(struct swaynag_instance *swaynag) {
|
||||||
close(swaynag->fd[1]);
|
close(swaynag->fd[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue