
# tecs.io.Process


Streaming child processes.

`new` starts the child immediately and returns its live standard-stream
endpoints. Piped stdin is a
[`Writer`](/modules/io/Process/#tecs.io.Process.Writer); piped stdout and stderr are
[`Reader`](/modules/io/Process/#tecs.io.Process.Reader) values. The
process owns all three endpoints. Closing one endpoint closes only that pipe;
closing the process closes every endpoint, terminates a live child, and reaps
it. Buffers and byte views passed to an endpoint remain caller-owned.

`Process:communicate` is the complete-exchange form for tools and build steps.
It feeds stdin while draining stdout and stderr concurrently, so neither
output pipe can fill and deadlock the child:

```teal
tecs.scoped(function(scope: tecs.Scope)
    local child <const> = scope:own(tecs.io.Process.new({
        args = {"git", "status", "--porcelain"},
        timeoutMs = 2000,
    }))

    local result, communicateReason = child:communicate()
    if result == nil then
        error(communicateReason)
    end

    if result:succeeded() then
        print(result.output)
    else
        io.stderr:write(result.errorOutput)
    end
end)
```

Interactive children use the same reader and writer vocabulary as files,
buffers, and transforms. Closing stdin sends EOF:

```teal
tecs.scoped(function(scope: tecs.Scope)
    local child <const> = scope:own(tecs.io.Process.new({
        args = {"/bin/cat"}
    }))

    local written, writeReason = child.stdin:write("one request\n")
    if written == nil then
        error(writeReason)
    end
    child.stdin:close()

    local reply, readReason = child.stdout:read(4096)
    if reply == nil then
        error(readReason)
    end
    print(reply)
end)
```

Frame-driven code uses `readAvailable`, `readAvailableInto`, and the matching
writer methods. Nil without a reason means an open pipe has no bytes or
capacity right now; an empty string or zero means output EOF. These methods
make backpressure visible instead of growing an implicit queue. Buffer and
byte-view variants avoid constructing Lua strings.

Use `"inherit"` for a CLI that should share the terminal, `"null"` to discard
a stream, and `stderr = "stdout"` for one ordered transcript. A nonzero child
exit still produces a ready [`Exit`](/modules/io/Process/#tecs.io.Process.Exit);
`succeeded` performs the separate exit-code check. Spawn failures return nil
and a reason. Deadlines and explicit kills set the exit's `killed` fields.

## Module contents

### Constructors

| Constructor | Description |
| --- | --- |
| [`new`](/modules/io/Process/#tecs.io.Process.new) | Starts a caller-owned child process with streaming standard I/O. |

### Types

| Type | Kind | Description |
| --- | --- | --- |
| [`CommunicateOptions`](/modules/io/Process/#tecs.io.Process.CommunicateOptions) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | CommunicateOptions controls a complete duplex exchange. |
| [`ErrorMode`](/modules/io/Process/#tecs.io.Process.ErrorMode) | <span class="tealdoc-kind-badge tealdoc-kind-enum">enum</span> | ErrorMode selects where a child writes standard error. |
| [`Exit`](/modules/io/Process/#tecs.io.Process.Exit) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | Exit describes how a child stopped. |
| [`InputMode`](/modules/io/Process/#tecs.io.Process.InputMode) | <span class="tealdoc-kind-badge tealdoc-kind-enum">enum</span> | InputMode selects where a child reads standard input. |
| [`Options`](/modules/io/Process/#tecs.io.Process.Options) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | Options configures a child and its standard streams. |
| [`OutputMode`](/modules/io/Process/#tecs.io.Process.OutputMode) | <span class="tealdoc-kind-badge tealdoc-kind-enum">enum</span> | OutputMode selects where a child writes standard output. |
| [`Reader`](/modules/io/Process/#tecs.io.Process.Reader) | <span class="tealdoc-kind-badge tealdoc-kind-interface">interface</span> | Reader reads one live child-process output pipe. |
| [`Result`](/modules/io/Process/#tecs.io.Process.Result) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | Result contains a completed duplex exchange. |
| [`Writer`](/modules/io/Process/#tecs.io.Process.Writer) | <span class="tealdoc-kind-badge tealdoc-kind-interface">interface</span> | Writer writes one live child-process input pipe. |

### Functions

| Function | Kind | Description |
| --- | --- | --- |
| [`communicate`](/modules/io/Process/#tecs.io.Process.communicate) | <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span> | Feeds stdin and captures stdout and stderr without pipe deadlock. |
| [`isRunning`](/modules/io/Process/#tecs.io.Process.isRunning) | <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span> | Returns whether the child has not stopped yet. |
| [`kill`](/modules/io/Process/#tecs.io.Process.kill) | <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span> | Requests that the child terminate. |

### Values

| Value | Type | Description |
| --- | --- | --- |
| [`finished`](/modules/io/Process/#tecs.io.Process.finished) | [`Future`](/modules/Future/) | Read-only. Settles ready with the exit description after the child stops. |
| [`pid`](/modules/io/Process/#tecs.io.Process.pid) | `integer` | Read-only. Reports the operating-system process identifier. |
| [`stderr`](/modules/io/Process/#tecs.io.Process.stderr) | [`Reader`](/modules/io/Process/#tecs.io.Process.Reader) | Read-only. Provides standard error when its mode is "pipe", or nil when error output is inherited, discarded, or... |
| [`stdin`](/modules/io/Process/#tecs.io.Process.stdin) | [`Writer`](/modules/io/Process/#tecs.io.Process.Writer) | Read-only. Provides standard input when its mode is "pipe", or nil when input is inherited or discarded. |
| [`stdout`](/modules/io/Process/#tecs.io.Process.stdout) | [`Reader`](/modules/io/Process/#tecs.io.Process.Reader) | Read-only. Provides standard output when its mode is "pipe", or nil when output is inherited or discarded. |

## Constructors

<a id="tecs.io.Process.new"></a>
### tecs.io.Process.new <span class="tealdoc-kind-badge tealdoc-kind-static">Static</span>

Starts a caller-owned child process with streaming standard I/O.

Piped endpoints are nonblocking at their `readAvailable` and
`writeAvailable` boundaries. The process owns them, while buffers and
byte views passed to endpoint methods remain caller-owned.


```teal
function tecs.io.Process.new(options: Options): Process, string
```

#### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `options` | [`Options`](/modules/io/Process/#tecs.io.Process.Options) | The caller supplies the program, arguments, environment, working directory, standard-stream modes, and optional deadline. |

#### Returns

| Type | Description |
| --- | --- |
| [`Process`](/modules/io/Process/) | Returns a caller-owned process when the platform starts it. |
| `string` | Returns the platform reason when the first return is nil. |

#### Examples

```teal
tecs.scoped(function(scope: tecs.Scope)
    local child <const> = scope:own(tecs.io.Process.new({
        args = {"git", "status", "--porcelain"},
        cwd = tecs.io.Path.new("workspace"),
    }))

    local result, communicateReason = child:communicate()

    assert(result, communicateReason)
end)
```

```teal
tecs.scoped(function(scope: tecs.Scope)
    local child <const> = scope:own(tecs.io.Process.new({
        args = {"git", "rev-parse", "HEAD"},
        timeoutMs = 2000,
    }))

    local result, communicateReason = child:communicate()

    assert(result, communicateReason)
    assert(result:succeeded())
    print(result.output)
end)
```

## Types

<a id="tecs.io.Process.CommunicateOptions"></a>
### tecs.io.Process.CommunicateOptions <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

`CommunicateOptions` controls a complete duplex exchange.


```teal
record tecs.io.Process.CommunicateOptions
    input: string | ByteView
    maxOutputBytes: integer
end
```

<a id="tecs.io.Process.CommunicateOptions.input"></a>
#### tecs.io.Process.CommunicateOptions.input <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Supplies complete standard-input bytes as a string,
open [`Buffer`](/modules/io/#tecs.io.Buffer), or open
[`ByteView`](/modules/io/#tecs.io.ByteView). Omitted input sends EOF
immediately.


```teal
tecs.io.Process.CommunicateOptions.input: string | ByteView
```

<a id="tecs.io.Process.CommunicateOptions.maxOutputBytes"></a>
#### tecs.io.Process.CommunicateOptions.maxOutputBytes <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Limits stdout and stderr together. Defaults to
268,435,456 bytes. Exceeding it forcibly terminates the child and
returns a failure.


```teal
tecs.io.Process.CommunicateOptions.maxOutputBytes: integer
```

<a id="tecs.io.Process.ErrorMode"></a>
### tecs.io.Process.ErrorMode <span class="tealdoc-kind-badge tealdoc-kind-enum">enum</span>

`ErrorMode` selects where a child writes standard error.


```teal
enum tecs.io.Process.ErrorMode
    "inherit"
    "null"
    "pipe"
    "stdout"
end
```

<a id="tecs.io.Process.Exit"></a>
### tecs.io.Process.Exit <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

`Exit` describes how a child stopped.


```teal
record tecs.io.Process.Exit
    exitCode: integer
    killed: boolean
    timedOut: boolean

    succeeded: function(self): boolean
end
```

<a id="tecs.io.Process.Exit.exitCode"></a>
#### tecs.io.Process.Exit.exitCode <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports the platform exit code, or the platform's best
answer after termination.


```teal
tecs.io.Process.Exit.exitCode: integer
```

<a id="tecs.io.Process.Exit.killed"></a>
#### tecs.io.Process.Exit.killed <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports whether Tecs requested termination.


```teal
tecs.io.Process.Exit.killed: boolean
```

<a id="tecs.io.Process.Exit.timedOut"></a>
#### tecs.io.Process.Exit.timedOut <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports whether the configured deadline requested that
termination.


```teal
tecs.io.Process.Exit.timedOut: boolean
```

<a id="tecs.io.Process.Exit.succeeded"></a>
#### tecs.io.Process.Exit:succeeded <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Returns whether the child exited normally with code zero.



```teal
function tecs.io.Process.Exit.succeeded(self): boolean
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessExit` | The completed exit to inspect. |

##### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns true only for a normal zero exit. |

<a id="tecs.io.Process.InputMode"></a>
### tecs.io.Process.InputMode <span class="tealdoc-kind-badge tealdoc-kind-enum">enum</span>

`InputMode` selects where a child reads standard input.


```teal
enum tecs.io.Process.InputMode
    "inherit"
    "null"
    "pipe"
end
```

<a id="tecs.io.Process.Options"></a>
### tecs.io.Process.Options <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

`Options` configures a child and its standard streams.


```teal
record tecs.io.Process.Options
    args: {string}
    cwd: string | Path
    env: {string: string}
    clearEnv: boolean
    stdin: ProcessInputMode
    stdout: ProcessOutputMode
    stderr: ProcessErrorMode
    timeoutMs: integer
end
```

<a id="tecs.io.Process.Options.args"></a>
#### tecs.io.Process.Options.args <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Supplies the program in `args[1]` followed by its
arguments. A program without a separator resolves through `PATH`.


```teal
tecs.io.Process.Options.args: {string}
```

<a id="tecs.io.Process.Options.cwd"></a>
#### tecs.io.Process.Options.cwd <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Selects the child's working directory as a string or
[`Path`](/modules/io/Path/), or omits it to inherit the current
directory.


```teal
tecs.io.Process.Options.cwd: string | Path
```

<a id="tecs.io.Process.Options.env"></a>
#### tecs.io.Process.Options.env <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Overlays environment variables on the inherited
environment, or supplies the complete environment with `clearEnv`.


```teal
tecs.io.Process.Options.env: {string: string}
```

<a id="tecs.io.Process.Options.clearEnv"></a>
#### tecs.io.Process.Options.clearEnv <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Starts with an empty environment when true. Defaults
to false.


```teal
tecs.io.Process.Options.clearEnv: boolean
```

<a id="tecs.io.Process.Options.stdin"></a>
#### tecs.io.Process.Options.stdin <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Selects `"pipe"`, `"inherit"`, or `"null"` for
standard input. Defaults to `"pipe"`.


```teal
tecs.io.Process.Options.stdin: ProcessInputMode
```

<a id="tecs.io.Process.Options.stdout"></a>
#### tecs.io.Process.Options.stdout <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Selects `"pipe"`, `"inherit"`, or `"null"` for
standard output. Defaults to `"pipe"`.


```teal
tecs.io.Process.Options.stdout: ProcessOutputMode
```

<a id="tecs.io.Process.Options.stderr"></a>
#### tecs.io.Process.Options.stderr <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Selects `"pipe"`, `"inherit"`, `"null"`, or
`"stdout"` for standard error. Defaults to `"pipe"`.


```teal
tecs.io.Process.Options.stderr: ProcessErrorMode
```

<a id="tecs.io.Process.Options.timeoutMs"></a>
#### tecs.io.Process.Options.timeoutMs <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Caller-writable. Forcibly terminates the child after this many
milliseconds, or omits the deadline. The deadline begins when the
process is created.


```teal
tecs.io.Process.Options.timeoutMs: integer
```

<a id="tecs.io.Process.OutputMode"></a>
### tecs.io.Process.OutputMode <span class="tealdoc-kind-badge tealdoc-kind-enum">enum</span>

`OutputMode` selects where a child writes standard output.


```teal
enum tecs.io.Process.OutputMode
    "inherit"
    "null"
    "pipe"
end
```

<a id="tecs.io.Process.Reader"></a>
### tecs.io.Process.Reader <span class="tealdoc-kind-badge tealdoc-kind-interface">interface</span>

`Reader` reads one live child-process output pipe.


```teal
interface tecs.io.Process.Reader is Reader
    isClosed: function(self): boolean
    isEOF: function(self): boolean
    readAvailable: function(self, maxBytes: integer): string, string
    readAvailableInto: function(
        self, destination: Buffer, offset: integer, maxBytes: integer
    ): integer, string
end
```

#### Interfaces

| Interface |
| --- |
| [`Reader`](/modules/io/#tecs.io.Reader) |

<a id="tecs.io.Process.Reader.isClosed"></a>
#### tecs.io.Process.Reader:isClosed <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Returns whether this endpoint has been closed.



```teal
function tecs.io.Process.Reader.isClosed(self): boolean
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessReader` | The process reader to inspect. |

##### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns true after `close`. |

<a id="tecs.io.Process.Reader.isEOF"></a>
#### tecs.io.Process.Reader:isEOF <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Returns whether the child closed its end and every byte was consumed.



```teal
function tecs.io.Process.Reader.isEOF(self): boolean
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessReader` | The process reader to inspect. |

##### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns true after end of file. |

<a id="tecs.io.Process.Reader.readAvailable"></a>
#### tecs.io.Process.Reader:readAvailable <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Reads immediately available bytes without waiting.

Nil without a reason means the pipe remains open but has no bytes
ready. An empty string means end of file.


```teal
function tecs.io.Process.Reader.readAvailable(
    self, maxBytes: integer
): string, string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessReader` | The process reader whose pipe advances. |
| `maxBytes` | `integer` | The caller supplies 1 through 65,536 bytes or omits it for 16,384. |

##### Returns

| Type | Description |
| --- | --- |
| `string` | Returns available bytes, nil when none are ready, or an empty string at end of file. |
| `string` | Returns a reason only when reading fails. |

#### Examples

```teal
tecs.scoped(function(scope: tecs.Scope)
    local child <const> = scope:own(tecs.io.Process.new({
        args = {"/bin/sh", "-c", "sleep 1; printf ready"},
    }))

    local chunk <const>, readReason = child.stdout:readAvailable()

    assert(chunk == nil)
    assert(readReason == nil)
end)
```

<a id="tecs.io.Process.Reader.readAvailableInto"></a>
#### tecs.io.Process.Reader:readAvailableInto <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Reads immediately available bytes into reusable storage.

Nil without a reason means no bytes are ready. Zero means end of file.


```teal
function tecs.io.Process.Reader.readAvailableInto(
    self, destination: Buffer, offset: integer, maxBytes: integer
): integer, string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessReader` | The process reader whose pipe advances. |
| `destination` | [`Buffer`](/modules/io/#tecs.io.Buffer) | The caller supplies an open destination buffer and retains ownership. |
| `offset` | `integer` | The caller supplies a non-negative destination offset or omits it for zero. |
| `maxBytes` | `integer` | The caller supplies 1 through 65,536 bytes or omits it for 16,384. |

##### Returns

| Type | Description |
| --- | --- |
| `integer` | Returns bytes read, nil when none are ready, or zero at end of file. |
| `string` | Returns a reason only when reading fails. |

<a id="tecs.io.Process.Result"></a>
### tecs.io.Process.Result <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

`Result` contains a completed duplex exchange.


```teal
record tecs.io.Process.Result
    exit: ProcessExit
    output: string
    errorOutput: string

    succeeded: function(self): boolean
end
```

<a id="tecs.io.Process.Result.exit"></a>
#### tecs.io.Process.Result.exit <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains the child's exit description.


```teal
tecs.io.Process.Result.exit: ProcessExit
```

<a id="tecs.io.Process.Result.output"></a>
#### tecs.io.Process.Result.output <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains every captured standard-output byte. It is empty
when stdout was inherited or discarded.


```teal
tecs.io.Process.Result.output: string
```

<a id="tecs.io.Process.Result.errorOutput"></a>
#### tecs.io.Process.Result.errorOutput <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains every captured standard-error byte. It is empty
when stderr was inherited, discarded, or merged into stdout.


```teal
tecs.io.Process.Result.errorOutput: string
```

<a id="tecs.io.Process.Result.succeeded"></a>
#### tecs.io.Process.Result:succeeded <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Returns whether the child exited normally with code zero.



```teal
function tecs.io.Process.Result.succeeded(self): boolean
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessResult` | The completed exchange to inspect. |

##### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns true only for a normal zero exit. |

<a id="tecs.io.Process.Writer"></a>
### tecs.io.Process.Writer <span class="tealdoc-kind-badge tealdoc-kind-interface">interface</span>

`Writer` writes one live child-process input pipe.


```teal
interface tecs.io.Process.Writer is Writer
    isClosed: function(self): boolean
    writeAvailable: function(
        self, bytes: string, offset: integer, count: integer
    ): integer, string
    writeAvailableFrom: function(
        self, source: Buffer, offset: integer, count: integer
    ): integer, string
    writeAvailableView: function(
        self, source: ByteView, offset: integer, count: integer
    ): integer, string
end
```

#### Interfaces

| Interface |
| --- |
| [`Writer`](/modules/io/#tecs.io.Writer) |

<a id="tecs.io.Process.Writer.isClosed"></a>
#### tecs.io.Process.Writer:isClosed <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Returns whether this endpoint has sent EOF or been closed.



```teal
function tecs.io.Process.Writer.isClosed(self): boolean
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessWriter` | The process writer to inspect. |

##### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns true after `close`. |

<a id="tecs.io.Process.Writer.writeAvailable"></a>
#### tecs.io.Process.Writer:writeAvailable <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Writes as many immediately acceptable string bytes as possible.

Nil without a reason means the pipe has no capacity yet.


```teal
function tecs.io.Process.Writer.writeAvailable(
    self, bytes: string, offset: integer, count: integer
): integer, string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessWriter` | The process writer whose pipe advances. |
| `bytes` | `string` | The caller supplies binary bytes including embedded NULs. |
| `offset` | `integer` | The caller supplies a zero-based string offset or omits it for zero. |
| `count` | `integer` | The caller supplies a byte count or omits it for the remainder. |

##### Returns

| Type | Description |
| --- | --- |
| `integer` | Returns bytes accepted, or nil when none fit immediately. |
| `string` | Returns a reason only when writing fails. |

<a id="tecs.io.Process.Writer.writeAvailableFrom"></a>
#### tecs.io.Process.Writer:writeAvailableFrom <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Writes an immediately acceptable buffer prefix without a Lua string.



```teal
function tecs.io.Process.Writer.writeAvailableFrom(
    self, source: Buffer, offset: integer, count: integer
): integer, string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessWriter` | The process writer whose pipe advances. |
| `source` | [`Buffer`](/modules/io/#tecs.io.Buffer) | The caller supplies an open source buffer and retains ownership. |
| `offset` | `integer` | The caller supplies a zero-based source offset or omits it for zero. |
| `count` | `integer` | The caller supplies a byte count or omits it for the remainder. |

##### Returns

| Type | Description |
| --- | --- |
| `integer` | Returns bytes accepted, or nil when none fit immediately. |
| `string` | Returns a reason only when writing fails. |

<a id="tecs.io.Process.Writer.writeAvailableView"></a>
#### tecs.io.Process.Writer:writeAvailableView <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Writes an immediately acceptable immutable-view prefix.



```teal
function tecs.io.Process.Writer.writeAvailableView(
    self, source: ByteView, offset: integer, count: integer
): integer, string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `ProcessWriter` | The process writer whose pipe advances. |
| `source` | [`ByteView`](/modules/io/#tecs.io.ByteView) | The caller supplies an open source view and retains ownership. |
| `offset` | `integer` | The caller supplies a zero-based source offset or omits it for zero. |
| `count` | `integer` | The caller supplies a byte count or omits it for the remainder. |

##### Returns

| Type | Description |
| --- | --- |
| `integer` | Returns bytes accepted, or nil when none fit immediately. |
| `string` | Returns a reason only when writing fails. |

## Functions

<a id="tecs.io.Process.communicate"></a>
### tecs.io.Process:communicate <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Feeds stdin and captures stdout and stderr without pipe deadlock.

The call blocks the current Lua thread, drains both output pipes while
feeding input, closes stdin after the final byte, and returns only
after the child exits and both captured pipes reach EOF. Run it in a
worker when blocking is inappropriate.


```teal
function tecs.io.Process.communicate(
    self, options: CommunicateOptions
): Result, string
```

#### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Process` | The open process whose piped endpoints are consumed. |
| `options` | [`CommunicateOptions`](/modules/io/Process/#tecs.io.Process.CommunicateOptions) | The caller supplies complete input and an output limit, or omits both. |

#### Returns

| Type | Description |
| --- | --- |
| [`Result`](/modules/io/Process/#tecs.io.Process.Result) | Returns the complete exchange result. |
| `string` | Returns a reason when communication fails or exceeds its output limit. |

#### Examples

```teal
tecs.scoped(function(scope: tecs.Scope)
    local child <const> = scope:own(tecs.io.Process.new({
        args = {"/bin/cat"}
    }))

    local result, communicateReason = child:communicate({
        input = "request bytes\n",
        maxOutputBytes = 1024 * 1024,
    })

    assert(result, communicateReason)
    assert(result.output == "request bytes\n")
end)
```

<a id="tecs.io.Process.isRunning"></a>
### tecs.io.Process:isRunning <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Returns whether the child has not stopped yet.



```teal
function tecs.io.Process.isRunning(self): boolean
```

#### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Process` | The process to inspect. |

#### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns true while the child remains live. |

<a id="tecs.io.Process.kill"></a>
### tecs.io.Process:kill <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Requests that the child terminate.



```teal
function tecs.io.Process.kill(self, force: boolean): boolean, string
```

#### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Process` | The process to terminate. |
| `force` | `boolean` | The caller requests an unhandleable termination when true or a graceful request when false or omitted. |

#### Returns

| Type | Description |
| --- | --- |
| `boolean` | Returns whether the request was delivered or the child had already stopped. |
| `string` | Returns the platform reason when the first return is false. |

## Values

<a id="tecs.io.Process.finished"></a>
### tecs.io.Process.finished <span class="tealdoc-kind-badge tealdoc-kind-variable">variable</span>

Read-only. Settles ready with the exit description after the child
stops. Canceling this future does not terminate the separately owned
process.


```teal
tecs.io.Process.finished: Future<Exit>
```

<a id="tecs.io.Process.pid"></a>
### tecs.io.Process.pid <span class="tealdoc-kind-badge tealdoc-kind-variable">variable</span>

Read-only. Reports the operating-system process identifier.


```teal
tecs.io.Process.pid: integer
```

<a id="tecs.io.Process.stderr"></a>
### tecs.io.Process.stderr <span class="tealdoc-kind-badge tealdoc-kind-variable">variable</span>

Read-only. Provides standard error when its mode is `"pipe"`, or nil
when error output is inherited, discarded, or merged into stdout. The
process owns it.


```teal
tecs.io.Process.stderr: Reader
```

<a id="tecs.io.Process.stdin"></a>
### tecs.io.Process.stdin <span class="tealdoc-kind-badge tealdoc-kind-variable">variable</span>

Read-only. Provides standard input when its mode is `"pipe"`, or nil
when input is inherited or discarded. The process owns it.


```teal
tecs.io.Process.stdin: Writer
```

<a id="tecs.io.Process.stdout"></a>
### tecs.io.Process.stdout <span class="tealdoc-kind-badge tealdoc-kind-variable">variable</span>

Read-only. Provides standard output when its mode is `"pipe"`, or nil
when output is inherited or discarded. The process owns it.


```teal
tecs.io.Process.stdout: Reader
```