exec

std.process.exec

rec ExitStatus

pub rec ExitStatus;

来自终止进程的原始等待状态

raw:由 wait_pid 返回的原始等待状态

rec Child

pub rec Child;

已派生子进程的句柄

pid:子进程的进程 ID

rec Reaped

pub rec Reaped;

wait_any 回收的子进程

child:被回收的子进程句柄 status:其退出状态

rec Output

pub rec Output;

运行子进程并收集其标准输出的结果

status:子进程的退出状态 bytes:子进程的完整标准输出,由调用者的分配器拥有

fun run

pub fun run(pathname: str, argv: **u8, envp: **u8) R.Result[ExitStatus, str];

派生一个进程并等待其退出

pathname:可执行文件的路径 argv:以空字符结尾的参数数组 envp:以空字符结尾的环境变量数组 ret:退出状态,或错误消息

fun run_shell

pub fun run_shell(command: str, cwd: str, envp: **u8) R.Result[ExitStatus, str];

通过主机的命令解释器,从 cwd 运行命令

解释器及其命令行约定是平台特有的,而不是调用者的:POSIX 直接将 sh -c <command> 传递给 execve,而 Windows 解析 %ComSpec% 并发出 "<comspec>" /s /c "<command verbatim>"。这种区别很重要,因为命令行编码是被派生程序的一个属性——这里其他所有派生操作使用的 CRT argv 约定并不是 cmd.exe 解析的约定,因此组装自己的 shell 调用的调用者必须知道应用哪个约定,否则会出错。

cwd 在子进程中应用,因此调用者自身的工作目录不会被触碰,且该目录绝不会进入命令行。

command:要运行的命令行 cwd:子进程的工作目录,或为 nil 以继承 envp:以空字符结尾的环境变量数组,或为 nil 以继承 ret:退出状态,或错误消息

fun output

pub fun output(a: *A.Allocator, pathname: str, argv: **u8, envp: **u8) R.Result[Output, str];

运行一个进程并收集其完整的标准输出

派生子进程时将 stdout 绑定到管道,并通过管道读端的 io.read_all 将其耗尽至文件末尾,因此可捕获任意长度的输出,且子进程永远不会因为管道满而阻塞。即使耗尽失败,也总是会等待子进程退出。

a:用于捕获输出的分配器 pathname:可执行文件的路径 argv:以空字符结尾的参数数组 envp:以空字符结尾的环境变量数组 ret:退出状态和捕获的标准输出,或错误

fun spawn

pub fun spawn(pathname: str, argv: **u8, envp: **u8) R.Result[Child, str];

启动进程而不等待

pathname:可执行文件的路径 argv:以空字符结尾的参数数组 envp:以空字符结尾的环境变量数组 ret:子进程句柄,或错误消息

fun spawn_redirected

pub fun spawn_redirected(pathname: str, argv: **u8, envp: **u8, stdout_fd: i32, stderr_fd: i32) R.Result[Child, str];

启动进程而不等待,并将其 stdout 和/或 stderr 绑定到调用者提供的描述符。

父进程保持对所传递描述符的所有权(在子进程退出后关闭它们,或者在派生后关闭以让管道的读端看到 EOF);-1 表示保持该流继承。stdin 总是继承的。

pathname:可执行文件的路径 argv:以空字符结尾的参数数组 envp:以空字符结尾的环境变量数组 stdout_fd:子进程 stdout 的描述符,或为 -1 表示继承 stderr_fd:子进程 stderr 的描述符,或为 -1 表示继承 ret:子进程句柄,或错误消息

fun terminate_child

pub fun terminate_child(child: Child) R.Result[bool, str];

强制停止子进程而不回收它

在此操作成功后,子进程仍然是可等待的。调用者必须仍然将其传递给 wait(或通过 wait_any 收集)以获取其状态并释放保留的平台资源。

terminate_childwaitwait_any 不得对同一个子进程并发运行。一旦某个等待操作开始回收子进程,其数字进程 ID 就可以被释放以供重用。

child:来自 spawn 的子进程句柄 ret:成功时为 true,或错误消息

fun wait

pub fun wait(child: Child) R.Result[ExitStatus, str];

等待子进程退出

child:来自 spawn 的子进程句柄 ret:退出状态,或错误消息

fun wait_any

pub fun wait_any() R.Result[Reaped, str];

阻塞直到此进程的任意子进程退出

在每个平台上具有 POSIX wait(-1) 语义(Windows 层通过跨其跟踪的子进程句柄等待来模拟 -1 pid)。返回的对标识了哪个子进程被回收以及它是如何退出的,因此一个管理多个子进程的调用者可以将退出状态映射回其工作项。当没有要等待的子进程时会报错。

wait_any 不得与 terminate_child 并发运行,因为它可能会回收并释放终止操作正在验证的进程 ID。

ret:被回收的子进程及其退出状态,或错误消息

fun exited

pub fun exited(status: ExitStatus) bool;

检查进程是否正常退出

status:要检查的退出状态 ret:如果进程调用了 exit 则为 true

fun code

pub fun code(status: ExitStatus) i32;

获取正常退出进程的退出码

status:要检查的退出状态 ret:退出码(0-255),仅在 exited() 为 true 时有效

fun signaled

pub fun signaled(status: ExitStatus) bool;

检查进程是否被信号杀死

status:要检查的退出状态 ret:如果被信号终止则为 true

fun signal

pub fun signal(status: ExitStatus) i32;

获取杀死进程的信号编号

status:要检查的退出状态 ret:信号编号

fun exit

pub fun exit(code: i64);

终止当前进程

code:退出码

fun resolve

pub fun resolve(a: *A.Allocator, name: str) R.Result[str, str];

使用 PATH 将用户命名的程序解析为可派生的路径

所有派生入口点都不搜索 PATHexecve 不解析任何内容,Windows 层传递非 NULL 的 lpApplicationName。调用者如果派生一个由用户命名而不是固定路径的程序,应首先在这里进行解析。

PATH 是唯一的来源。决不查询当前目录,因此提交到工作树中的二进制文件无法遮蔽真正的工具。

a:用于结果的分配器 name:程序名,可是裸名或已有路径的名称 ret:拥有的可派生路径,或错误

fun resolve_in

pub fun resolve_in(a: *A.Allocator, name: str, search: str) R.Result[str, str];

针对调用者提供的搜索列表解析程序名

搜索策略,环境读取留给 resolve。拥有自己列表的调用者(如配置的工具链目录、沙箱)在这里进行搜索而不通过 PATH,并且该策略保持可测试,无需设置环境变量。

search 具有 PATH 形状且不会被修改:在 Windows 上由 ; 分隔,其他地方由 : 分隔。条目会被跳过,而不是被视为当前目录,这正是此功能存在的全部意义——让操作系统搜索会在 Windows 上将工作目录排在真正工具的前面。

已经拼写为路径的名称会以未解析且未探测的形式返回。结果在两种情况下都由调用者拥有,因此释放是无条件的。为带路径的名称返回借用的参数会使所有权依赖于值,这就是调用者最终泄漏一个路径并双重释放另一个路径的原因。

a:用于结果的分配器 name:程序名,可是裸名或已有路径的名称 searchPATH 形状的目录列表,按顺序搜索 ret:拥有的可派生路径,或错误