Skip to content

Commit

Permalink
Conditional reprs based on the target_os (incomplete)
Browse files Browse the repository at this point in the history
  • Loading branch information
j1ah0ng committed Mar 12, 2020
1 parent bfd2228 commit da50e56
Showing 1 changed file with 120 additions and 18 deletions.
138 changes: 120 additions & 18 deletions src/sys/resource.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
//! Configure the process resource limits.
use std::mem;

use libc::{self, c_uint, rlimit, RLIM_INFINITY};
use libc::{self, rlimit, __rlimit_resource_t, RLIM_INFINITY};
pub use libc::rlim_t;

use {Errno, Result};

#[cfg(target_os = "linux")]
libc_enum!{
/// A resource that limits apply to
#[repr(u32)]
pub enum Resource {
// POSIX
/// This is the maximum size of the process's virtual memory (address space). The limit is specified in bytes, and is rounded down to the system page size.
/// This is the maximum size of the process's virtual memory (address space). The limit is
/// specified in bytes, and is rounded down to the system page size.
RLIMIT_AS,
/// This is the maximum size of a core file (see core(5)) in bytes that the process may dump.
/// This is the maximum size of a core file (see core(5)) in bytes that the process may
/// dump.
RLIMIT_CORE,
/// This is a limit, in seconds, on the amount of CPU time that the process can consume.
RLIMIT_CPU,
/// This is the maximum size of the process's data segment (initialized data, uninitialized data, and heap). The limit is specified in bytes, and is rounded down to the system page size.
/// This is the maximum size of the process's data segment (initialized data, uninitialized
/// data, and heap). The limit is specified in bytes, and is rounded down to the system
/// page size.
RLIMIT_DATA,
/// This is the maximum size in bytes of files that the process may create. Attempts to extend a file beyond this limit result in delivery of a SIGXFSZ signal.
/// This is the maximum size in bytes of files that the process may create. Attempts to
/// extend a file beyond this limit result in delivery of a SIGXFSZ signal.
RLIMIT_FSIZE,
/// This specifies a value one greater than the maximum file descriptor number that can be opened by this process.
/// This specifies a value one greater than the maximum file descriptor number that can be
/// opened by this process.
RLIMIT_NOFILE,
/// This is the maximum size of the process stack, in bytes. Upon reaching this limit, a SIGSEGV signal is generated.
/// This is the maximum size of the process stack, in bytes. Upon reaching this limit, a
/// SIGSEGV signal is generated.
RLIMIT_STACK,

// BSDs and Linux
/// This is the maximum number of bytes of memory that may be locked into RAM. This limit is in effect rounded down to the nearest multiple of the system page size.
/// This is the maximum number of bytes of memory that may be locked into RAM. This limit
/// is in effect rounded down to the nearest multiple of the system page size.
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
RLIMIT_MEMLOCK,
/// This is a limit on the number of extant process (or, more precisely on Linux, threads) for the real user ID of the calling process.
/// This is a limit on the number of extant process (or, more precisely on Linux, threads)
/// for the real user ID of the calling process.
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
RLIMIT_NPROC,
/// This is a limit (in bytes) on the process's resident set (the number of virtual pages resident in RAM).
Expand All @@ -41,19 +51,110 @@ libc_enum!{
/// This is a limit on the combined number of flock(2) locks and fcntl(2) leases that this process may establish.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_LOCKS,
/// This is a limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process.
/// This is a limit on the number of bytes that can be allocated for POSIX message queues
/// for the real user ID of the calling process.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_MSGQUEUE,
/// This specifies a ceiling to which the process's nice value can be raised using setpriority(2) or nice(2). The actual ceiling for the nice value is calculated as 20 - rlim_cur.
/// This specifies a ceiling to which the process's nice value can be raised using
/// setpriority(2) or nice(2). The actual ceiling for the nice value is calculated as 20 -
/// rlim_cur.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_NICE,
/// This specifies a ceiling on the real-time priority that may be set for this process using sched_setscheduler(2) and sched_setparam(2).
/// This specifies a ceiling on the real-time priority that may be set for this process
/// using sched_setscheduler(2) and sched_setparam(2).
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_RTPRIO,
/// This is a limit (in microseconds) on the amount of CPU time that a process scheduled under a real-time scheduling policy may consume without making a blocking system call.
/// This is a limit (in microseconds) on the amount of CPU time that a process scheduled
/// under a real-time scheduling policy may consume without making a blocking system call.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_RTTIME,
/// This is a limit on the number of signals that may be queued for the real user ID of the calling process. Both standard and real-time signals are counted for the purpose of checking this limit.
/// This is a limit on the number of signals that may be queued for the real user ID of the
/// calling process. Both standard and real-time signals are counted for the purpose of
/// checking this limit.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_SIGPENDING,

// Available on some BSD
/// The maximum number of kqueues this user id is allowed to create.
#[cfg(target_os = "freebsd")]
RLIMIT_KQUEUES,
/// The maximum number of pseudo-terminals this user id is allowed to create.
#[cfg(target_os = "freebsd")]
RLIMIT_NPTS,
/// The maximum size (in bytes) of socket buffer usage for this user.
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
RLIMIT_SBSIZE,
/// The maximum size (in bytes) of the swap space that may be reserved or used by all of this user id's processes.
#[cfg(target_os = "freebsd")]
RLIMIT_SWAP,
}
}

#[cfg(not(target_os = "linux"))]
libc_enum!{
/// A resource that limits apply to
#[repr(i32)]
pub enum Resource {
// POSIX
/// This is the maximum size of the process's virtual memory (address space). The limit is
/// specified in bytes, and is rounded down to the system page size.
RLIMIT_AS,
/// This is the maximum size of a core file (see core(5)) in bytes that the process may
/// dump.
RLIMIT_CORE,
/// This is a limit, in seconds, on the amount of CPU time that the process can consume.
RLIMIT_CPU,
/// This is the maximum size of the process's data segment (initialized data, uninitialized
/// data, and heap). The limit is specified in bytes, and is rounded down to the system
/// page size.
RLIMIT_DATA,
/// This is the maximum size in bytes of files that the process may create. Attempts to
/// extend a file beyond this limit result in delivery of a SIGXFSZ signal.
RLIMIT_FSIZE,
/// This specifies a value one greater than the maximum file descriptor number that can be
/// opened by this process.
RLIMIT_NOFILE,
/// This is the maximum size of the process stack, in bytes. Upon reaching this limit, a
/// SIGSEGV signal is generated.
RLIMIT_STACK,

// BSDs and Linux
/// This is the maximum number of bytes of memory that may be locked into RAM. This limit
/// is in effect rounded down to the nearest multiple of the system page size.
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
RLIMIT_MEMLOCK,
/// This is a limit on the number of extant process (or, more precisely on Linux, threads)
/// for the real user ID of the calling process.
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
RLIMIT_NPROC,
/// This is a limit (in bytes) on the process's resident set (the number of virtual pages resident in RAM).
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
RLIMIT_RSS,

// Android and Linux only
/// This is a limit on the combined number of flock(2) locks and fcntl(2) leases that this process may establish.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_LOCKS,
/// This is a limit on the number of bytes that can be allocated for POSIX message queues
/// for the real user ID of the calling process.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_MSGQUEUE,
/// This specifies a ceiling to which the process's nice value can be raised using
/// setpriority(2) or nice(2). The actual ceiling for the nice value is calculated as 20 -
/// rlim_cur.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_NICE,
/// This specifies a ceiling on the real-time priority that may be set for this process
/// using sched_setscheduler(2) and sched_setparam(2).
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_RTPRIO,
/// This is a limit (in microseconds) on the amount of CPU time that a process scheduled
/// under a real-time scheduling policy may consume without making a blocking system call.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_RTTIME,
/// This is a limit on the number of signals that may be queued for the real user ID of the
/// calling process. Both standard and real-time signals are counted for the purpose of
/// checking this limit.
#[cfg(any(target_os = "android", target_os = "linux"))]
RLIMIT_SIGPENDING,

Expand Down Expand Up @@ -97,8 +198,9 @@ libc_enum!{
///
/// [`Resource`]: enum.Resource.html
pub fn getrlimit(resource: Resource) -> Result<(Option<rlim_t>, Option<rlim_t>)> {
let mut rlim: rlimit = unsafe { mem::MaybeUninit::uninit().assume_init() };
let res = unsafe { libc::getrlimit(resource as c_uint, &mut rlim as *mut _) };
let mut rlim = mem::MaybeUninit::<&rlimit>::uninit();
let res = unsafe { libc::getrlimit(resource as __rlimit_resource_t, rlim.as_mut_ptr() as *mut _) };
let rlim = unsafe { rlim.assume_init() };
// TODO: use Option::filter after it has been stabilized
Errno::result(res).map(|_| {
(if rlim.rlim_cur != RLIM_INFINITY { Some(rlim.rlim_cur) } else { None },
Expand Down Expand Up @@ -133,10 +235,10 @@ pub fn getrlimit(resource: Resource) -> Result<(Option<rlim_t>, Option<rlim_t>)>
///
/// [`Resource`]: enum.Resource.html
pub fn setrlimit(resource: Resource, soft_limit: Option<rlim_t>, hard_limit: Option<rlim_t>) -> Result<()> {
let mut rlim: rlimit = unsafe { mem::MaybeUninit::uninit().assume_init() };
let mut rlim: rlimit = unsafe { mem::zeroed() };
rlim.rlim_cur = soft_limit.unwrap_or(RLIM_INFINITY);
rlim.rlim_max = hard_limit.unwrap_or(RLIM_INFINITY);

let res = unsafe { libc::setrlimit(resource as c_uint, &rlim as *const _) };
let res = unsafe { libc::setrlimit(resource as __rlimit_resource_t, &rlim as *const _) };
Errno::result(res).map(|_| ())
}

0 comments on commit da50e56

Please sign in to comment.