Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

lib/process.x

Run commands and pipelines without a shell.

Primary API

FunctionSummary
Env.getReturns the value of this process’s environment variable name, or NULL when it is unset.
Job.checkReturns job once its status is zero, starting it and waiting as needed.
Job.cleanupTerminates and reaps a job that is still running: SIGTERM, then SIGKILL to any stage still running a second later.
Job.errorsReturns the captured standard error of job, starting it and waiting as needed, or NULL when standard error was not captured or was empty.
Job.killSends signal to every stage of job that is still running.
Job.linesReturns the captured standard output of job as lines without their endings.
Job.liveMakes job pass standard output through instead of capturing it, the same as options({stdout: <inherit>}), and returns it.
Job.optionsSets options on job and returns it.
Job.outputReturns the captured standard output of job, starting it and waiting as needed.
Job.pipeAdds command after the last stage of job, reading that stage’s output, and returns the job.
Job.readyReports whether every stage of job has exited, without blocking.
Job.runPasses standard output through, waits for job, and raises when its status is not zero: live() followed by check().
Job.startStarts job without waiting and returns it.
Job.statusReturns the status of job, starting it and waiting as needed: the exit status, or 128 plus a signal.
Job.wait_anyRemoves and returns the first job in jobs that has finished, waiting until one does.
List.jobReturns a Job for command, a command or pipeline, without starting it.

Env

Env.get

String Env.get(String name)

Returns the value of this process’s environment variable name, or NULL when it is unset. The env option sets variables for a child instead.

Source: lib/process.x:664

Job

Job.check

Job Job.check(Job job)

Returns job once its status is zero, starting it and waiting as needed.

Raises: <cmd-fail> with command and status details, plus output and errors when they were captured, or the start causes of Job.start.

Source: lib/process.x:558

Job.cleanup

void Job.cleanup(Job job)

Terminates and reaps a job that is still running: SIGTERM, then SIGKILL to any stage still running a second later.

Source: lib/process.x:634

Job.errors

String Job.errors(Job job)

Returns the captured standard error of job, starting it and waiting as needed, or NULL when standard error was not captured or was empty.

Raises: the start causes of Job.start, or <bad-arg> when the captured text contains a NUL byte.

Source: lib/process.x:609

Job.kill

void Job.kill(Job job, int signal)

Sends signal to every stage of job that is still running.

Source: lib/process.x:626

Job.lines

List Job.lines(Job job)

Returns the captured standard output of job as lines without their endings.

Raises: the causes of Job.output.

Source: lib/process.x:602

Job.live

Job Job.live(Job job)

Makes job pass standard output through instead of capturing it, the same as options({stdout: <inherit>}), and returns it.

Raises: <bad-arg> for a job that has started.

Source: lib/process.x:527

Job.options

Job Job.options(Job job, Map options)

Sets options on job and returns it. The keys are atoms: dir names the working directory, env is a Map of variables added to the inherited environment, and input is a String given to the first stage’s standard input. stdout is capture, inherit, or a file path and applies to the last stage; stderr is inherit, capture, stdout to merge, or a file path and applies to every stage. A key set again replaces its earlier value.

#include "process.x"
int main(void) {
String root = %(pwd).job().options({dir: "/"}).output();
  return root == "/\n" ? 0 : 1;
}

Raises: <bad-arg> for an unknown key or a job that has started.

Source: lib/process.x:487

Job.output

String Job.output(Job job)

Returns the captured standard output of job, starting it and waiting as needed. A live job, or one whose output was empty, returns NULL.

Raises: the causes of Job.check, or <bad-arg> when the output contains a NUL byte.

Source: lib/process.x:588

Job.pipe

Job Job.pipe(Job job, List command)

Adds command after the last stage of job, reading that stage’s output, and returns the job. A pipeline command adds each of its stages.

Raises: <bad-arg> for a job that has started.

Source: lib/process.x:455

Job.ready

int Job.ready(Job job)

Reports whether every stage of job has exited, without blocking. A job that has not started reports 0.

Source: lib/process.x:617

Job.run

void Job.run(Job job)

Passes standard output through, waits for job, and raises when its status is not zero: live() followed by check().

Raises: the causes of Job.live and Job.check.

Source: lib/process.x:579

Job.start

meta native Job Job.start(Job job)

Starts job without waiting and returns it. A job that has started is returned unchanged.

Raises: <not-found> when a program or the dir option does not exist, <io-fail> when a pipe, fork, output file, or other start step fails, or <bad-arg> for an empty command.

Source: lib/process.x:537

Job.status

int Job.status(Job job)

Returns the status of job, starting it and waiting as needed: the exit status, or 128 plus a signal. A stage that never ran because the start raised reports 127. A status that is not zero is an ordinary result here.

Raises: the start causes of Job.start.

Source: lib/process.x:547

Job.wait_any

Job Job.wait_any(Array jobs)

Removes and returns the first job in jobs that has finished, waiting until one does. An empty jobs returns NULL.

Raises: <bad-arg> when a job in jobs has not started.

Source: lib/process.x:644

List

List.job

meta native Job List.job(List command)

Returns a Job for command, a command or pipeline, without starting it. The job captures standard output and passes standard error through. Its first result starts it, waits, and records the run. A Job destination calls this converter, so the call is usually left implicit.

#include "process.x"
int main(void) {
Job job = %(printf "a\nb\n");
  return job.status() == 0 && job.lines().len() == 2 ? 0 : 1;
}

Source: lib/process.x:427

Public types

TypeKindSummary
EnvaliasThe receiverless owner of Env.get.
JobclassA command or pipeline and the record of its one run.
JobLaunchstructThe launch options embedded in a Job.

Env

typedef Symbol Env

The receiverless owner of Env.get.

Source: lib/process.x:49

Job

class Job { List stages; JobLaunch launch; long *pids; int *statuses; int count, started, finished, status, nul_output, nul_errors; File output_file, errors_file; String output_text, errors_text; } *

A command or pipeline and the record of its one run. A job that is still running when its Scope ends, or when its $auto block exits, is terminated and reaped.

Source: lib/process.x:33

JobLaunch

typedef struct _JobLaunch { String dir, input, stdout_path, stderr_path; int has_input, capture_output, capture_errors, errors_to_output; char **environment; } JobLaunch

The launch options embedded in a Job. Set these through Job.options before the job starts. The record has the job’s lifetime. Everything a child needs is prepared before fork, so the child only duplicates descriptors, changes directory, and calls execvp.

Source: lib/process.x:23

Design notes

Job owns running a command or pipeline without a shell. A command is an ordinary List whose elements’ strs become its arguments, and a List of commands is a pipeline. A job runs once, when its first result is requested, and records that run; its status is the last failing stage’s status, with 128 plus the signal for a signalled stage. The calling process’s own environment is read here too, beside the env option that sets a child’s.

Tests and examples

make verify (unittest/test-process.x) and make examples (scripts/line-counts).