-
Notifications
You must be signed in to change notification settings - Fork 692
Add getrlimit(2) and setrlimit(2) #364
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 all commits
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,54 @@ | ||
use std::mem; | ||
|
||
use libc::{self, c_int}; | ||
pub use libc::{rlimit, 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}; | ||
|
||
#[repr(i32)] | ||
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. Using the type I got around that in my pull request by using the default ( I would prefer to write Is there a way to conditionalize the repr line on platforms? We certainly can conditionalise the whole enumeration definition on the platform, but that is a lot of repetition, though that certainly can be dealt with using macros. 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.
This should work: #[cfg_attr(target_os = "linux", repr(i32))]
#[cfg_attr(target_os = "some_other", repr(i16))]
pub enum Resource {
...
} 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. Also I kind of answered this in #362 (comment) before seeing the question. |
||
pub enum Resource { | ||
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. should this be 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. @fiveop thoughts? since you added the convention on enums... 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. I would prefer 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.
I'm not completely sold on this, but I could see naming the enum let limit = ResourceLimit::RLIMIT_STACK.get().unwrap();
ResourceLimit::RLIMIT_STACK.set(limit).unwrap(); 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. yeah I thought of this kind of approach but I don't know yet how I feel about going so far from the C API. In related news: I just created https://github.com/nix-rust/rfcs and will create RFC 0000 soon (probably tomorrow) to bootstrap the process. Then we'll have a good place to discuss stuff like this. 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. If we add the The more I think about it, the more I like @posborne's proposal. |
||
// 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, | ||
} | ||
|
||
pub fn getrlimit(resource: Resource) -> Result<rlimit> { | ||
let mut rlim = unsafe { mem::uninitialized() }; | ||
let res = unsafe { libc::getrlimit(resource as c_int, &mut rlim as *mut _) }; | ||
Errno::result(res).map(|_| rlim) | ||
} | ||
|
||
pub fn setrlimit(resource: Resource, rlim: rlimit) -> Result<()> { | ||
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.rlim_cur != limit.rlim_max); | ||
|
||
let orig_limit = limit; | ||
|
||
limit.rlim_cur = limit.rlim_max; | ||
setrlimit(Resource::RLIMIT_STACK, limit).unwrap(); | ||
|
||
let limit2 = getrlimit(Resource::RLIMIT_STACK).unwrap(); | ||
assert_eq!(limit.rlim_cur, limit2.rlim_cur); | ||
assert_eq!(limit.rlim_max, limit2.rlim_max); | ||
|
||
setrlimit(Resource::RLIMIT_STACK, orig_limit).unwrap(); | ||
|
||
let final_limit = getrlimit(Resource::RLIMIT_STACK).unwrap(); | ||
assert_eq!(orig_limit.rlim_cur, final_limit.rlim_cur); | ||
assert_eq!(orig_limit.rlim_max, final_limit.rlim_max); | ||
} |
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 think these should be reexported, but I'm not sure if we are consistently doing that.
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.
What about
RLIM_SAVED_CUR
andRLIM_SAVED_MAX
?Why don't we wrap rlimit and provide proper accessor methods? I admit that it would be purely cosmetic in this case, as far as I can see.
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.
forgotten! fixed.
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.
What about the rlimit wrapper?
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.
oh I was deciding not to do that since we aren't doing anything with the type. I wanted it to be easy to specify inline, eg
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.
What about
ResourceLimit::new(1024 * 1024, RLIM_INFINITY)
?