structstd.net.Stream[src]

Types

TypeReader[src]

Source Code

Source code
pub const Reader = io.Reader(Stream, ReadError, read)

TypeWriter[src]

Source Code

Source code
pub const Writer = io.Writer(Stream, WriteError, write)

Fields

handle: posix.socket_t

Underlying platform-defined type which may or may not be interchangeable with a file system file descriptor.

Error Sets

Error SetReadError[src]

Errors

anyerror means the error set is known only at runtime.

AccessDenied

In WASI, this error occurs when the file descriptor does not hold the required rights to read from it.

BrokenPipe
Canceled

reading a timerfd with CANCEL_ON_SET will lead to this error when the clock goes through a discontinuous change

ConnectionResetByPeer
ConnectionTimedOut
InputOutput
IsDir
LockViolation

Unable to read file due to lock.

NotOpenForReading
OperationAborted
ProcessNotFound

This error occurs in Linux if the process to be read from no longer exists.

SocketNotConnected
SystemResources
Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

WouldBlock

This error occurs when no global event loop is configured, and reading from the file descriptor would block.

Source Code

Source code
pub const ReadError = error{
    InputOutput,
    SystemResources,
    IsDir,
    OperationAborted,
    BrokenPipe,
    ConnectionResetByPeer,
    ConnectionTimedOut,
    NotOpenForReading,
    SocketNotConnected,

    /// This error occurs when no global event loop is configured,
    /// and reading from the file descriptor would block.
    WouldBlock,

    /// reading a timerfd with CANCEL_ON_SET will lead to this error
    /// when the clock goes through a discontinuous change
    Canceled,

    /// In WASI, this error occurs when the file descriptor does
    /// not hold the required rights to read from it.
    AccessDenied,

    /// This error occurs in Linux if the process to be read from
    /// no longer exists.
    ProcessNotFound,

    /// Unable to read file due to lock.
    LockViolation,
} || UnexpectedError

Error SetWriteError[src]

Errors

anyerror means the error set is known only at runtime.

AccessDenied

File descriptor does not hold the required rights to write to it.

BrokenPipe
ConnectionResetByPeer

Connection reset by peer.

DeviceBusy
DiskQuota
FileTooBig
InputOutput
InvalidArgument
LockViolation

The process cannot access the file because another process has locked a portion of the file. Windows-only.

NoDevice

This error occurs when a device gets disconnected before or mid-flush while it's being written to - errno(6): No such device or address.

NoSpaceLeft
NotOpenForWriting
OperationAborted
ProcessNotFound

This error occurs in Linux if the process being written to no longer exists.

SystemResources
Unexpected UnexpectedError

The Operating System returned an undocumented error code.

This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.

When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.

WouldBlock

This error occurs when no global event loop is configured, and reading from the file descriptor would block.

Source Code

Source code
pub const WriteError = error{
    DiskQuota,
    FileTooBig,
    InputOutput,
    NoSpaceLeft,
    DeviceBusy,
    InvalidArgument,

    /// File descriptor does not hold the required rights to write to it.
    AccessDenied,
    BrokenPipe,
    SystemResources,
    OperationAborted,
    NotOpenForWriting,

    /// The process cannot access the file because another process has locked
    /// a portion of the file. Windows-only.
    LockViolation,

    /// This error occurs when no global event loop is configured,
    /// and reading from the file descriptor would block.
    WouldBlock,

    /// Connection reset by peer.
    ConnectionResetByPeer,

    /// This error occurs in Linux if the process being written to
    /// no longer exists.
    ProcessNotFound,
    /// This error occurs when a device gets disconnected before or mid-flush
    /// while it's being written to - errno(6): No such device or address.
    NoDevice,
} || UnexpectedError

Functions

Functionclose[src]

pub fn close(s: Stream) void

Parameters

Source Code

Source code
pub fn close(s: Stream) void {
    switch (native_os) {
        .windows => windows.closesocket(s.handle) catch unreachable,
        else => posix.close(s.handle),
    }
}

Functionreader[src]

pub fn reader(self: Stream) Reader

Parameters

self: Stream

Source Code

Source code
pub fn reader(self: Stream) Reader {
    return .{ .context = self };
}

