pub struct SpawnOptions {
pub cgroup_procs: Option<Arc<CString>>,
pub open_file_limit: Option<u64>,
pub process_limit: Option<u64>,
pub pids_limits: Arc<[PidsLimit]>,
pub before_spawn: Option<Arc<dyn Fn() -> SpawnGuard + Send + Sync>>,
pub on_spawn: Option<Arc<dyn Fn(SpawnedProcess) + Send + Sync>>,
}Expand description
What the shell does with each external process it spawns, for an embedder that confines or tracks the processes its commands start. The default does nothing.
The options are part of the shell’s RuntimeOptions, so they reach every
external command the shell runs, pipelines, background jobs and subshells
included, since those copy the shell they run in.
The exec builtin applies them in the shell’s own process, with no fork,
so an exec that fails leaves in place the steps that ran before the
failure. The order is the cgroup join, the process counts, the shell’s
other descriptors, then the open-file limit; with process counts set, the
builtin refuses before any step runs.
Fields§
§cgroup_procs: Option<Arc<CString>>A file each child writes 0 to after it is forked and before it runs
its program. For a cgroup v2’s cgroup.procs file, the write moves
the child into that cgroup, so it cannot fork a process outside it;
only Linux has cgroups. When the child cannot open the file or write
to it, the command fails to execute and its program never runs.
open_file_limit: Option<u64>The soft limit on open files (RLIMIT_NOFILE) each child gets, set
after it is forked and before it runs its program, for an embedder
that raised its own soft limit and gives its children the one it
started with. A value above the hard limit sets the hard limit, and
on macOS a value it refuses is lowered to OPEN_MAX (10240). None
leaves the limit the child inherits; on a platform without resource
limits, setting it fails every external command.
process_limit: Option<u64>The limit on the processes of the user id (RLIMIT_NPROC) each
child gets, set after it is forked and before it runs its program:
both its soft and its hard limit become this value, or its hard limit
when that is lower, so neither the program nor its descendants can
raise it. The kernel then refuses a fork by the child or a descendant
while the user id has that many processes, except for root and a
process with CAP_SYS_RESOURCE or CAP_SYS_ADMIN, which it does not
bind. The exec builtin refuses to replace the shell while it is
set, because the shell’s own process would set it, and would keep a
hard limit it cannot raise again if the exec failed; a subshell’s
exec forks and is limited as usual. None leaves the limit the
child inherits. Only Linux sets it; on another platform, setting it
fails every external command.
pids_limits: Arc<[PidsLimit]>Process counts each child checks after it joins the cgroup in
cgroup_procs and before it runs its program. The kernel does not
apply a cgroup’s pids.max to a process that moves into it, so the
child checks the count itself and fails its spawn, without running its
program, when a count is above its limit or cannot be read: the
command then fails to execute, with status 126, and on_spawn is not
called. The exec builtin refuses to replace the shell while the
list is non-empty, because in the shell’s own process a count would
include every thread of the shell; a subshell’s exec forks and is
checked as usual. Empty, the default, checks nothing; on a platform
without this check, a non-empty list fails every external command.
before_spawn: Option<Arc<dyn Fn() -> SpawnGuard + Send + Sync>>Called before each child is spawned. The shell holds the value it
returns until on_spawn has returned for that child, or until the
spawn fails, then drops it. An embedder that reaps processes it did
not spawn, such as a child subreaper, holds a lock in it so that no
reap runs between the fork and on_spawn: a child that exits in that
window is a zombie the embedder does not yet know, and reaping it
would take the exit status the shell waits for. It runs on the
shell’s task, so it should return quickly.
on_spawn: Option<Arc<dyn Fn(SpawnedProcess) + Send + Sync>>Called with each child once it has started, before the shell waits for it. It runs on the shell’s task, so it should return quickly.
Trait Implementations§
Source§impl Clone for SpawnOptions
impl Clone for SpawnOptions
Source§impl Debug for SpawnOptions
impl Debug for SpawnOptions
Auto Trait Implementations§
impl !RefUnwindSafe for SpawnOptions
impl !UnwindSafe for SpawnOptions
impl Freeze for SpawnOptions
impl Send for SpawnOptions
impl Sync for SpawnOptions
impl Unpin for SpawnOptions
impl UnsafeUnpin for SpawnOptions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more