-
Notifications
You must be signed in to change notification settings - Fork 721
Add getrlimit(2) and setrlimit(2) #879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
63c438f
aaf89e4
f69bedb
2c4d804
13f75c1
7b537e3
8c18615
de89045
7242607
1c629ad
f87978b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| use std::mem; | ||
|
|
||
| use libc::{self, c_int}; | ||
| pub use libc::{rlimit, rlim_t, RLIM_INFINITY}; | ||
|
|
||
| #[cfg(any(target_os = "linux", | ||
| target_os = "openbsd", | ||
| target_os = "netbsd", | ||
| target_os = "bitrig"))] | ||
|
||
| pub use libc::{RLIM_SAVED_CUR, RLIM_SAVED_MAX}; | ||
|
||
|
|
||
| use {Errno, Result}; | ||
|
|
||
| #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| #[repr(i32)] | ||
| pub enum Resource { | ||
|
||
| // POSIX | ||
| RLIMIT_CORE = libc::RLIMIT_CORE, | ||
| RLIMIT_CPU = libc::RLIMIT_CPU, | ||
| RLIMIT_DATA = libc::RLIMIT_DATA, | ||
| RLIMIT_FSIZE = libc::RLIMIT_FSIZE, | ||
| RLIMIT_NOFILE = libc::RLIMIT_NOFILE, | ||
| RLIMIT_STACK = libc::RLIMIT_STACK, | ||
| RLIMIT_AS = libc::RLIMIT_AS, | ||
| // BSDs and Linux | ||
| #[cfg(all(unix, not(target_os = "solaris")))] | ||
|
||
| RLIMIT_MEMLOCK = libc::RLIMIT_MEMLOCK, | ||
| #[cfg(all(unix, not(target_os = "solaris")))] | ||
| RLIMIT_NPROC = libc::RLIMIT_NPROC, | ||
| #[cfg(all(unix, not(target_os = "solaris")))] | ||
| RLIMIT_RSS = libc::RLIMIT_RSS, | ||
| // Linux-only | ||
|
||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
|
||
| RLIMIT_LOCKS = libc::RLIMIT_LOCKS, | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| RLIMIT_MSGQUEUE = libc::RLIMIT_MSGQUEUE, | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| RLIMIT_NICE = libc::RLIMIT_NICE, | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| RLIMIT_RTPRIO = libc::RLIMIT_RTPRIO, | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| RLIMIT_RTTIME = libc::RLIMIT_RTTIME, | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| RLIMIT_SIGPENDING = libc::RLIMIT_SIGPENDING, | ||
| } | ||
|
||
|
|
||
| #[inline] | ||
| fn rlim_to_option(rlim: rlim_t) -> Option<rlim_t> { | ||
|
||
| match rlim { | ||
| RLIM_INFINITY => None, | ||
| rlim => Some(rlim), | ||
| } | ||
| } | ||
|
|
||
| pub fn getrlimit(resource: Resource) -> Result<(Option<rlim_t>, Option<rlim_t>)> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs a doccomment, should have an example as well.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| let mut rlim: rlimit = unsafe { mem::uninitialized() }; | ||
| let res = unsafe { libc::getrlimit(resource as c_int, &mut rlim as *mut _) }; | ||
| Errno::result(res)?; | ||
| Ok((rlim_to_option(rlim.rlim_cur), rlim_to_option(rlim.rlim_max))) | ||
| } | ||
|
|
||
| pub fn setrlimit(resource: Resource, limit: (Option<rlim_t>, Option<rlim_t>)) -> Result<()> { | ||
|
||
| let mut rlim: rlimit = unsafe { mem::uninitialized() }; | ||
| rlim.rlim_cur = limit.0.unwrap_or(RLIM_INFINITY); | ||
| rlim.rlim_max = limit.1.unwrap_or(RLIM_INFINITY); | ||
|
|
||
| let res = unsafe { libc::setrlimit(resource as c_int, &rlim as *const _) }; | ||
| Errno::result(res).map(drop) | ||
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| use nix::sys::resource::{Resource, getrlimit, setrlimit}; | ||
|
|
||
| #[test] | ||
| pub fn test_resource_limits() { | ||
| let mut limit = getrlimit(Resource::RLIMIT_STACK).unwrap(); | ||
| assert!(limit.0 != limit.1); | ||
|
||
|
|
||
| let orig_limit = limit; | ||
|
|
||
| limit.0 = limit.1; | ||
| setrlimit(Resource::RLIMIT_STACK, limit).unwrap(); | ||
|
|
||
| let limit2 = getrlimit(Resource::RLIMIT_STACK).unwrap(); | ||
| assert_eq!(limit.0, limit2.0); | ||
| assert_eq!(limit.1, limit2.1); | ||
|
|
||
| setrlimit(Resource::RLIMIT_STACK, orig_limit).unwrap(); | ||
|
|
||
| let final_limit = getrlimit(Resource::RLIMIT_STACK).unwrap(); | ||
| assert_eq!(orig_limit.0, final_limit.0); | ||
| assert_eq!(orig_limit.1, final_limit.1); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand why you're reexporting
rlim_t, but why reexport the others?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, limited the reexport to
rlim_t