Spawner

Struct Spawner 

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

Spawn a child.

§Thread Safety

This entire object is safe to pass and construct across multiple threads.

§Examples

Launch bash in a child, inheriting the parent’s input/output/error:

spawn::Spawner::new("bash").unwrap().spawn().unwrap();

Launch cat, feeding it input from the parent:

use std::io::Write;
let mut handle = spawn::Spawner::new("cat").unwrap()
    .input(spawn::StreamMode::Pipe)
    .output(spawn::StreamMode::Pipe)
    .spawn()
    .unwrap();
let string = "Hello, World!";
write!(handle, "{}", &string);
handle.close();
let output = handle.output().unwrap().read_all().unwrap();
assert!(output == string);

Implementations§

Source§

impl<'a> Spawner

Source

pub fn new(cmd: impl Into<String>) -> Result<Self, Error>

Construct a Spawner to spawn cmd. cmd will be resolved from PATH.

Source

pub fn abs(cmd: impl Into<String>) -> Self

Construct a Spanwner to spawn cmd. This function treats cmd as an absolute path. No resolution is performed.

Source

pub fn input(self, input: StreamMode) -> Self

Control whether to hook the child’s standard input.

Source

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

Control whether to hook the child’s standard output.

Source

pub fn error(self, error: StreamMode) -> Self

Control whether to hook the child’s standard error.

Source

pub fn name(self, name: &str) -> Self

Give a unique name to the process, so you can refer to the Handle. If no name is set, the string passed to Spawn::new() will be used

Source

pub fn associate(&self, process: Handle)

Attach another process that is attached to the main child, and should be killed when the eventual Handle goes out of scope.

Source

pub fn get_associate<'b>( &'b self, name: &str, ) -> Option<RefMut<'b, String, Handle>>

Returns a mutable reference to an associate within the Handle, if it exists. The associate is another Handle instance.

Source

pub fn mode(self, mode: Mode) -> Self

Drop privilege to the provided user mode on the child, immediately after the fork. This does not affected the parent process, but prevents the child from changing outside of the assigned UID.

If is set to Original, the child is launched with the exact same operating set as the parent, persisting SetUID privilege.

If mode is not set, or set to Existing, it adopts whatever operating set the parent is in when spawn() is called. This is ill-advised.

If the parent is not SetUID, this parameter is a no-op

Source

pub fn elevate(self, elevate: bool) -> Self

Elevate the child to root privilege by using PolKit for authentication. pkexec must exist, and must be in path. The operating set of the child must ensure the real user can authorize via PolKit.

Source

pub fn preserve_env(self, preserve: bool) -> Self

Preserve the environment of the parent when launching the child. Spawner defaults to clearing the environment.

Source

pub fn cap(self, cap: Capability) -> Self

Add a capability to the child’s capability set. Note that this function cannot grant capability the program does not possess, it merely prevents existing capabilities from being cleared.

Source

pub fn caps(self, caps: impl IntoIterator<Item = Capability>) -> Self

Add capabilities to the child’s capability set. Note that this function cannot grant capability the program does not possess, it merely prevents existing capabilities from being cleared.

Source

pub fn new_privileges(self, allow: bool) -> Self

Control whether the child is allowed new privileges. Note that this function cannot grant privilege the program does not already have, but merely allows it access to existing privileges not shared by the parent.

Source

pub fn env( self, key: impl Into<Cow<'a, str>>, var: impl Into<Cow<'a, str>>, ) -> Result<Self, Error>

Sets an environment variable to pass to the process. Note that if preserve_env is set to true, this value will overwrite the existing value, if it exists.

Source

