rlimit/
lib.rs

1//! rlimit - Resource limits.
2//!
3//! ## Set resource limit
4//! ```no_run
5//! # #[cfg(unix)]
6//! # {
7//! use rlimit::{setrlimit, Resource};
8//!
9//! const DEFAULT_SOFT_LIMIT: u64 = 4 * 1024 * 1024;
10//! const DEFAULT_HARD_LIMIT: u64 = 8 * 1024 * 1024;
11//! assert!(Resource::FSIZE.set(DEFAULT_SOFT_LIMIT, DEFAULT_HARD_LIMIT).is_ok());
12//!
13//! let soft = 16384;
14//! let hard = soft * 2;
15//! assert!(setrlimit(Resource::NOFILE, soft, hard).is_ok());
16//! # }
17//! ```
18//!
19//! ## Get resource limit
20//! ```no_run
21//! # #[cfg(unix)]
22//! # {
23//! use rlimit::{getrlimit, Resource};
24//!
25//! assert!(Resource::NOFILE.get().is_ok());
26//! assert_eq!(getrlimit(Resource::CPU).unwrap(), (rlimit::INFINITY, rlimit::INFINITY));
27//! # }
28//! ```
29//!
30//! ## Windows
31//!
32//! Windows does not have Unix-like resource limits.
33//! It only supports changing the number of simultaneously open files currently permitted at the stdio level.
34//!
35//! See the official documentation of
36//! [`_getmaxstdio`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getmaxstdio?view=msvc-170)
37//! and
38//! [`_setmaxstdio`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmaxstdio?view=msvc-170).
39//!
40//! ```no_run
41//! # #[cfg(windows)]
42//! # {
43//! println!("{}", rlimit::getmaxstdio()); // 512
44//! rlimit::setmaxstdio(2048).unwrap();
45//! println!("{}", rlimit::getmaxstdio()); // 2048
46//! # }
47//! ```
48//!
49//! ## Increase NOFILE limit
50//! See the example [nofile](https://github.com/Nugine/rlimit/blob/main/examples/nofile.rs).
51//!
52//! You can also use the tool function [`rlimit::increase_nofile_limit`][`crate::increase_nofile_limit`]
53//!
54//! ```no_run
55//! rlimit::increase_nofile_limit(10240).unwrap();
56//! rlimit::increase_nofile_limit(u64::MAX).unwrap();
57//! ```
58//!
59//! # Troubleshoot
60//!
61//! ## Failed to increase NOFILE to hard limit on macOS
62//! On macOS, getrlimit by default reports that the hard limit is
63//! unlimited, but there is usually a stricter hard limit discoverable
64//! via sysctl (`kern.maxfilesperproc`). Failing to discover this secret stricter hard limit will
65//! cause the call to setrlimit to fail.
66//!
67//! [`rlimit::increase_nofile_limit`][`crate::increase_nofile_limit`]
68//! respects `kern.maxfilesperproc`.
69//!
70
71#![cfg_attr(docsrs, feature(doc_cfg))]
72#![deny(
73    missing_docs,
74    missing_debug_implementations,
75    clippy::all,
76    clippy::pedantic,
77    clippy::cargo
78)]
79#![allow(
80    clippy::option_if_let_else,  // I don't like it. The match expression is more readable.
81)]
82
83#[allow(unused_macros)]
84macro_rules! group {
85    ($($item:item)*) => {
86        $($item)*
87    }
88}
89
90#[cfg(any(doc, windows))]
91group! {
92    mod windows;
93
94    #[doc(inline)]
95    pub use self::windows::*;
96}
97
98#[cfg(any(doc, unix))]
99group! {
100    mod bindings;
101
102    mod unix;
103    mod resource;
104
105    #[doc(inline)]
106    pub use self::unix::*;
107
108    #[doc(inline)]
109    pub use self::resource::Resource;
110}
111
112#[cfg(any(doc, target_os = "linux", target_os = "android"))]
113group! {
114    mod proc_limits;
115
116    #[doc(inline)]
117    pub use self::proc_limits::*;
118}
119
120mod tools;
121#[doc(inline)]
122pub use self::tools::*;
123
124#[cfg(test)]
125mod tests {
126    #[test]
127    fn build_cfg() {
128        if cfg!(target_os = "linux") || cfg!(target_os = "android") {
129            assert!(cfg!(rlimit__has_prlimit64));
130            assert!(cfg!(not(rlimit__get_kern_max_files_per_proc)));
131        }
132
133        if cfg!(target_os = "macos") {
134            assert!(cfg!(not(rlimit__has_prlimit64)));
135            assert!(cfg!(rlimit__get_kern_max_files_per_proc));
136        }
137    }
138}