Пакет процессов
Пакет Process предоставляет поддержку для работы с процессами в стиле Unix. Для каждого внешнего процесса, который вы хотите обработать, вам нужно создать объект ProcessMonitor и соответствующий объект ProcessNotify. Каждый ProcessMonitor работает как отдельный актёр и при получении данных вызовет метод соответствующего объекта ProcessNotify.
Пример программы
Следующая программа запустит внешнюю программу и запишет данные в её стандартный ввод. Полученный вывод в стандартном выводе дочернего процесса будет перенаправлен клиенту ProcessNotify и напечатан.
use "process"
use "files"
actor Main
new create(env: Env) =>
// create a notifier
let client = ProcessClient(env)
let notifier: ProcessNotify iso = consume client
// define the binary to run
try
let path = FilePath(env.root as AmbientAuth, "/bin/cat")?
// define the arguments; first arg is always the binary name
let args: Array[String] val = ["cat"]
// define the environment variable for the execution
let vars: Array[String] val = ["HOME=/"; "PATH=/bin"]
// create a ProcessMonitor and spawn the child process
let auth = env.root as AmbientAuth
let pm: ProcessMonitor = ProcessMonitor(auth, auth, consume notifier,
path, args, vars)
// write to STDIN of the child process
pm.write("one, two, three")
pm.done_writing() // closing stdin allows cat to terminate
else
env.out.print("Could not create FilePath!")
end
// define a client that implements the ProcessNotify interface
class ProcessClient is ProcessNotify
let _env: Env
new iso create(env: Env) =>
_env = env
fun ref stdout(process: ProcessMonitor ref, data: Array[U8] iso) =>
let out = String.from_array(consume data)
_env.out.print("STDOUT: " + out)
fun ref stderr(process: ProcessMonitor ref, data: Array[U8] iso) =>
let err = String.from_array(consume data)
_env.out.print("STDERR: " + err)
fun ref failed(process: ProcessMonitor ref, err: ProcessError) =>
_env.out.print(err.string())
fun ref dispose(process: ProcessMonitor ref, child_exit_status: ProcessExitStatus) =>
let code: I32 = consume child_exit_code
match child_exit_status
| let exited: Exited =>
_env.out.print("Child exit code: " + exited.exit_code().string())
| let signaled: Signaled =>
_env.out.print("Child terminated by signal: " + signaled.signal().string())
end
Переносимость процессов
ProcessMonitor поддерживает запуск процессов на Linux, FreeBSD, OSX и Windows.
Остановка ProcessMonitor и внешнего процесса
Когда процесс запускается с помощью ProcessMonitor, и нет необходимости дальнейшего общения с ним с помощью stdin и stdout или stderr, вызов done_writing() закроет стандартный ввод дочернего процесса. Процессы, ожидающие ввода, будут уведомлены об EOF в их stdin и смогут завершиться.
Если необходимо отменить запущенную программу и остановить ProcessMonitor, вызов dispose завершит дочерний процесс и очистит все ресурсы.
После того, как будет обнаружено закрытие дочернего процесса, статус завершения процесса будет получен, и будет вызван ProcessNotify.dispose.
Статус завершения процесса может быть либо экземпляром Exited, содержащим код завершения процесса в случае завершения программы самостоятельно, либо (только на системах POSIX, таких как Linux, OSX или BSD) экземпляром Signaled, содержащим номер сигнала, который привёл к завершению процесса.
Публичные типы
- интерфейс ProcessNotify
- тип ProcessMonitorAuth
- актёр ProcessMonitor
- класс ProcessError
- тип ProcessErrorType
- примитив ExecveError
- примитив PipeError
- примитив ForkError
- примитив WaitpidError
- примитив WriteError
- примитив KillError
- примитив CapError
- примитив ChdirError
- примитив UnknownError
- примитив StartProcessAuth
- класс Exited
- класс Signaled
- тип ProcessExitStatus
© 2016-2020, The Pony Developers
© 2014-2015, Causality Ltd.
Licensed under the BSD 2-Clause License.
https://stdlib.ponylang.io/process--index