yash_env/system/
resource.rs

1// This file is part of yash, an extended POSIX shell.
2// Copyright (C) 2024 WATANABE Yuki
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17//! Resource types and limits
18//!
19//! This module defines resource types and their limit values that are used in
20//! [`getrlimit`] and [`setrlimit`].
21//!
22//! [`getrlimit`]: super::System::getrlimit
23//! [`setrlimit`]: super::System::setrlimit
24
25#[cfg(unix)]
26type RawLimit = libc::rlim_t;
27#[cfg(not(unix))]
28type RawLimit = u64;
29
30/// Unsigned integer type for resource limits
31///
32/// The size of this type may vary depending on the platform.
33pub type Limit = RawLimit;
34
35#[cfg(unix)]
36const RLIM_INFINITY: Limit = libc::RLIM_INFINITY;
37#[cfg(not(unix))]
38const RLIM_INFINITY: Limit = Limit::MAX;
39
40/// Constant to specify an unlimited resource limit
41///
42/// The value of this constant is platform-specific.
43pub const INFINITY: Limit = RLIM_INFINITY;
44
45// No platforms are known to define `RLIM_SAVED_CUR` and `RLIM_SAVED_MAX` that
46// have different values from `RLIM_INFINITY`, so they are not defined here.
47
48// When adding a new resource type, also update the yash_builtin::ulimit::resource module.
49
50/// Resource type definition
51///
52/// A `Resource` value represents a resource whose limit can be retrieved or
53/// set using [`getrlimit`] and [`setrlimit`].
54///
55/// This enum contains all possible resource types that may or may not be
56/// available depending on the platform.
57///
58/// [`getrlimit`]: super::System::getrlimit
59/// [`setrlimit`]: super::System::setrlimit
60#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
61#[non_exhaustive]
62pub enum Resource {
63    /// Maximum total memory size of the process
64    AS,
65    /// Maximum size of a core file created by a terminated process
66    CORE,
67    /// Maximum amount of CPU time the process can consume
68    CPU,
69    /// Maximum size of a data segment of the process
70    DATA,
71    /// Maximum size of a file the process can create
72    FSIZE,
73    /// Maximum number of kernel event queues (kqueues)
74    KQUEUES,
75    /// Maximum number of file locks the process can hold
76    LOCKS,
77    /// Maximum size of memory locked into RAM
78    MEMLOCK,
79    /// Maximum total size of POSIX message queues
80    MSGQUEUE,
81    /// Maximum process priority
82    ///
83    /// This resource specifies the highest priority that a process can set using
84    /// `setpriority` or `nice`. When the resource value is set to *n*, the process
85    /// can lower its nice value (that is, raise the priority) to (20 - *n*).
86    NICE,
87    /// Maximum number of open files in the process
88    NOFILE,
89    /// Maximum number of processes the user can run
90    NPROC,
91    /// Maximum physical memory size of the process
92    RSS,
93    /// Maximum real-time priority
94    RTPRIO,
95    /// Maximum amount of CPU time the process can consume in real-time
96    /// scheduling mode without a blocking system call (microseconds)
97    RTTIME,
98    /// Maximum size of the socket buffer
99    SBSIZE,
100    /// Maximum number of signals that can be queued to the process
101    SIGPENDING,
102    /// Maximum size of the process stack
103    STACK,
104    /// Maximum size of the swap space that can be used by the user
105    SWAP,
106}
107
108impl Resource {
109    /// Slice of all resource types (including those not available on the current platform)
110    pub const ALL: &'static [Resource] = &[
111        Self::AS,
112        Self::CORE,
113        Self::CPU,
114        Self::DATA,
115        Self::FSIZE,
116        Self::KQUEUES,
117        Self::LOCKS,
118        Self::MEMLOCK,
119        Self::MSGQUEUE,
120        Self::NICE,
121        Self::NOFILE,
122        Self::NPROC,
123        Self::RSS,
124        Self::RTPRIO,
125        Self::RTTIME,
126        Self::SBSIZE,
127        Self::SIGPENDING,
128        Self::STACK,
129        Self::SWAP,
130    ];
131}
132
133/// Pair of soft and hard limits
134#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
135pub struct LimitPair {
136    pub soft: Limit,
137    pub hard: Limit,
138}
139
140impl LimitPair {
141    /// Returns `true` if the soft limit exceeds the hard limit
142    #[must_use]
143    pub fn soft_exceeds_hard(&self) -> bool {
144        self.hard != INFINITY && (self.soft == INFINITY || self.soft > self.hard)
145    }
146}