pub fn pass_env(self, key: impl Into<Cow<'a, str>>) -> Result<Self, Error>

Passes the value of the provided environment variable to the child. If preserve_env is true, this is functionally a no-op.

Source

pub fn seccomp(self, seccomp: Filter) -> Self

Move a SECCOMP filter to the Spawner, loading in the child after forking. SECCOMP is the last operation applied. This has several consequences:

  1. The child will be running under the assigned operating set mode, and said operating set must have permission to load the filter.
  2. If using Notify, the path to the monitor socket must be accessible by the operating set mode.
  3. Your SECCOMP filter must permit execve to launch the application. This does not have to be ALLOW. See the caveats to Notify if you are using it.
Source

pub fn arg(self, arg: impl Into<Cow<'a, str>>) -> Result<Self, Error>

Move a new argument to the argument vector. This function is guaranteed to append to the end of the current argument vector.

Source

pub fn fd(self, fd: impl Into<OwnedFd>) -> Self

Move a new FD to the Spawner. FD’s will be shared to the child under the same value. Any FD’s in the parent not explicitly passed will be dropped.

Source

pub fn fd_arg( self, arg: impl Into<Cow<'a, str>>, fd: impl Into<OwnedFd>, ) -> Result<Self, Error>

Move a FD to the Spawner, and attach it to an argument to ensure the value is identical.

§Example

Bubblewrap supports the –file flag, which accepts a FD and destination. If you want to ensure you don’t accidentally mismatch FDs, you can commit both the FD and argument in the same transaction:

let file = std::fs::File::create("file.txt").unwrap();
spawn::Spawner::new("bwrap").unwrap()
    .fd_arg("--file", file).unwrap()
    .arg("/file.txt").unwrap()
    .spawn().unwrap();
std::fs::remove_file("file.txt").unwrap();
Source

pub fn args<I, S>(self, args: I) -> Result<Self, Error>
where I: IntoIterator<Item = S>, S: Into<Cow<'a, str>>,

Move an iterator of arguments into the Spawner. It is guaranteed that the arguments in the iterator will appear sequentially, and in the same order.

Source

pub fn fds<I, S>(self, fds: I) -> Self
where I: IntoIterator<Item = S>, S: Into<OwnedFd>,

Move an iterator of FD’s to the Spawner.

Source

pub fn input_i(&self, input: StreamMode)

Set the input flag without consuming the Spawner.

Source

pub fn output_i(&self, output: StreamMode)

Set the output flag without consuming the Spawner.

Source

pub fn error_i(&self, error: StreamMode)

Set the error flag without consuming the Spawner.

Source

pub fn elevate_i(&self, elevate: bool)

Set the elevate flag without consuming the Spawner.

Source

pub fn preserve_env_i(&self, preserve: bool)

Set the preserve environment flag without consuming the Spawner.

Source

pub fn cap_i(&mut self, cap: Capability)

Add a capability without consuming the Spawner.

Source

pub fn caps_i(&mut self, caps: impl IntoIterator<Item = Capability>)

Adds a capability set without consuming the Spawner.

Source

pub fn new_privileges_i(&self, allow: bool)

Set the NO_NEW_PRIVS flag without consuming the Spawner.

Source

pub fn env_i( &self, key: impl Into<Cow<'a, str>>, value: impl Into<Cow<'a, str>>, ) -> Result<(), Error>

Sets an environment variable to the child process without consuming the Spawner.

Source

pub fn pass_env_i(&self, key: impl Into<Cow<'a, str>>) -> Result<(), Error>

Pass an environment variable to the child process without consuming the Spawner.

Source

pub fn mode_i(&self, mode: Mode)

Set the user mode without consuming the Spawner.

Source

pub fn seccomp_i(&self, seccomp: Filter)

Set a SECCOMP filter without consuming the Spawner.

Source

pub fn arg_i(&self, arg: impl Into<Cow<'a, str>>) -> Result<(), Error>

Move an argument to the Spawner in-place.

Source

pub fn fd_i(&self, fd: impl Into<OwnedFd>)

Move a FD to the Spawner in-place.

Source

pub fn fd_arg_i( &self, arg: impl Into<Cow<'a, str>>, fd: impl Into<OwnedFd>, ) -> Result<(), Error>

Move FDs to the Spawner in-place, passing it as an argument.

Source

pub fn fds_i<I, S>(&self, fds: I)
where I: IntoIterator<Item = S>, S: Into<OwnedFd>,

Move an iterator of FDs to the Spawner in-place.

Source

pub fn args_i<I, S>(&self, args: I) -> Result<(), Error>
where I: IntoIterator<Item = S>, S: Into<Cow<'a, str>>,

Move an iterator of arguments to the Spawner in-place. Both sequence and order are guaranteed.

Source

pub fn cache_start(&self) -> Result<(), Error>

Set the cache index. Once the cache flag has been set, all subsequent arguments will be cached to the file provided to cache_write. On future runs, cache_read can be used to append those cached contents to the Spawner’s arguments. This function fails if cache_start is called twice without having first called cache_write.

§Examples
let cache = std::path::PathBuf::from("cmd.cache");
let mut handle = spawn::Spawner::abs("/usr/bin/bash");
if cache.exists() {
    handle.cache_read(&cache).unwrap();
} else {
    handle.cache_start().unwrap();
    handle.arg_i("arg").unwrap();
    handle.cache_write(&cache).unwrap();
}
std::fs::remove_file(cache);
§Caveat

Because the cache is written to disk, ephemeral values, such as FD values, temporary files, etc, must not be passed to the Spawner, otherwise those values would be cached, and likely be invalid when trying to use the cached results.

Source

pub fn cache_write(&self, path: &Path) -> Result<(), Error>

Write all arguments added to the Spawner since cache_start was called to the file provided. This function will fail if cache_start was not called, or if there are errors writing to the provided path.

Source

pub fn cache_read(&self, path: &Path) -> Result<(), Error>

Read from the cache file, adding its contents to the Spawner’s arguments. This function will fail if there is an error reading the file, or if the contents contain strings will NULL bytes.

Source

pub fn spawn(self) -> Result<Handle, Error>

Spawn the child process. This consumes the structure, returning a spawn::Handle.

§Errors

This function can fail for many reasons:

§Parent Errors (Which will return Err)
  • The fork fails.
  • The Parent fails to setup/close/duplicate input/output/error pipes.
§Child Errors (Which will cause errors when using the Handle)
  • The child fails to close/duplicate input/output/error pipes.
  • The application to run cannot be resolved in PATH.
  • Elevate is enabled, but pkexec cannot be found in PATH.
  • The resolved application (Or pkexec if elevate) has a path containing a NULL byte.
  • F_SETFD cannot be cleared on owned FDs.
  • SIGTERM cannot be set as the Child’s Death Sig.
  • A user mode has been set, but dropping to it fails.
  • A SECCOMP filter is set, but it fails to set.
  • execve Fails.

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.