Skip to main content

rlimit/
utils.rs

1//! Some tools for operating resource limits.
2
3use std::io;
4
5/// Returns the value of `kern.maxfilesperproc` by sysctl.
6/// # Errors
7/// Returns an error if any syscall failed.
8// #begin-codegen KERN_MAXFILESPERPROC
9// generated from rust-lang/libc 6568dacc81b2dd2edae571ab97bbca94bc662595
10#[cfg(any(
11    any(target_os = "macos", target_os = "ios"),
12    target_os = "dragonfly",
13    target_os = "freebsd",
14))]
15// #end-codegen KERN_MAXFILESPERPROC
16pub fn get_kern_max_files_per_proc() -> io::Result<u64> {
17    use std::mem;
18    use std::ptr;
19
20    let mut mib = [libc::CTL_KERN, libc::KERN_MAXFILESPERPROC];
21    let mut max_files_per_proc: libc::c_int = 0;
22    let mut oldlen = mem::size_of::<libc::c_int>();
23    let ret = unsafe {
24        libc::sysctl(
25            mib.as_mut_ptr(),
26            2,
27            &mut max_files_per_proc as *mut libc::c_int as *mut libc::c_void,
28            &mut oldlen,
29            ptr::null_mut(),
30            0,
31        )
32    };
33
34    if ret < 0 {
35        return Err(io::Error::last_os_error());
36    }
37
38    debug_assert!(max_files_per_proc >= 0);
39    Ok(max_files_per_proc as u64)
40}
41
42/// Try to increase NOFILE limit and return the current soft limit.
43///
44/// `lim` is the expected limit which can be up to [`u64::MAX`].
45///
46/// This function does nothing if `RLIMIT_NOFILE` does not exist on current platform.
47///
48/// # Errors
49/// Returns an error if any syscall failed.
50pub fn increase_nofile_limit(lim: u64) -> io::Result<u64> {
51    // #begin-codegen RLIMIT_NOFILE
52    // generated from rust-lang/libc 6568dacc81b2dd2edae571ab97bbca94bc662595
53    #[cfg(any(
54        all(target_os = "linux", target_env = "gnu"),
55        all(
56            target_os = "linux",
57            target_env = "musl",
58            any(
59                target_arch = "x86",
60                target_arch = "mips",
61                target_arch = "powerpc",
62                target_arch = "hexagon",
63                target_arch = "arm"
64            )
65        ),
66        all(
67            target_os = "linux",
68            target_env = "musl",
69            any(
70                target_arch = "x86_64",
71                target_arch = "aarch64",
72                target_arch = "mips64",
73                target_arch = "powerpc64"
74            )
75        ),
76        all(
77            target_os = "linux",
78            target_env = "uclibc",
79            any(target_arch = "mips", target_arch = "mips64")
80        ),
81        any(target_os = "freebsd", target_os = "dragonfly"),
82        any(target_os = "macos", target_os = "ios"),
83        any(target_os = "openbsd", target_os = "netbsd"),
84        target_os = "android",
85        target_os = "emscripten",
86        target_os = "fuchsia",
87        target_os = "haiku",
88        target_os = "solarish",
89    ))]
90    // #end-codegen RLIMIT_NOFILE
91    {
92        use super::Resource;
93
94        let (soft, hard) = Resource::NOFILE.get()?;
95
96        if soft >= hard {
97            return Ok(hard);
98        }
99
100        if soft >= lim {
101            return Ok(soft);
102        }
103
104        let mut lim = lim;
105
106        lim = lim.min(hard);
107
108        // #begin-codegen KERN_MAXFILESPERPROC
109        // generated from rust-lang/libc 6568dacc81b2dd2edae571ab97bbca94bc662595
110        #[cfg(any(
111            any(target_os = "macos", target_os = "ios"),
112            target_os = "dragonfly",
113            target_os = "freebsd",
114        ))]
115        // #end-codegen KERN_MAXFILESPERPROC
116        {
117            lim = lim.min(get_kern_max_files_per_proc()?)
118        }
119
120        Resource::NOFILE.set(lim, hard)?;
121
122        Ok(lim)
123    }
124
125    // #begin-codegen not RLIMIT_NOFILE
126    // generated from rust-lang/libc 6568dacc81b2dd2edae571ab97bbca94bc662595
127    #[cfg(not(any(
128        all(target_os = "linux", target_env = "gnu"),
129        all(
130            target_os = "linux",
131            target_env = "musl",
132            any(
133                target_arch = "x86",
134                target_arch = "mips",
135                target_arch = "powerpc",
136                target_arch = "hexagon",
137                target_arch = "arm"
138            )
139        ),
140        all(
141            target_os = "linux",
142            target_env = "musl",
143            any(
144                target_arch = "x86_64",
145                target_arch = "aarch64",
146                target_arch = "mips64",
147                target_arch = "powerpc64"
148            )
149        ),
150        all(
151            target_os = "linux",
152            target_env = "uclibc",
153            any(target_arch = "mips", target_arch = "mips64")
154        ),
155        any(target_os = "freebsd", target_os = "dragonfly"),
156        any(target_os = "macos", target_os = "ios"),
157        any(target_os = "openbsd", target_os = "netbsd"),
158        target_os = "android",
159        target_os = "emscripten",
160        target_os = "fuchsia",
161        target_os = "haiku",
162        target_os = "solarish",
163    )))]
164    // #end-codegen not RLIMIT_NOFILE
165    {
166        Ok(lim)
167    }
168}