subprocess.cpp raw
1 // Copyright (c) 2025-present The Limenka Knots developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <limenka-build-config.h> // IWYU pragma: keep
6
7 #if !((defined _MSC_VER) || (defined __MINGW32__))
8
9 #if HAVE_CLOSE_RANGE_LINUX
10 #ifndef _GNU_SOURCE
11 #define _GNU_SOURCE
12 #endif
13 #include <linux/close_range.h>
14 #endif
15
16 #include <limits.h>
17 #include <sys/types.h>
18 #include <sys/time.h>
19 #include <sys/resource.h>
20 #include <unistd.h>
21
22 namespace subprocess {
23 namespace detail {
24
25 void subprocess_close_all_fds(const int except_fd)
26 {
27 #if HAVE_CLOSE_RANGE_GENERIC || HAVE_CLOSE_RANGE_LINUX
28 if (except_fd < 3) {
29 if (!close_range(3, UINT_MAX, 0)) return;
30 } else if (except_fd == 3) {
31 if (!close_range(4, UINT_MAX, 0)) return;
32 } else {
33 if (!(close_range(3, except_fd - 1, 0) || close_range(except_fd + 1, UINT_MAX, 0))) return;
34 }
35 #endif
36
37 unsigned int max_fd;
38
39 struct rlimit limit_fds;
40 if (getrlimit(RLIMIT_NOFILE, &limit_fds) == 0 && limit_fds.rlim_cur < INT_MAX) {
41 max_fd = limit_fds.rlim_cur;
42 } else {
43 max_fd = INT_MAX;
44 }
45
46 for (int fd = max_fd; fd > 2; --fd) {
47 if (fd == except_fd) continue;
48 close(fd);
49 }
50 }
51
52 } // namespace detail
53 } // namespace subprocess
54
55 #endif // !((defined _MSC_VER) || (defined __MINGW32__))
56