Browse the docs

silk.platform.native.descriptor.

Reads and writes on file descriptors that the caller owns, for native providers.

When to use#

Use NativeDescriptor to build a native provider, such as silk.io.writer_native or silk.io.standard_input_native. Application code uses the Writer and StandardInput effects instead.

Details#

One system call transfers at most 0x7ffff000 bytes. A call that a signal interrupts is made again. An empty buffer makes no system call. The functions never close the descriptor.

Errors#

Each function returns false on failure and writes the native error code to error, or 0 when the system returned a count that is not valid.

Gotchas#

  • The caller keeps the descriptor open and controls access from other threads.

  • NativeDescriptor.writeAll and NativeDescriptor.writeAllGather can fail after part of the bytes were written.

  • The module is empty on targets other than Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.

Examples#

Make empty transfers#

silk
import silk.platform.native.descriptor { NativeDescriptor }

pub fn main() -> i32 {
  let mut nativeError = 0

  // Descriptor 1 is standard output. An empty write makes no system call.
  let written = run NativeDescriptor.writeAll(1, b"", &mut nativeError)
  if !written || nativeError != 0 {
    return 1
  }

  // A read of zero bytes also makes no system call.
  let mut empty: [u8; 0] = []
  let mut count: usize = 7
  let read = run NativeDescriptor.read(0, &mut empty, &mut count, &mut nativeError)
  if !read || count != 0 {
    return 1
  }
  return 0
}

Import as NativeDescriptor with import silk.platform.native.descriptor { NativeDescriptor }.

Public declarations: 5.

read#

silk
pub unsafe extern "C" fn read(fd: i32, buffer: ?[*]mut u8, count: usize) -> isize

The C read function: reads at most count bytes from fd into buffer.

Gotchas#

buffer must have count writable bytes during the call. After a negative result, read the error code at once.

write#

silk
pub unsafe extern "C" fn write(fd: i32, buffer: ?[*]const u8, count: usize) -> isize

The C write function: writes at most count bytes from buffer to fd.

Gotchas#

buffer must have count readable bytes during the call. A positive result can be less than count. After a negative result, read the error code at once.

isatty#

silk
pub unsafe extern "C" fn isatty(fd: i32) -> i32

The C isatty function: returns 1 when fd is a terminal, else 0.

__error#

silk
pub unsafe extern "C" fn __error() -> *mut i32

Returns the error code slot of the thread on Darwin. Read it at once after a failed call.

NativeDescriptor#

silk
pub struct NativeDescriptor

Safe reads and writes on a descriptor that the caller owns, for native providers.

When to use#

Use it to build a native provider, such as silk.io.writer_native or silk.io.standard_input_native. Application code uses the Writer and StandardInput effects instead.

Details#

One system call transfers at most 0x7ffff000 bytes. A call that a signal interrupts is made again. An empty buffer makes no system call. The functions never close the descriptor. Each function returns false on failure and writes the native error code to error, or 0 when the system returned a count that is not valid.

Gotchas#

  • The caller keeps the descriptor open and controls access from other threads.

  • The type is empty on targets other than Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.

Implementation NativeDescriptor#

silk
impl NativeDescriptor

Associated function read#

silk
pub effect fn read(fd: i32, buffer: &mut [u8], count: &mut usize, error: &mut i32) -> bool

Reads one time from fd into the start of buffer, and returns whether it succeeded.

Details#

On success, count is the number of bytes read. Zero means the end of input, or an empty buffer. On failure, count is zero and error is the native error code, or zero for a count that is not valid. Bytes after the count are not changed.

Associated function isTerminal#

silk
pub effect fn isTerminal(fd: i32) -> bool

Returns whether fd, such as 2 for standard error, is a terminal. A closed descriptor, a pipe, a file, or a failed query answers false.

Associated function writeAll#

silk
pub effect fn writeAll(fd: i32, buffer: &[u8], error: &mut i32) -> bool

Writes all of buffer to fd, and returns whether it succeeded.

Details#

It calls write until all bytes are written. On failure, error is the native error code, or zero if the system wrote nothing or returned a count that is not valid.

Gotchas#

Part of buffer can be written before a failure. Do not write all of it again without a check.

Associated function writeAllGather#

silk
pub effect fn writeAllGather(fd: i32, head: &[u8], rest: &[&[u8]], error: &mut i32) -> bool

Writes all of head and then all bytes of each slice of rest to fd, in order, and returns whether it succeeded.

When to use#

Use it to send buffered bytes and new slices together, without first copying the slices into the buffer. Pass an empty head when there is no buffer.

Details#

Each system call is one writev of at most eight non-empty slices and at most 0x7ffff000 bytes. After a partial write, the next call starts at the first byte that was not written. Empty slices add nothing to a call. A call that a signal interrupts is made again. On failure, error is the native error code, or zero if the system wrote nothing or returned a count that is not valid.

Gotchas#

Part of the bytes can be written before a failure. Do not write all of them again without a check.

Category: Native platform.

Profiles: aarch64-apple-darwin.

View the source of this page