Processrecord
A running child.
Methods
drop
drop: nosuspend function(takes self: process.Process): nil
Arguments
| Name | Type | Description |
|---|
takes self | process.Process | |
Returns
constructor
Starts a child process.
The child is an owner: closing it ends the process, waits for the exit, and releases every stream, and the same runs when its scope ends. Reading a stream or waiting for the exit suspends, so a caller under a scheduler keeps its frame.
local child = new process.Process({
args = {"grep", "-c", "nupp"},
stderr = "stdout",
})
local result = assert(child:communicate({input = text}))
child:close()
Arguments
| Name | Type | Description |
|---|
self | any | the process being initialized |
options | process.Options | what to run and how to connect it |
Returns
Raises
destroy
destroy: function destroy(takes self): nil
Releases the process when its owner leaves scope.
Arguments
| Name | Type | Description |
|---|
takes self | any | |
Returns
isRunning
isRunning: function isRunning(self): boolean
Whether it is still running.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
wait
wait: function wait(self): process.Exit
Waits for it to end and answers how.
Suspends while it runs.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
| Type | Description |
|---|
process.Exit | |
kill
kill: function kill(self, force: boolean?): boolean, string?
Asks the direct child to end; force insists. Descendants keep their ordinary operating-system lifetime. Answers whether the request was made.
Arguments
| Name | Type | Description |
|---|
self | any | |
force | boolean? | |
Returns
| Type | Description |
|---|
boolean | |
string? | |
communicate
Writes input, closes stdin, drains stdout and stderr, and waits for the exit. Answers the complete exchange or a reason it could not be completed.
One combined step per pass: offer some input, take whatever each output has, suspend only when none of the three moved.
Arguments
Returns
| Type | Description |
|---|
process.Result? | |
string? | |
close
close: function close(self): boolean, string?
Closes every stream, ends the child if it is still running, waits for it to actually finish, and releases it. Idempotent, and what drop runs when the owner goes out of lexical scope.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
| Type | Description |
|---|
boolean | |
string? | |
Raises
Fields
pid
Operating-system process identifier.
stdin
Its standard input, when it was piped.
stdout
Its standard output, when it was piped.
stderr
Its standard error, when it was piped.
Readerrecord
record process.Reader is Reader2
timeoutMs: integer
function isEOF(self): boolean end
function isClosed(self): boolean end
function poll(self, limit: integer?): string? end
function next(self): string? end
function readCompletion(self, limit: integer): (string?, string?) end
function setTimeout(self, timeoutMs: integer): nil end
function read(self, count: integer): (string?, string?) end
function readSpan(self, exclusive destination: span.Writable<uint8>): (integer?, string?) end
function readInto(self, exclusive destination: Buffer, offset: integer?, count: integer?): (integer?, string?) end
function transferTo(self, exclusive destination: Writer2): (integer?, string?) end
function close(takes self): nil end
end
One of a child's readable streams.
Its blocking read and its nonblocking poll are both here on purpose. A caller draining several streams at once cannot use the blocking form on any of them, because waiting on one is exactly what starves the others, which is the whole reason communicate can drain three pipes without deadlocking.
The completion-oriented nupp.io.Reader methods are the public tecs-compatible surface. poll remains alongside them as the concrete nonblocking operation the combined drain needs; generic readers are not widened with readiness operations.
The tolerance that does exist is narrow and worth naming exactly: closing the same live opaque handle twice is harmless, because the second call finds the stream already released and says so. Destroying a handle while a borrowed reference still exists leaves that reference reading freed memory, which no amount of care at the call site can make safe.
Borrowing the record through asReader keeps a single owner and makes its lifetime a question about Nupp values, which the checker can answer.
Methods
isEOF
isEOF: function isEOF(self): boolean
Whether the far end has finished.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
isClosed
isClosed: function isClosed(self): boolean
Whether this end has been closed.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
poll
poll: function poll(self, limit: integer?): string?
Takes whatever is available without waiting: the bytes, "" when nothing is ready yet, or nil at end of stream.
The non-blocking half of reading, which communicate needs so that one quiet stream does not stop it serving another. limit caps how many bytes to take, defaulting to a whole pipe's worth. It is here because the shared nupp.io.Reader promises "at most count". Without the limit its completion-oriented method would have to keep surplus bytes beside this record, giving end of stream and closedness two homes. One place decides both, and the caller says how much it wants.
Zero and negative polling limits read one byte. This concrete nonblocking operation keeps that defensive behavior even though the shared Reader contract requires a positive count. Settled here rather than at the platform because the platform is where it stops being a number and becomes a buffer size: a signed zero or minus one arriving at a native size conversion is either an empty read that looks like end of stream or an enormous one, and neither is worth being able to ask for. read passes its caller's count straight through.
Arguments
| Name | Type | Description |
|---|
self | any | |
limit | integer? | |
Returns
next
next: function next(self): string?
Reads the next available bytes, suspending until there are some. Answers nil at end of stream.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
readCompletion
readCompletion: function readCompletion(self, limit: integer): string?, string?
The shared Reader operation uses the concrete bounded poll but still waits through the same state machine as every other completion-oriented call. Keeping the limit here avoids a surplus buffer and its second notion of EOF.
Arguments
| Name | Type | Description |
|---|
self | any | |
limit | integer | |
Returns
| Type | Description |
|---|
string? | |
string? | |
setTimeout
setTimeout: function setTimeout(self, timeoutMs: integer): nil
Bounds the next completion-oriented read.
Arguments
| Name | Type | Description |
|---|
self | any | |
timeoutMs | integer | |
Returns
Raises
read
read: function read(self, count: integer): string?, string?
Arguments
| Name | Type | Description |
|---|
self | any | |
count | integer | |
Returns
| Type | Description |
|---|
string? | |
string? | |
readSpan
readSpan: function readSpan(self, exclusive destination: span.Writable<uint8>): integer?, string?
Arguments
| Name | Type | Description |
|---|
self | any | |
exclusive destination | span.Writable<uint8> | |
Returns
| Type | Description |
|---|
integer? | |
string? | |
readInto
readInto: function readInto(self, exclusive destination: Buffer, offset: integer?, count: integer?): integer?, string?
Arguments
| Name | Type | Description |
|---|
self | any | |
exclusive destination | Buffer | |
offset | integer? | |
count | integer? | |
Returns
| Type | Description |
|---|
integer? | |
string? | |
transferTo
transferTo: function transferTo(self, exclusive destination: Writer2): integer?, string?
Arguments
| Name | Type | Description |
|---|
self | any | |
exclusive destination | Writer2 | |
Returns
| Type | Description |
|---|
integer? | |
string? | |
close
close: function close(takes self): nil
Arguments
| Name | Type | Description |
|---|
takes self | any | |
Returns
Fields
timeoutMs
Maximum time one completion-oriented read may wait.
Writerrecord
record process.Writer is Writer2
timeoutMs: integer
function isGone(self): boolean end
function isClosed(self): boolean end
function offer(self, data: string): integer end
function send(self, data: string, stopAt: number?, stallFor: integer?): integer end
function setTimeout(self, timeoutMs: integer): nil end
function write(exclusive self, bytes: string): (boolean, string?) end
function writeSpan(exclusive self, borrows source: span.ByteSpan): (integer?, string?) end
function flush(self): (boolean, string?) end
function close(takes self): nil end
end
A child's writable stream.
offer and isGone are the nonblocking half, for the same reason the reader has poll: the prelude's nupp.io.Writer.write writes the whole value, which a drain loop serving three pipes cannot afford to wait for. The completion-oriented write remains the ordinary nupp.io.Writer operation; offer is concrete and additional.
Methods
isGone
isGone: function isGone(self): boolean
Whether the far end has gone: the child is no longer reading this, and no amount of waiting will change that.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
isClosed
isClosed: function isClosed(self): boolean
Whether this end has been closed.
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
offer
offer: function offer(self, data: string): integer
Writes what the pipe will take without waiting. Answers how many bytes went, which may be none and may be fewer than offered.
Arguments
| Name | Type | Description |
|---|
self | any | |
data | string | |
Returns
send
send: function send(self, data: string, stopAt: number?, stallFor: integer?): integer
Writes every byte, suspending as often as the pipe makes it. Answers how many went, which is all of them unless the far end went away first.
Arguments
| Name | Type | Description |
|---|
self | any | |
data | string | |
stopAt | number? | |
stallFor | integer? | |
Returns
setTimeout
setTimeout: function setTimeout(self, timeoutMs: integer): nil
Bounds the next completion-oriented write.
Arguments
| Name | Type | Description |
|---|
self | any | |
timeoutMs | integer | |
Returns
Raises
write
write: function write(exclusive self, bytes: string): boolean, string?
Arguments
| Name | Type | Description |
|---|
exclusive self | any | |
bytes | string | |
Returns
| Type | Description |
|---|
boolean | |
string? | |
writeSpan
writeSpan: function writeSpan(exclusive self, borrows source: span.ByteSpan): integer?, string?
Arguments
| Name | Type | Description |
|---|
exclusive self | any | |
borrows source | span.ByteSpan | |
Returns
| Type | Description |
|---|
integer? | |
string? | |
flush
flush: function flush(self): boolean, string?
Arguments
| Name | Type | Description |
|---|
self | any | |
Returns
| Type | Description |
|---|
boolean | |
string? | |
close
close: function close(takes self): nil
Arguments
| Name | Type | Description |
|---|
takes self | any | |
Returns
Fields
timeoutMs
Maximum time one completion-oriented write may wait.