6.19. kink/PROCESS

Control the current process and subprocesses.

About exit statuses

In POSIX compliant systems, only the least 8 bits of the exit status can be usable [1]. To comply with that restriction, PROCESS.exit only accepts integer numbers in [0, 255].

In Windows API, the exit status is a 32bit unsigned integer [2]. To be able to handle that, the range of the result of Process.wait is defined as [0, 4294967295]. Note that, although Windows API specifies the exit status as unsigned, cmd.exe and PowerShell treat the exit status as signed.

[1] https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html

[2] https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess

6.19.1. type process

`process` is a subprocess launched by PROCESS.start.

6.19.1.1. P.wait(...[$config={}])

`wait` waits until the exit status of the subprocess becomes available, or it reaches the timeout.

Config methods:

• C.timeout(Timeout_seconds)

• C.on_success($success): default = VAL.identity

• C.on_timeout($timeout): default = a thunk which raises an exception

`Timeout_seconds` is a non-negative `num` of arbitrary scale. It is used as the seconds until the timeout. If the timeout is reached before the exit status becomes available, `wait` tail-calls $timeout with no arg.

`wait` might adjust `Timeout_seconds` to an appropriate value.

If C.timeout is not called, `wait` never reaches the timeout.

If the exit status becomes available within the timeout. `wait` tail-calls $success with the exit status as an integer `num` in the range [0, 4294967295].

Preconditions

`Timeout_seconds` must be a non-negative `num`.

$success must be a function which takes an integer `num` in the range [0, 4294967295].

$timeout must be a thunk.

6.19.1.2. P.stdin

`stdin` returns the pipe `output` linked to the standard input of the subprocess.

Precondition

PROCESS.start must have been called with C.stdin_from_pipe.

6.19.1.3. P.stdout

`stdout` returns the pipe `input` linked to the standard output of the subprocess.

Precondition

PROCESS.start must have been called with C.stdout_to_pipe.

6.19.1.4. P.stderr

`stderr` returns the pipe `input` linked to the standard error of the subprocess.

Precondition

PROCESS.start must have been called with C.stderr_to_pipe.

6.19.2. PROCESS.start(Command_and_args ...[$config={}])

`start` launches a subprocess by executing the command specified by `Command_and_args`.

If `start` successfully launches a subprocess, it tail-calls $success with the `process` value which represents the launched subprocess. $success is given by C.on_success, or VAL.identity by default.

If `start` fails to launch a subprocess, it tail-calls $error with an `exception`. $error is given by C.on_error, or {(:Exc) Exc.raise } by default.

Preconditions

`Command_and_args` must be a `vec` of `str` values.

`Command_and_args` must not be empty.

$config must be a function which takes a `start_config`.

Example: inherit standard IO of the current process

Example: pipe the standard output

6.19.3. type start_config

`start_config` is a config value of PROCESS.start.

Standard IO

If `stdin_from_pipe` or `stdin_from_file` methods are not called, the subprocess will inherit the standard input from the current process.

If `stdout_to_pipe`, `stdout_to_overwrite`, or `stdout_to_append` methods are not called, the subprocess will inherit the standard output from the current process.

If `stderr_to_pipe`, `stderr_to_overwrite`, `stderr_to_append`, or `stderr_to_stdout` methods are not called, the subprocess will inherit the standard error output from the current process.

6.19.3.1. C.stdin_from_pipe

`stdin_from_pipe` specifies that the standard input of the subprocess will be connected to a pipe `output`.

If you specify `stdin_from_pipe`, you will need to call P.stdin to get the pipe `output` connected to the subprocess.

6.19.3.2. C.stdin_from_file(File_path)

`stdin_from_file` specifies that the file on `File_path` will be the source of the standard input of the subprocess.

If the file cannot be opened, PROCESS.start results in an error.

Precondition

`File_path` must be a `str`.

6.19.3.3. C.stdout_to_pipe

`stdout_to_pipe` specifies that the standard output of the subprocess will be connected to the pipe `input`.