Functionwriter[src]

pub fn writer(self: Stream) Writer

Parameters

self: Stream

Source Code

Source code
pub fn writer(self: Stream) Writer {
    return .{ .context = self };
}

Functionread[src]

pub fn read(self: Stream, buffer: []u8) ReadError!usize

Parameters

self: Stream
buffer: []u8

Source Code

Source code
pub fn read(self: Stream, buffer: []u8) ReadError!usize {
    if (native_os == .windows) {
        return windows.ReadFile(self.handle, buffer, null);
    }

    return posix.read(self.handle, buffer);
}

Functionreadv[src]

pub fn readv(s: Stream, iovecs: []const posix.iovec) ReadError!usize

Parameters

iovecs: []const posix.iovec

Source Code

Source code
pub fn readv(s: Stream, iovecs: []const posix.iovec) ReadError!usize {
    if (native_os == .windows) {
        // TODO improve this to use ReadFileScatter
        if (iovecs.len == 0) return @as(usize, 0);
        const first = iovecs[0];
        return windows.ReadFile(s.handle, first.base[0..first.len], null);
    }

    return posix.readv(s.handle, iovecs);
}

FunctionreadAll[src]

pub fn readAll(s: Stream, buffer: []u8) ReadError!usize

Returns the number of bytes read. If the number read is smaller than buffer.len, it means the stream reached the end. Reaching the end of a stream is not an error condition.

Parameters

buffer: []u8

Source Code

Source code
pub fn readAll(s: Stream, buffer: []u8) ReadError!usize {
    return readAtLeast(s, buffer, buffer.len);
}

FunctionreadAtLeast[src]

pub fn readAtLeast(s: Stream, buffer: []u8, len: usize) ReadError!usize

Returns the number of bytes read, calling the underlying read function the minimal number of times until the buffer has at least len bytes filled. If the number read is less than len it means the stream reached the end. Reaching the end of the stream is not an error condition.

Parameters

buffer: []u8
len: usize

Source Code

Source code
pub fn readAtLeast(s: Stream, buffer: []u8, len: usize) ReadError!usize {
    assert(len <= buffer.len);
    var index: usize = 0;
    while (index < len) {
        const amt = try s.read(buffer[index..]);
        if (amt == 0) break;
        index += amt;
    }
    return index;
}

Functionwrite[src]

pub fn write(self: Stream, buffer: []const u8) WriteError!usize

TODO in evented I/O mode, this implementation incorrectly uses the event loop's file system thread instead of non-blocking. It needs to be reworked to properly use non-blocking I/O.

Parameters

self: Stream
buffer: []const u8

Source Code

Source code
pub fn write(self: Stream, buffer: []const u8) WriteError!usize {
    if (native_os == .windows) {
        return windows.WriteFile(self.handle, buffer, null);
    }

    return posix.write(self.handle, buffer);
}

FunctionwriteAll[src]

pub fn writeAll(self: Stream, bytes: []const u8) WriteError!void

Parameters

self: Stream
bytes: []const u8

Source Code

Source code
pub fn writeAll(self: Stream, bytes: []const u8) WriteError!void {
    var index: usize = 0;
    while (index < bytes.len) {
        index += try self.write(bytes[index..]);
    }
}

Functionwritev[src]

pub fn writev(self: Stream, iovecs: []const posix.iovec_const) WriteError!usize

See https://github.com/ziglang/zig/issues/7699 See equivalent function: std.fs.File.writev.

Parameters

self: Stream
iovecs: []const posix.iovec_const

Source Code

Source code
pub fn writev(self: Stream, iovecs: []const posix.iovec_const) WriteError!usize {
    return posix.writev(self.handle, iovecs);
}

FunctionwritevAll[src]

pub fn writevAll(self: Stream, iovecs: []posix.iovec_const) WriteError!void

The iovecs parameter is mutable because this function needs to mutate the fields in order to handle partial writes from the underlying OS layer. See https://github.com/ziglang/zig/issues/7699 See equivalent function: std.fs.File.writevAll.

Parameters

self: Stream
iovecs: []posix.iovec_const

Source Code

