Skip to main content

SpawnSpec

Struct SpawnSpec 

Source
pub struct SpawnSpec { /* private fields */ }
Expand description

A child process about to be launched.

A builder rather than a bare Command so that the arguments and the environment can be inspected before the launch — which is what SpawnSpec::spawn_with_handoff does.

Implementations§

Source§

impl SpawnSpec

Source

pub fn new(program: impl Into<PathBuf>) -> Self

Starts a specification for program.

Source

pub fn arg(self, arg: impl AsRef<OsStr>) -> Self

Appends one argument.

Source

pub fn args<I, S>(self, args: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<OsStr>,

Appends several arguments.

Source

pub fn env(self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> Self

Sets one environment variable for the child, on top of the inherited environment.

Source

pub fn working_dir(self, dir: impl Into<PathBuf>) -> Self

Sets the child’s working directory.

Source

pub fn output(self, output: OutputMode) -> Self

Chooses what happens to the child’s output.

Source

pub fn normal_scheduling(self) -> Self

Starts the child at normal scheduling priority even when this process runs throttled.

On macOS a launchd agent declared ProcessType = Background runs “darwinbg”: priority 4, efficiency cores only, throttled I/O. That is right for the daemon, which mostly waits, and wrong for the runners it starts, which inherit it and then run every build step 4 to 20 times slower than a classic runner does. With this set, the child clears the inherited background state for itself (setpriority(PRIO_DARWIN_PROCESS, 0, 0)) between fork and exec, so the daemon stays in the background and only the runner and its descendants leave it.

Best effort, on purpose. A throttled runner still runs its job correctly; a runner that fails to start runs nothing. So a failed call does not abort the launch: the parent reads the child’s priority back after the spawn and logs a warning when it is still at the background ceiling, which is the one report a post-fork hook cannot make itself. Leaving the background state needs no privilege for one’s own process, so that warning is not expected to fire.

No effect on other platforms, which have no such inherited state.

Source

pub fn arguments(&self) -> &[OsString]

The arguments as configured. Exposed so a security test can assert what a process listing would show.

Source

pub fn configured_env(&self, name: &str) -> Option<&OsStr>

The variable the child gets for name, as configured on top of the inherited environment: the last Self::env for it wins, as it does in the child. Names compare without case on Windows, as Windows does.

Source

pub fn spawn(&self) -> Result<ChildProcess, ProcessError>

Launches the child.

§Errors

ProcessError::Spawn when the program cannot be launched, and ProcessError::Identity when it launches but its start time cannot be read — which would leave an unrecordable process running, so the child is killed rather than leaked.

Source

pub fn spawn_with_handoff( &self, handoff: &RestrictiveHandoff, ) -> Result<ChildProcess, ProcessError>

Launches the child after proving the handoff payload is not in the command line or the environment.

This is the enforcement point for 07-security.md’s control on “A process listing reveals a JIT config”. e3 should reach for this and not for SpawnSpec::spawn, because a rule that is checked is a rule, and a rule that is written down is a hope.

§Errors

ProcessError::SecretInCommandLine when the payload appears in an argument or an environment value, plus everything SpawnSpec::spawn returns.

Source

pub fn spawn_runner_with_handoff( &self, handoff: &RestrictiveHandoff, ) -> Result<ChildProcess, ProcessError>

Launches GitHub Runner using its supported process-safe JIT input.

The encoded configuration is deliberately absent from SpawnSpec: callers cannot render it as an argument or accidentally retain it in a reusable specification. It is copied from the restrictive handoff into the child’s initial environment at the final Command::spawn boundary. GitHub Runner’s CommandSettings treats jitconfig as a secret and removes ACTIONS_RUNNER_INPUT_JITCONFIG from the process environment before executing the run command.

The caller still owns deleting handoff immediately after this method returns. A failed launch leaves deletion to RestrictiveHandoff’s fail-closed Drop implementation.

§Errors

ProcessError::SecretInCommandLine when the payload was also placed in an argument or explicitly configured environment value, plus every error returned by SpawnSpec::spawn.

Trait Implementations§

Source§

impl Clone for SpawnSpec

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SpawnSpec

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more