From 6c2bbb42ea612831da826cd80fdf71e8ec7c6079 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 17 Jul 2022 00:47:20 +0000 Subject: [PATCH 1/2] common: Add helpers for raising/lowering FD limit Signed-off-by: Joshua Ashton --- include/common/fd_util.h | 8 ++++++++ src/common/fd_util.c | 39 +++++++++++++++++++++++++++++++++++++++ src/common/meson.build | 1 + 3 files changed, 48 insertions(+) create mode 100644 include/common/fd_util.h create mode 100644 src/common/fd_util.c diff --git a/include/common/fd_util.h b/include/common/fd_util.h new file mode 100644 index 00000000..9819f252 --- /dev/null +++ b/include/common/fd_util.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __LABWC_FD_UTIL_H +#define __LABWC_FD_UTIL_H + +void increase_nofile_limit(void); +void restore_nofile_limit(void); + +#endif /* __LABWC_FD_UTIL_H */ diff --git a/src/common/fd_util.c b/src/common/fd_util.c new file mode 100644 index 00000000..f45cad83 --- /dev/null +++ b/src/common/fd_util.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define _POSIX_C_SOURCE 200809L + +#include +#include + +#include "common/fd_util.h" + +static struct rlimit original_nofile_rlimit = {0}; + +void +increase_nofile_limit(void) +{ + if (getrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) { + wlr_log_errno(WLR_ERROR, "Failed to bump max open files limit: getrlimit(NOFILE) failed"); + return; + } + + struct rlimit new_rlimit = original_nofile_rlimit; + new_rlimit.rlim_cur = new_rlimit.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &new_rlimit) != 0) { + wlr_log_errno(WLR_ERROR, "Failed to bump max open files limit: setrlimit(NOFILE) failed"); + + wlr_log(WLR_INFO, "Running with %d max open files", + (int)original_nofile_rlimit.rlim_cur); + } +} + +void +restore_nofile_limit(void) +{ + if (original_nofile_rlimit.rlim_cur == 0) { + return; + } + + if (setrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) { + wlr_log_errno(WLR_ERROR, "Failed to restore max open files limit: setrlimit(NOFILE) failed"); + } +} diff --git a/src/common/meson.build b/src/common/meson.build index d04e9f63..3b099537 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -1,6 +1,7 @@ labwc_sources += files( 'buf.c', 'dir.c', + 'fd_util.c', 'font.c', 'grab-file.c', 'nodename.c', From 722aa042b7a270d8da3f2a7c78c77dd59d67eb9b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 17 Jul 2022 00:49:26 +0000 Subject: [PATCH 2/2] main: Increase FD limit This defaults to 1024, which is tiny, but is a requirement for processes using the deprecated `select` function. We must reset this back whenever we fork to start a new process, as this is inherited, and breaks applications using `select` otherwise. Signed-off-by: Joshua Ashton --- src/common/spawn.c | 3 +++ src/main.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/common/spawn.c b/src/common/spawn.c index d8d0abd4..349f65fc 100644 --- a/src/common/spawn.c +++ b/src/common/spawn.c @@ -10,6 +10,7 @@ #include #include #include "common/spawn.h" +#include "common/fd_util.h" void spawn_async_no_shell(char const *command) @@ -39,6 +40,8 @@ spawn_async_no_shell(char const *command) wlr_log(WLR_ERROR, "unable to fork()"); goto out; case 0: + restore_nofile_limit(); + setsid(); sigset_t set; sigemptyset(&set); diff --git a/src/main.c b/src/main.c index 1e2dc1ee..0cb521b5 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "theme.h" #include "xbm/xbm.h" #include "menu/menu.h" +#include "common/fd_util.h" struct rcxml rc = { 0 }; @@ -85,6 +86,8 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } + increase_nofile_limit(); + struct server server = { 0 }; server_init(&server); server_start(&server);