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
impl<'a> Spawner
Sourcepub fn new(cmd: impl Into<String>) -> Result<Self, Error>
pub fn new(cmd: impl Into<String>) -> Result<Self, Error>
Construct a Spawner to spawn cmd.
cmd will be resolved from PATH.
Sourcepub fn abs(cmd: impl Into<String>) -> Self
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.
Sourcepub fn input(self, input: StreamMode) -> Self
pub fn input(self, input: StreamMode) -> Self
Control whether to hook the child’s standard input.
Sourcepub fn output(self, output: StreamMode) -> Self
pub fn output(self, output: StreamMode) -> Self
Control whether to hook the child’s standard output.
Sourcepub fn error(self, error: StreamMode) -> Self
pub fn error(self, error: StreamMode) -> Self
Control whether to hook the child’s standard error.
Sourcepub fn name(self, name: &str) -> Self
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
Sourcepub fn associate(&self, process: Handle)
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.
Sourcepub fn get_associate<'b>(
&'b self,
name: &str,
) -> Option<RefMut<'b, String, Handle>>
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.
Sourcepub fn mode(self, mode: Mode) -> Self
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
Sourcepub fn elevate(self, elevate: bool) -> Self
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.
Sourcepub fn preserve_env(self, preserve: bool) -> Self
pub fn preserve_env(self, preserve: bool) -> Self
Preserve the environment of the parent when launching the child.
Spawner defaults to clearing the environment.
Sourcepub fn cap(self, cap: Capability) -> Self
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.
Sourcepub fn caps(self, caps: impl IntoIterator<Item = Capability>) -> Self
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.
Sourcepub fn new_privileges(self, allow: bool) -> Self
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.
Sourcepub fn env(
self,
key: impl Into<Cow<'a, str>>,
var: impl Into<Cow<'a, str>>,
) -> Result<Self, Error>
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.
Sourcepub fn pass_env(self, key: impl Into<Cow<'a, str>>) -> Result<Self, Error>
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.
Sourcepub fn seccomp(self, seccomp: Filter) -> Self
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:
- The child will be running under the assigned operating set mode, and said operating set must have permission to load the filter.
- If using Notify, the path to the monitor socket must be accessible by the operating set mode.
- Your SECCOMP filter must permit
execveto launch the application. This does not have to be ALLOW. See the caveats to Notify if you are using it.
Sourcepub fn arg(self, arg: impl Into<Cow<'a, str>>) -> Result<Self, Error>
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.
Sourcepub fn fd(self, fd: impl Into<OwnedFd>) -> Self
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.
Sourcepub fn fd_arg(
self,
arg: impl Into<Cow<'a, str>>,
fd: impl Into<OwnedFd>,
) -> Result<Self, Error>
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();Sourcepub fn args<I, S>(self, args: I) -> Result<Self, Error>
pub fn args<I, S>(self, args: I) -> Result<Self, Error>
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.
Sourcepub fn input_i(&self, input: StreamMode)
pub fn input_i(&self, input: StreamMode)
Set the input flag without consuming the Spawner.
Sourcepub fn output_i(&self, output: StreamMode)
pub fn output_i(&self, output: StreamMode)
Set the output flag without consuming the Spawner.
Sourcepub fn error_i(&self, error: StreamMode)
pub fn error_i(&self, error: StreamMode)
Set the error flag without consuming the Spawner.
Sourcepub fn preserve_env_i(&self, preserve: bool)
pub fn preserve_env_i(&self, preserve: bool)
Set the preserve environment flag without consuming the Spawner.
Sourcepub fn caps_i(&mut self, caps: impl IntoIterator<Item = Capability>)
pub fn caps_i(&mut self, caps: impl IntoIterator<Item = Capability>)
Adds a capability set without consuming the Spawner.
Sourcepub fn new_privileges_i(&self, allow: bool)
pub fn new_privileges_i(&self, allow: bool)
Set the NO_NEW_PRIVS flag without consuming the Spawner.
Sourcepub fn env_i(
&self,
key: impl Into<Cow<'a, str>>,
value: impl Into<Cow<'a, str>>,
) -> Result<(), Error>
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.
Sourcepub fn pass_env_i(&self, key: impl Into<Cow<'a, str>>) -> Result<(), Error>
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.
Sourcepub fn arg_i(&self, arg: impl Into<Cow<'a, str>>) -> Result<(), Error>
pub fn arg_i(&self, arg: impl Into<Cow<'a, str>>) -> Result<(), Error>
Move an argument to the Spawner in-place.
Sourcepub fn fd_arg_i(
&self,
arg: impl Into<Cow<'a, str>>,
fd: impl Into<OwnedFd>,
) -> Result<(), Error>
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.
Sourcepub fn args_i<I, S>(&self, args: I) -> Result<(), Error>
pub fn args_i<I, S>(&self, args: I) -> Result<(), Error>
Move an iterator of arguments to the Spawner in-place.
Both sequence and order are guaranteed.
Sourcepub fn cache_start(&self) -> Result<(), Error>
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.
Sourcepub fn cache_write(&self, path: &Path) -> Result<(), Error>
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.
Sourcepub fn cache_read(&self, path: &Path) -> Result<(), Error>
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.
Sourcepub fn spawn(self) -> Result<Handle, Error>
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
forkfails. - 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
pkexeccannot be found in PATH. - The resolved application (Or
pkexecif elevate) has a path containing a NULL byte. F_SETFDcannot 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.
execveFails.
Auto Trait Implementations§
impl !Freeze for Spawner
impl !RefUnwindSafe for Spawner
impl Send for Spawner
impl Sync for Spawner
impl Unpin for Spawner
impl !UnwindSafe for Spawner
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
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