Module io/stdio
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
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) -> i32fd 0, for interop with fd-based APIs (e.g. BufReader.new).
Parameters
| Name | Type | Notes |
|---|---|---|
self | Stdin |
Returns: i32
impl(Stdin, Reader(...))
read : (Stdin) fn(self : &Stdin, buf : *(u8), size : usize, io : Io) -> Impl(Future(usize, IoExn))Methods
read_to_end : (Stdin) fn(self : &Stdin, io : Io) -> Impl(Future(ArrayList(u8), IoExn))read_to_string : (Stdin) fn(self : &Stdin, io : Io) -> Impl(Future(String, IoExn))The process's standard output (fd 1), a plain value like Stdin.
Trait Implementations
impl(Stdout, ...)
fd : (Stdout) fn(self : &Stdout) -> i32fd 1, for interop with fd-based APIs (e.g. BufWriter.new).
Parameters
| Name | Type | Notes |
|---|---|---|
self | Stdout |
Returns: i32
impl(Stdout, Writer(...))
write : (Stdout) fn(self : &Stdout, buf : *(u8), size : usize, io : Io) -> Impl(Future(usize, IoExn))Methods
write_all : (Stdout) fn(self : &Stdout, buf : *(u8), size : usize, io : Io) -> Impl(Future(unit, IoExn))The process's standard error (fd 2), a plain value like Stdin.
Trait Implementations
impl(Stderr, ...)
fd : (Stderr) fn(self : &Stderr) -> i32impl(Stderr, Writer(...))
write : (Stderr) fn(self : &Stderr, buf : *(u8), size : usize, io : Io) -> Impl(Future(usize, IoExn))Methods
write_all : (Stderr) fn(self : &Stderr, buf : *(u8), size : usize, io : Io) -> Impl(Future(unit, IoExn))