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}