Source code
pub fn writevAll(self: Stream, iovecs: []posix.iovec_const) WriteError!void {
    if (iovecs.len == 0) return;

    var i: usize = 0;
    while (true) {
        var amt = try self.writev(iovecs[i..]);
        while (amt >= iovecs[i].len) {
            amt -= iovecs[i].len;
            i += 1;
            if (i >= iovecs.len) return;
        }
        iovecs[i].base += amt;
        iovecs[i].len -= amt;
    }
}

Source Code

Source code
pub const Stream = struct {
    /// Underlying platform-defined type which may or may not be
    /// interchangeable with a file system file descriptor.
    handle: posix.socket_t,

    pub fn close(s: Stream) void {
        switch (native_os) {
            .windows => windows.closesocket(s.handle) catch unreachable,
            else => posix.close(s.handle),
        }
    }

    pub const ReadError = posix.ReadError;
    pub const WriteError = posix.WriteError;

    pub const Reader = io.Reader(Stream, ReadError, read);
    pub const Writer = io.Writer(Stream, WriteError, write);

    pub fn reader(self: Stream) Reader {
        return .{ .context = self };
    }

    pub fn writer(self: Stream) Writer {
        return .{ .context = self };
    }

    pub fn read(self: Stream, buffer: []u8) ReadError!usize {
        if (native_os == .windows) {
            return windows.ReadFile(self.handle, buffer, null);
        }

        return posix.read(self.handle, buffer);
    }

    pub fn readv(s: Stream, iovecs: []const posix.iovec) ReadError!usize {
        if (native_os == .windows) {
            // TODO improve this to use ReadFileScatter
            if (iovecs.len == 0) return @as(usize, 0);
            const first = iovecs[0];
            return windows.ReadFile(s.handle, first.base[0..first.len], null);
        }

        return posix.readv(s.handle, iovecs);
    }

    /// Returns the number of bytes read. If the number read is smaller than
    /// `buffer.len`, it means the stream reached the end. Reaching the end of
    /// a stream is not an error condition.
    pub fn readAll(s: Stream, buffer: []u8) ReadError!usize {
        return readAtLeast(s, buffer, buffer.len);
    }

    /// Returns the number of bytes read, calling the underlying read function
    /// the minimal number of times until the buffer has at least `len` bytes
    /// filled. If the number read is less than `len` it means the stream
    /// reached the end. Reaching the end of the stream is not an error
    /// condition.
    pub fn readAtLeast(s: Stream, buffer: []u8, len: usize) ReadError!usize {
        assert(len <= buffer.len);
        var index: usize = 0;
        while (index < len) {
            const amt = try s.read(buffer[index..]);
            if (amt == 0) break;
            index += amt;
        }
        return index;
    }

    /// TODO in evented I/O mode, this implementation incorrectly uses the event loop's
    /// file system thread instead of non-blocking. It needs to be reworked to properly
    /// use non-blocking I/O.
    pub fn write(self: Stream, buffer: []const u8) WriteError!usize {
        if (native_os == .windows) {
            return windows.WriteFile(self.handle, buffer, null);
        }

        return posix.write(self.handle, buffer);
    }

    pub fn writeAll(self: Stream, bytes: []const u8) WriteError!void {
        var index: usize = 0;
        while (index < bytes.len) {
            index += try self.write(bytes[index..]);
        }
    }

    /// See https://github.com/ziglang/zig/issues/7699
    /// See equivalent function: `std.fs.File.writev`.
    pub fn writev(self: Stream, iovecs: []const posix.iovec_const) WriteError!usize {
        return posix.writev(self.handle, iovecs);
    }

    /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
    /// order to handle partial writes from the underlying OS layer.
    /// See https://github.com/ziglang/zig/issues/7699
    /// See equivalent function: `std.fs.File.writevAll`.
    pub fn writevAll(self: Stream, iovecs: []posix.iovec_const) WriteError!void {
        if (iovecs.len == 0) return;

        var i: usize = 0;
        while (true) {
            var amt = try self.writev(iovecs[i..]);
            while (amt >= iovecs[i].len) {
                amt -= iovecs[i].len;
                i += 1;
                if (i >= iovecs.len) return;
            }
            iovecs[i].base += amt;
            iovecs[i].len -= amt;
        }
    }
}