If you specify `stdout_to_pipe`, you will need to call P.stdout to get the pipe `input` connected to the subprocess.

6.19.3.4. C.stdout_to_overwrite(File_path)

`stdout_to_overwrite` specifies that the file on `File_path` will be opened with overwrite mode, and used as the destination of the standard output of the subprocess.

If the file cannot be opened, PROCESS.start results in an error.

Precondition

`File_path` must be a `str`.

6.19.3.5. C.stdout_to_append(File_path)

`stdout_to_append` specifies that the file on `File_path` will be opened with append mode, and used as the destination of the standard output of the subprocess.

If the file cannot be opened, PROCESS.start results in an error.

Precondition

`File_path` must be a `str`.

6.19.3.6. C.stderr_to_pipe

`stderr_to_pipe` specifies that the standard error output of the subprocess will be connected to the pipe `input`.

If you specify `stderr_to_pipe`, you will need to call P.stderr to get the pipe `input` connected to the subprocess.

6.19.3.7. C.stderr_to_overwrite(File_path)

`stderr_to_overwrite` specifies that the file on `File_path` is opened with overwrite mode, and used as the destination of the standard error output of the subprocess.

If the file cannot be opened, PROCESS.start results in an error.

Precondition

`File_path` must be a `str`.

6.19.3.8. C.stderr_to_append(File_path)

`stderr_to_append` specifies that the file on `File_path` is opened with append mode, and used as the destination of the standard error output of the subprocess.

If the file cannot be opened, PROCESS.start results in an error.

Precondition

`File_path` must be a `str`.

6.19.3.9. C.stderr_to_stdout

`stderr_to_stdout` specifies that the standard error output of the subprocess will be redirected to its standard output.

It is same as specifying `2>&1` in Unix shells.

6.19.3.10. C.dir(Dir_path)

`dir` specifies `Dir_path` as the working directory of the subprocess.

If the subprocess cannot change the directory to `Dir_path`, PROCESS.start results in an error.

Precondition

`Dir_path` must be a `str`.

6.19.3.11. C.set_env(Env_name Env_val)

`set_env` specifies that the subprocess has the environment variable with the name `Env_name` and the value `Env_val`.

Case sensitivity of `Env_name` depends on the host system. Typically, it is case sensitive on Unix systems, and case insensitive on Windows systems.

Preconditions

`Env_name` must be a `str`.

`Env_val` must be a `str`.

6.19.3.12. C.unset_env(Env_name)

`unset_env` specifies that the subprocess does not have the environment variable with the name `Env_name`.

Case sensitivity of `Env_name` depends on the host system. Typically, it is case sensitive on Unix systems, and case insensitive on Windows systems.

Precondition

`Env_name` must be a `str`.

6.19.3.13. C.on_success($success)

`on_success` specifies that $success is used as the success continuation of PROCESS.start.

Precondition

$success must be a function which takes a `process`.

6.19.3.14. C.on_error($error)

`on_error` specifies that $error is used as the error continuation of PROCESS.start.

Precondition

$error must be a function which takes an `exception`.

6.19.4. PROCESS.pid

`pid` returns the current process id in an integer `num`.

Example

6.19.5. PROCESS.env(Env_name)

`env` returns a `str` of the environment variable specified by `Env_name`.

Case sensitivity of `Env_name` depends on the host system. Typically, it is case sensitive on Unix systems, and case insensitive on Windows systems.

Preconditions

`Env_name` must be a `str`.

The current process must have the specified environment variable.

Example

6.19.6. PROCESS.have_env?(Env_name)

`have_env?` returns whether the current process has the environment variable specified by `Env_name`.

Case sensitivity of `Env_name` depends on the host system. Typically, it is case sensitive on Unix systems, and case insensitive on Windows systems.

Precondition

`Env_name` must be a `str`.

Example

6.19.7. PROCESS.exit(Exit_status)

`exit` terminates the current process with `Exit_status`.

Precondition

`Exit_status` must be an integer `num` in the range [0, 255].