Module io/stdio

io/stdio
Stability: unstable — may still change; see below.

Typed standard-stream handles — stdin() / stdout() / stderr() (plans/archive/STD_API_AUDIT.md §D5).

Each handle wraps its well-known file descriptor (0/1/2) and implements the async Reader/Writer traits from std/io, so code written against the traits works on the standard streams the same way it works on a File or a TcpStream. This is the typed replacement for the BufReader.new(i32(0)) magic number.

The handles are UNBUFFERED: every read/write is one async syscall, and they keep NO offset of their own. Each transfer passes offset u64.MAX, which the runtime reads as "the descriptor's own position" (read(2)/write(2), not pread/pwrite; std/sys/file's offset rules). So every stdout() handle, every stderr() handle redirected onto the same file (2>&1), libc's stdout and a parent shell's earlier writes all share the kernel's one file position: a stream redirected to a regular file is appended to, never overwritten (issues/fixed/stddoc-io-stdio-handles-write-positionally-and-clobber-redirected-output.md).

Sharing the position is not sharing a buffer: std/fmt's print and println write through libc's buffered stdout, which flushes when its buffer fills or at exit, so text printed before a handle write can land AFTER it (no bytes are lost). Flush libc first (std/libc/stdio's fflush) when the order across the two writers matters.

There is no write_string here: the handles carry exactly the trait surface, whose write/write_all take a raw *(u8), so writing text from safe code goes through BufWriter(Stdout) (which has write_string/write_bytes) or through std/fmt. Likewise the line primitive for input is BufReader(Stdin).read_line, not a method here.

Stability

unstable — Rust's io::stdout() returns a handle to ONE shared, locked stream that println! also writes through, while stdout() here returns an independent, unbuffered object and std/fmt keeps libc's own buffer (the ordering note above). Joining the two writers is the open question. The three types, the three accessors and the fd() methods are expected to keep their names.

Types

Stdin struct
Stdin

The process's standard input (fd 0). A plain value: it holds no state, so copies are free and every copy reads the same descriptor.

Trait Implementations

impl(Stdin, ...)
fd : (Stdin) fn(self : &Stdin) -> i32

fd 0, for interop with fd-based APIs (e.g. BufReader.new).

Parameters

NameTypeNotes
selfStdin

Returns: i32

impl(Stdin, Reader(...))
read : (Stdin) fn(self : &Stdin, buf : *(u8), size : usize, io : Io) -> Impl(Future(usize, IoExn))

Read up to size bytes into buf. Resolves to the number of bytes actually read; 0 means end-of-stream. Throws IoExn on failure.

Parameters

NameTypeNotes
selfStdin
buf*(u8)
sizeusize
ioIo

Returns: Impl(Future(usize, IoExn))

Methods
clone : (Stdin) fn(self : &Stdin) -> Stdin

Parameters

NameTypeNotes
selfStdin

Returns: Stdin

read_to_end : (Stdin) fn(self : &Stdin, io : Io) -> Impl(Future(ArrayList(u8), IoExn))

Read until end-of-stream, resolving to all remaining bytes. Loops the raw read straight into the result's spare capacity, doubling it whenever it fills (Rust's default_read_to_end), so implementors get it for free and callers never touch a raw pointer.

Parameters

NameTypeNotes
selfStdin
ioIo

Returns: Impl(Future(ArrayList(u8), IoExn))

read_to_string : (Stdin) fn(self : &Stdin, io : Io) -> Impl(Future(String, IoExn))

Read until end-of-stream and decode as UTF-8. Unlike the UNCHECKED per-type conveniences that predate D5, this validates: malformed bytes throw IoError.InvalidData (use read_to_end + String.from_utf8 to see the exact offset).

Parameters

NameTypeNotes
selfStdin
ioIo

Returns: Impl(Future(String, IoExn))

Stdout struct
Stdout

The process's standard output (fd 1), a plain value like Stdin.

Trait Implementations

impl(Stdout, ...)
fd : (Stdout) fn(self : &Stdout) -> i32

fd 1, for interop with fd-based APIs (e.g. BufWriter.new).

Parameters

NameTypeNotes
selfStdout

Returns: i32

impl(Stdout, Writer(...))
write : (Stdout) fn(self : &Stdout, buf : *(u8), size : usize, io : Io) -> Impl(Future(usize, IoExn))

Write up to size bytes from buf. Resolves to the number of bytes actually written (which may be less than size). Throws IoExn on failure.

Parameters

NameTypeNotes
selfStdout
buf*(u8)
sizeusize
ioIo

Returns: Impl(Future(usize, IoExn))

flush : (Stdout) fn(self : &Stdout, io : Io) -> Impl(Future(unit, IoExn))

Flush any buffered bytes through to the underlying sink. Unbuffered writers resolve immediately.

Parameters

NameTypeNotes
selfStdout
ioIo

Returns: Impl(Future(unit, IoExn))

Methods
clone : (Stdout) fn(self : &Stdout) -> Stdout

Parameters

NameTypeNotes
selfStdout

Returns: Stdout

write_all : (Stdout) fn(self : &Stdout, buf : *(u8), size : usize, io : Io) -> Impl(Future(unit, IoExn))

Write ALL size bytes from buf, looping the raw write over short counts. Throws IoError.WriteZero if the sink stops accepting bytes before everything is delivered.

Parameters

NameTypeNotes
selfStdout
buf*(u8)
sizeusize
ioIo

Returns: Impl(Future(unit, IoExn))

Stderr struct
Stderr

The process's standard error (fd 2), a plain value like Stdin.

Trait Implementations

impl(Stderr, ...)
fd : (Stderr) fn(self : &Stderr) -> i32

fd 2, for interop with fd-based APIs.

Parameters

NameTypeNotes
selfStderr

Returns: i32

impl(Stderr, Writer(...))
write : (Stderr) fn(self : &Stderr, buf : *(u8), size : usize, io : Io) -> Impl(Future(usize, IoExn))

Write up to size bytes from buf. Resolves to the number of bytes actually written (which may be less than size). Throws IoExn on failure.

Parameters

NameTypeNotes
selfStderr
buf*(u8)
sizeusize
ioIo

Returns: Impl(Future(usize, IoExn))

flush : (Stderr) fn(self : &Stderr, io : Io) -> Impl(Future(unit, IoExn))

Flush any buffered bytes through to the underlying sink. Unbuffered writers resolve immediately.

Parameters

NameTypeNotes
selfStderr
ioIo

Returns: Impl(Future(unit, IoExn))

Methods
clone : (Stderr) fn(self : &Stderr) -> Stderr

Parameters

NameTypeNotes
selfStderr

Returns: Stderr

write_all : (Stderr) fn(self : &Stderr, buf : *(u8), size : usize, io : Io) -> Impl(Future(unit, IoExn))

Write ALL size bytes from buf, looping the raw write over short counts. Throws IoError.WriteZero if the sink stops accepting bytes before everything is delivered.

Parameters

NameTypeNotes
selfStderr
buf*(u8)
sizeusize
ioIo

Returns: Impl(Future(unit, IoExn))

Functions

stdin function
fn() -> Stdin

Handle to standard input.

Returns: Stdin

stdout function
fn() -> Stdout

Handle to standard output.

Returns: Stdout

stderr function
fn() -> Stderr

Handle to standard error.

Returns: Stderr