Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
0.2.0 Preview 1 · Frozen documentation

RunProcess

Executes one explicit command synchronously through terminal cleanup. May allocate/spawn/block. Command input backing remains borrowed only through return. No unsafe block, implicit shell or ambient argv/environment/cwd is needed. Timeout/cancellation terminate the owned group and reap the direct child before failure returns; OS uninterruptible work has no promised wall-clock kill bound.

Sn is under heavy development. Reference extracted from this release’s bundled standard library. Public API examples are not an exhaustive compatibility test. Read the matching release guide for tested workflows and limitations. Read the status →

Module std.process

import std.process;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

RunProcess

pub fn RunProcess(Command: readonly ProcessCommand&, Limit: Timeout, Token: CancellationToken) -> Result<ProcessExit, ProcessError>

Executes one explicit command synchronously through terminal cleanup. May allocate/spawn/block. Command input backing remains borrowed only through return. No unsafe block, implicit shell or ambient argv/environment/cwd is needed. Timeout/cancellation terminate the owned group and reap the direct child before failure returns; OS uninterruptible work has no promised wall-clock kill bound. Command: Explicit owned backing borrowed unmodified through return. Limit: Nonnegative exact relative timeout or Endless; rounded upward at the native nanosecond boundary, never silently converted to endless. Token: Owned cooperative cancellation observation, inert by default. Return: Detached normal/abnormal exit, or launch/control/native failure.

Example

module example.process_execution;
from std.process import Arguments, Environment, ProgramInputs, ProcessCommand,
    RunProcess, RunProcessAsync, ProcessError, ProcessFailure;
from std.fs import Path;
from std.text import NativeString;
from std.prelude import Result;
from std.task import Task;
from std.time import Timeout, Seconds;
fn CreateCommand() -> Result<ProcessCommand, ProcessError> {
    var Executable = {
        // Scoped writable carriers end immediately after explicit payload transfer.
        var ExecutableCreation = Path.TryCreate("/bin/sh");
        switch ExecutableCreation {
            case .Ok { Value = Value: mut Path& } => break move(Value);
            case .Err => return .Err { Error = ProcessError { Reason = .OutOfMemory, NativeCode = 0 } };
        }
    };
    var Directory = {
        var DirectoryCreation = Path.TryCreate("/");
        switch DirectoryCreation {
            case .Ok { Value = Value: mut Path& } => break move(Value);
            case .Err => return .Err { Error = ProcessError { Reason = .OutOfMemory, NativeCode = 0 } };
        }
    };
    var Values = Arguments();
    let CommandArguments: str[3] = ["/bin/sh", "-c", "exit 7"];
    for Text in CommandArguments {
        var Argument = {
            var ValueCreation = NativeString.TryCreate(Text);
            switch ValueCreation {
                case .Ok { Value = Value: mut NativeString& } => break move(Value);
                case .Err => return .Err { Error = ProcessError { Reason = .OutOfMemory, NativeCode = 0 } };
            }
        };
        if Values.TryPush(move(Argument)) is .Err { Error = _ } { return .Err { Error = ProcessError { Reason = .OutOfMemory, NativeCode = 0 } }; }
    }
    return .Ok { Value = ProcessCommand(move(Executable), move(Directory), ProgramInputs(move(Values), Environment())) };
}
async fn Main() -> Task<i32> {
    // This example explicitly requires a Linux host with a POSIX shell.
    var Command = {
        var CommandCreation = CreateCommand();
        switch CommandCreation {
            case .Ok { Value = Value: mut ProcessCommand& } => break move(Value);
            case .Err => return 1;
        }
    };
    let Limit = switch Timeout.TryFromDuration(Seconds.Create(2)) { case .Ok { Value = Value } => break Value; case .Err => return 2; };
    let Readonly: readonly ProcessCommand& = Command;
    if Readonly.Executable.IsEmpty || Command.Inputs().Arguments().Length != 3 { return 3; }
    Command.ChangeStandardStreamInheritance(false);
    switch RunProcess(Readonly, Limit) {
        case .Ok { Value = PatternPayload5134 } => {
            switch PatternPayload5134 {
                case .Exited { Code = PatternPayload5135 } if (PatternPayload5135 == 7) => {}
                default => return 4;
            }
        }
        default => return 4;
    }
    switch await RunProcessAsync(move(Command), Limit) {
        case .Ok { Value = PatternPayload5136 } => {
            switch PatternPayload5136 {
                case .Exited { Code = PatternPayload5137 } if (PatternPayload5137 == 7) => {}
                default => return 5;
            }
        }
        default => return 5;
    }
    return 0;
}

RunProcess

pub fn RunProcess(Command: readonly ProcessCommand&) -> Result<ProcessExit, ProcessError>

Supplies the omitted arguments to RunProcess. Note: Defaults: Limit = .Endless, Token = CancellationToken(). Command: Same input, ownership and lifetime contract as the full operation. Return: The full synchronous operation's value or typed failure.

RunProcess

pub fn RunProcess(Command: readonly ProcessCommand&, mut Limit: Timeout) -> Result<ProcessExit, ProcessError>

Supplies the omitted arguments to RunProcess. Note: Defaults: Token = CancellationToken(). Command: Same input, ownership and lifetime contract as the full operation. Limit: Same input, ownership and lifetime contract as the full operation. Return: The full synchronous operation's value or typed failure.

RunProcessAsync

pub async fn RunProcessAsync(mut Command: ProcessCommand, Limit: Timeout, Token: CancellationToken) -> Task<Result<ProcessExit, ProcessError>>

Consumes explicit command ownership and executes on the blocking pool. Command backing and cancellation query remain owned through terminal native cleanup. May allocate/queue; submission never performs native launch/wait on the initiating thread. Resume uses the caller's captured executor. Command: Owned executable/cwd/argv/environment transferred into work. Limit: Exact nonnegative relative native execution allowance or Endless; queue admission time is separate from the native execution allowance. Token: Owned cooperative cancellation observation, inert by default. Return: Unique task yielding detached exit or native/admission/control failure.

RunProcessAsync

pub fn RunProcessAsync(mut Command: ProcessCommand) -> Task<Result<ProcessExit, ProcessError>>

Supplies the omitted arguments to RunProcessAsync. Note: Defaults: Limit = .Endless, Token = CancellationToken(). Command: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

RunProcessAsync

pub fn RunProcessAsync(mut Command: ProcessCommand, mut Limit: Timeout) -> Task<Result<ProcessExit, ProcessError>>

Supplies the omitted arguments to RunProcessAsync. Note: Defaults: Token = CancellationToken(). Command: Same input, ownership and lifetime contract as the full operation. Limit: Same input, ownership and lifetime contract as the full operation. Return: Exact full-operation result; no additional async frame is created.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library