pub struct SandboxResult {
pub exit_code: i32,
pub signal: Option<i32>,
pub timed_out: bool,
pub memory_peak: u64,
pub cpu_time_us: u64,
pub wall_time_ms: u64,
}Expand description
Sandbox execution result
Fields§
§exit_code: i32Exit code
signal: Option<i32>Signal that killed process (if any)
timed_out: boolWhether timeout occurred
memory_peak: u64Memory usage in bytes
cpu_time_us: u64CPU time in microseconds
wall_time_ms: u64Wall clock time in seconds
Implementations§
Source§impl SandboxResult
impl SandboxResult
Sourcepub fn killed_by_seccomp(&self) -> bool
pub fn killed_by_seccomp(&self) -> bool
Check if process was killed by seccomp (SIGSYS - signal 31) Returns true if exit code is 159 (128 + 31)
Sourcepub fn seccomp_error(&self) -> Option<&'static str>
pub fn seccomp_error(&self) -> Option<&'static str>
Get human-readable error message if process failed due to seccomp
Sourcepub fn check_seccomp_error(&self) -> Result<&SandboxResult>
pub fn check_seccomp_error(&self) -> Result<&SandboxResult>
Convert to Result, returning error if process was killed by seccomp
Examples found in repository?
examples/stream_long_running.rs (line 71)
14fn main() -> sandbox_rs::Result<()> {
15 let tmp = tempdir().expect("Failed to create temp dir");
16
17 let mut sandbox = SandboxBuilder::new("long-running-example")
18 .memory_limit_str("512M")?
19 .cpu_limit_percent(100)
20 .timeout(Duration::from_secs(30))
21 .seccomp_profile(SeccompProfile::Unrestricted)
22 .root(tmp.path())
23 .build()?;
24
25 println!("Running bash script with streaming output...\n");
26
27 // Run a bash script that outputs multiple lines
28 let (result, stream) = sandbox.run_with_stream(
29 "/bin/bash",
30 &[
31 "-c",
32 "for i in {1..5}; do echo \"Line $i from stdout\"; echo \"Error line $i\" >&2; done",
33 ],
34 )?;
35
36 println!("Streaming output:");
37
38 let mut stdout_count = 0;
39 let mut stderr_count = 0;
40 let mut final_exit_code = result.exit_code;
41
42 for chunk in stream.into_iter() {
43 match chunk {
44 StreamChunk::Stdout(line) => {
45 stdout_count += 1;
46 println!(" [OUT #{}] {}", stdout_count, line);
47 }
48 StreamChunk::Stderr(line) => {
49 stderr_count += 1;
50 eprintln!(" [ERR #{}] {}", stderr_count, line);
51 }
52 StreamChunk::Exit {
53 exit_code,
54 signal: _,
55 } => {
56 println!("Process finished with exit code: {}", exit_code);
57 final_exit_code = exit_code;
58 }
59 }
60 }
61
62 let mut result = result;
63 result.exit_code = final_exit_code;
64
65 println!("\nSummary:");
66 println!(" Stdout lines: {}", stdout_count);
67 println!(" Stderr lines: {}", stderr_count);
68 println!(" Wall time: {} ms", result.wall_time_ms);
69 println!(" Exit code: {}", result.exit_code);
70
71 result.check_seccomp_error()?;
72
73 Ok(())
74}More examples
examples/stream_basic.rs (line 63)
10fn main() -> sandbox_rs::Result<()> {
11 // Create a temporary directory for the sandbox
12 let tmp = tempdir().expect("Failed to create temp dir");
13
14 // Create a sandbox with streaming enabled
15 let mut sandbox = SandboxBuilder::new("stream-example")
16 .memory_limit_str("256M")?
17 .cpu_limit_percent(50)
18 .timeout(Duration::from_secs(30))
19 .root(tmp.path())
20 .build()?;
21
22 println!("Starting sandboxed process with streaming...\n");
23
24 // Run process with streaming
25 let (result, stream) = sandbox.run_with_stream("/bin/echo", &["Hello from sandbox!"])?;
26
27 println!("Process output (streaming):");
28
29 // Iterate through all output chunks
30 let mut final_exit_code = result.exit_code;
31 let mut final_signal = result.signal;
32
33 for chunk in stream.into_iter() {
34 match chunk {
35 StreamChunk::Stdout(line) => {
36 println!("[STDOUT] {}", line);
37 }
38 StreamChunk::Stderr(line) => {
39 eprintln!("[STDERR] {}", line);
40 }
41 StreamChunk::Exit { exit_code, signal } => {
42 println!("\nProcess exited with code: {}", exit_code);
43 if let Some(sig) = signal {
44 println!("Killed by signal: {}", sig);
45 }
46 final_exit_code = exit_code;
47 final_signal = signal;
48 }
49 }
50 }
51
52 // Update result with the actual exit code from streaming
53 let mut result = result;
54 result.exit_code = final_exit_code;
55 result.signal = final_signal;
56
57 println!("\nExecution stats:");
58 println!(" Exit code: {}", result.exit_code);
59 println!(" Wall time: {} ms", result.wall_time_ms);
60 println!(" Memory peak: {} bytes", result.memory_peak);
61
62 // Check for seccomp errors and return error if found
63 result.check_seccomp_error()?;
64
65 Ok(())
66}examples/stream_non_blocking.rs (line 89)
14fn main() -> sandbox_rs::Result<()> {
15 let tmp = tempdir().expect("Failed to create temp dir");
16
17 let mut sandbox = SandboxBuilder::new("non-blocking-example")
18 .memory_limit_str("256M")?
19 .cpu_limit_percent(50)
20 .seccomp_profile(SeccompProfile::Unrestricted)
21 .root(tmp.path())
22 .build()?;
23
24 println!("Running process with non-blocking stream reads...\n");
25
26 // Run a process that outputs slowly
27 let (result, stream) = sandbox.run_with_stream(
28 "/bin/bash",
29 &[
30 "-c",
31 "for i in {1..3}; do echo \"Message $i\"; sleep 0.1; done",
32 ],
33 )?;
34
35 println!("Non-blocking polling:");
36
37 let mut received_chunks = 0;
38 let mut polling_attempts = 0;
39 let mut final_exit_code = result.exit_code;
40
41 loop {
42 polling_attempts += 1;
43
44 // Try to read without blocking
45 match stream.try_recv()? {
46 Some(chunk) => match chunk {
47 StreamChunk::Stdout(line) => {
48 println!("[STDOUT] {}", line);
49 received_chunks += 1;
50 }
51 StreamChunk::Stderr(line) => {
52 eprintln!("[STDERR] {}", line);
53 received_chunks += 1;
54 }
55 StreamChunk::Exit {
56 exit_code,
57 signal: _,
58 } => {
59 println!("Process exited with code: {}", exit_code);
60 // Capture the real exit code from the stream
61 final_exit_code = exit_code;
62 break;
63 }
64 },
65 None => {
66 // No data available right now, we could do other work here
67 std::thread::sleep(Duration::from_millis(10));
68 }
69 }
70
71 // Safety limit to prevent infinite loop in case of issues
72 if polling_attempts > 10000 {
73 println!("Safety timeout reached");
74 break;
75 }
76 }
77
78 // Update result with the actual exit code from streaming
79 let mut result = result;
80 result.exit_code = final_exit_code;
81
82 println!("\nStatistics:");
83 println!(" Chunks received: {}", received_chunks);
84 println!(" Polling attempts: {}", polling_attempts);
85 println!(" Exit code: {}", result.exit_code);
86 println!(" Wall time: {} ms", result.wall_time_ms);
87
88 // Check for seccomp errors and return error if found
89 result.check_seccomp_error()?;
90
91 Ok(())
92}Trait Implementations§
Source§impl Clone for SandboxResult
impl Clone for SandboxResult
Source§fn clone(&self) -> SandboxResult
fn clone(&self) -> SandboxResult
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl Freeze for SandboxResult
impl RefUnwindSafe for SandboxResult
impl Send for SandboxResult
impl Sync for SandboxResult
impl Unpin for SandboxResult
impl UnwindSafe for SandboxResult
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
Mutably borrows from an owned value. Read more