diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 99b517d8c2f..6b6457dbc22 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -208,7 +208,7 @@ static int get_max_fd(void) { return (int) (m - 1); } -int close_all_fds(int except[], size_t n_except) { +int close_all_fds_full(int except[], size_t n_except, bool allow_alloc) { static bool have_close_range = true; /* Assume we live in the future */ _cleanup_closedir_ DIR *d = NULL; int r = 0; @@ -274,7 +274,7 @@ int close_all_fds(int except[], size_t n_except) { /* Fallback for when close_range() is not supported */ opendir_fallback: - d = opendir("/proc/self/fd"); + d = allow_alloc ? opendir("/proc/self/fd") : NULL; if (d) { struct dirent *de; @@ -302,8 +302,8 @@ int close_all_fds(int except[], size_t n_except) { return r; } - /* Fallback for when /proc isn't available (for example in chroots) by brute-forcing through the file - * descriptor table. */ + /* Fallback for when /proc isn't available (for example in chroots) or when we cannot allocate by + * brute-forcing through the file descriptor table. */ int max_fd = get_max_fd(); if (max_fd < 0) diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index d3c2944d869..61b6684cb3c 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -56,7 +56,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(DIR*, closedir, NULL); int fd_nonblock(int fd, bool nonblock); int fd_cloexec(int fd, bool cloexec); -int close_all_fds(int except[], size_t n_except); +int close_all_fds_full(int except[], size_t n_except, bool allow_alloc); +static inline int close_all_fds(int except[], size_t n_except) { + return close_all_fds_full(except, n_except, true); +} int same_fd(int a, int b); diff --git a/src/shared/exec-util.c b/src/shared/exec-util.c index 42f6c4d75ad..cffa3fe96e7 100644 --- a/src/shared/exec-util.c +++ b/src/shared/exec-util.c @@ -452,7 +452,7 @@ _noreturn_ void freeze(void) { log_close(); /* Make sure nobody waits for us on a socket anymore */ - (void) close_all_fds(NULL, 0); + (void) close_all_fds_full(NULL, 0, false); sync();