pipe
import pipe from "pipe";
import io from "io";
import time from "time";
fn main() -> i32 {
var l: pipe.Listener = pipe.listen("director") or { return 1; };
// another program: pipe.connect("director")
var pane: pipe.Stream = l.accept(time.seconds(10)) or {
io.println("no pane: {err}");
return 2;
};
pane.write_all("run step 1\n") or { return 3; };
let reply: ?string = pane.read_line(time.seconds(5)) or {
io.println("no answer: {err}"); // TimedOut
return 4;
};
if (reply != null) { io.println("pane says {reply!}"); }
pane.close();
l.close();
return 0;
}pipe connects programs on the same machine. One program listens on a
name; others connect to it; each connection is a stream of bytes both ways.
On Windows it is a named pipe, \\.\pipe\<name>, which any program can
also open as a file. On Linux and macOS it is a Unix domain socket, a
socket file in the temporary directory. Not available on Uusi.
Listening
| Function | Does |
|---|---|
listen(name) -> Listener or io.IoError | Listen on name |
l.accept(timeout) -> Stream or io.IoError | The next client’s connection; TimedOut after timeout |
l.path() -> string | Where the pipe is |
l.close() | Stop listening (removes the socket file on Linux and macOS) |
listen fails with AddrInUse when another program listens on the name.
A socket file left behind by a program that ended without closing is
replaced. When accept times out the listener keeps listening: call it
again. Leave the timeout out to wait without limit.
Connecting
| Function | Does |
|---|---|
connect(name, timeout) -> Stream or io.IoError | Connect to the program listening on name |
path(name) -> string | Where the pipe called name is: \\.\pipe\<name>, or a file in the temporary directory |
connect fails with NotFound when nothing is there (ConnectionRefused
on Linux and macOS for a socket file no one listens on). On Windows it
waits at most timeout while the pipe is busy. A name with a path
separator in it is used as a path as it is.
Streams
| Function | Does |
|---|---|
s.read(buf, timeout) -> i64 or io.IoError | Up to buf.len bytes; 0 once the other end has closed |
s.read_line(timeout) -> ?string or io.IoError | The next line without its newline; null at the end |
s.write(data) -> i64 or io.IoError / s.write_all(data) | Write some / all of data |
s.reader() -> io.Reader / s.writer() -> io.Writer | For read_all, BufReader, BufWriter, fmt (no timeout) |
s.close() | Close this end: the other end reads the end |
Every timeout is an optional time.Duration: left out, the call waits as
long as it takes; when it passes, the call fails with TimedOut.
read_line’s timeout is for the whole line, and a line it timed out on is
kept: the next call carries on with it. A write fails with BrokenPipe
once the other end has closed.
Last modified: