From c90911c7cf5cc47d11217d6686a0b175ac8d7d1b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 11 Jul 2023 16:13:17 -0700 Subject: [PATCH 1/2] Update to resources. --- command.md | 1659 +++++++++++++-------------- wit/deps/clocks/timezone.wit | 30 +- wit/deps/filesystem/preopens.wit | 6 + wit/deps/filesystem/types.wit | 988 ++++++++-------- wit/deps/filesystem/world.wit | 1 + wit/deps/io/streams.wit | 342 +++--- wit/deps/poll/poll.wit | 39 +- wit/deps/sockets/ip-name-lookup.wit | 14 +- wit/deps/sockets/network.wit | 12 +- wit/deps/sockets/tcp.wit | 63 +- wit/deps/sockets/udp.wit | 48 +- wit/terminal.wit | 32 +- 12 files changed, 1539 insertions(+), 1695 deletions(-) create mode 100644 wit/deps/filesystem/preopens.wit diff --git a/command.md b/command.md index 646c049..f096a09 100644 --- a/command.md +++ b/command.md @@ -78,27 +78,11 @@ also known as Unix Time.

Types

-

type pollable

-

u32

-

A "pollable" handle. -

This is conceptually represents a stream<_, _>, or in other words, -a stream that one can wait on, repeatedly, but which does not itself -produce any data. It's temporary scaffolding until component-model's -async features are ready.

-

And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

-

pollable lifetimes are not automatically managed. Users must ensure -that they do not outlive the resource they reference.

-

This represents a resource.

+

resource pollable

+
Resource Members
+

TODO


Functions

-

drop-pollable: func

-

Dispose of the specified pollable, after which it may no longer -be used.

-
Params
-

poll-oneoff: func

Poll for completion on a set of pollables.

The "oneoff" in the name refers to the fact that this function must do a @@ -107,18 +91,16 @@ inefficient if the number is large and the same subscriptions are used many times. In the future, this is expected to be obsoleted by the component model async proposal, which will include a scalable waiting facility.

-

Note that the return type would ideally be list<bool>, but that would -be more difficult to polyfill given the current state of wit-bindgen. -See https://github.com/bytecodealliance/preview2-prototyping/pull/11#issuecomment-1329873061 -for details. For now, we use zero to mean "not ready" and non-zero to -mean "ready".

+

The result list is the same length as the argument +list, and indicates the readiness of each corresponding +element in that / list, with true indicating ready.

Params
Return values

Import interface wasi:clocks/monotonic-clock

WASI Monotonic Clock is a clock API intended to let users measure elapsed @@ -162,7 +144,7 @@ reached.

Return values

Import interface wasi:clocks/timezone


@@ -170,14 +152,17 @@ reached.

type datetime

datetime

-#### `record timezone-display` +#### `resource timezone` +

Resource Members
+

TODO

+

record timezone-display

Information useful for displaying the timezone of a specific datetime.

This information may vary within a single timezone to reflect daylight saving time adjustments.

Record Fields
-

type timezone

-

u32

-

A timezone. -

In timezones that recognize daylight saving time, also known as daylight -time and summer time, the information returned from the functions varies -over time to reflect these adjustments.

-

This represents a resource.


Functions

-

display: func

+

[method]timezone.display: func

Return information needed to display the given datetime. This includes the UTC offset, the time zone name, and a flag indicating whether daylight saving time is active.

If the timezone cannot be determined for the given datetime, return a -timezone-display for UTC with a utc-offset of 0 and no daylight +timezone-display for UTC with a utc-offset of 0 and no daylight saving time.

Params
Return values
-

utc-offset: func

-

The same as display, but only return the UTC offset.

+

[method]timezone.utc-offset: func

+

The same as display, but only return the UTC offset.

Params
Return values
-

drop-timezone: func

-

Dispose of the specified input-stream, after which it may no longer -be used.

-
Params
-

Import interface wasi:io/streams

WASI I/O is an I/O abstraction API which is currently focused on providing @@ -259,46 +230,39 @@ when it does, they are expected to subsume this API.

An error type returned from a stream operation. Currently this doesn't provide any additional information.

Record Fields
-

type output-stream

-

u32

-

An output bytestream. In the future, this will be replaced by handle -types. -

This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

-

output-streams are non-blocking to the extent practical on -underlying platforms. Except where specified otherwise, I/O operations also -always return promptly, after the number of bytes that can be written -promptly, which could even be zero. To wait for the stream to be ready to -accept data, the subscribe-to-output-stream function to obtain a -pollable which can be polled for using wasi_poll.

-

And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

-

This represents a resource.

-

type input-stream

-

u32

-

An input bytestream. In the future, this will be replaced by handle -types. -

This conceptually represents a stream<u8, _>. It's temporary -scaffolding until component-model's async features are ready.

-

input-streams are non-blocking to the extent practical on underlying -platforms. I/O operations always return promptly; if fewer bytes are -promptly available than requested, they return the number of bytes promptly -available, which could even be zero. To wait for data to be available, -use the subscribe-to-input-stream function to obtain a pollable which -can be polled for using wasi_poll.

-

And at present, it is a u32 instead of being an actual handle, until -the wit-bindgen implementation of handles and resources is ready.

-

This represents a resource.

+

enum stream-status

+

Streams provide a sequence of data and then end; once they end, they +no longer provide any further data.

+

For example, a stream reading from a file ends when the stream reaches +the end of the file. For another example, a stream reading from a +socket ends when the socket is closed.

+
Enum Cases
+ +

resource input-stream

+
Resource Members
+

TODO

+

resource output-stream

+
Resource Members
+

TODO


Functions

-

read: func

+

[method]input-stream.read: func

Read bytes from a stream.

This function returns a list of bytes containing the data that was -read, along with a bool which, when true, indicates that the end of the -stream was reached. The returned list will contain up to len bytes; it -may return fewer than requested, but not more.

+read, along with a stream-status which indicates whether the end of +the stream was reached. The returned list will contain up to len +bytes; it may return fewer than requested, but not more.

Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +skip will always report end-of-stream rather than producing more data.

If len is 0, it represents a request to read 0 bytes, which should always succeed, assuming the stream hasn't reached its end yet, and @@ -308,130 +272,123 @@ a buffer as large as that would imply. FIXME: describe what happens if allocation fails.

Params
Return values
-

blocking-read: func

+

[method]input-stream.blocking-read: func

Read bytes from a stream, with blocking.

-

This is similar to read, except that it blocks until at least one +

This is similar to read, except that it blocks until at least one byte can be read.

Params
Return values
-

skip: func

+

[method]input-stream.skip: func

Skip bytes from a stream.

-

This is similar to the read function, but avoids copying the +

This is similar to the read function, but avoids copying the bytes into the instance.

Once a stream has reached the end, subsequent calls to read or -skip will always report end-of-stream rather than producing more +skip will always report end-of-stream rather than producing more data.

-

This function returns the number of bytes skipped, along with a bool -indicating whether the end of the stream was reached. The returned -value will be at most len; it may be less.

+

This function returns the number of bytes skipped, along with a +stream-status indicating whether the end of the stream was +reached. The returned value will be at most len; it may be less.

Params
Return values
-

blocking-skip: func

+

[method]input-stream.blocking-skip: func

Skip bytes from a stream, with blocking.

-

This is similar to skip, except that it blocks until at least one +

This is similar to skip, except that it blocks until at least one byte can be consumed.

Params
Return values
-

subscribe-to-input-stream: func

+

[method]input-stream.subscribe-to-input-stream: func

Create a pollable which will resolve once either the specified stream has bytes available to read or the other end of the stream has been closed.

Params
Return values
-

drop-input-stream: func

-

Dispose of the specified input-stream, after which it may no longer -be used.

-
Params
- -

write: func

+

[method]output-stream.write: func

Write bytes to a stream.

This function returns a u64 indicating the number of bytes from buf that were written; it may be less than the full list.

Params
Return values
-

blocking-write: func

+

[method]output-stream.blocking-write: func

Write bytes to a stream, with blocking.

-

This is similar to write, except that it blocks until at least one +

This is similar to write, except that it blocks until at least one byte can be written.

Params
Return values
-

write-zeroes: func

+

[method]output-stream.write-zeroes: func

Write multiple zero bytes to a stream.

This function returns a u64 indicating the number of zero bytes that were written; it may be less than len.

Params
Return values
-

blocking-write-zeroes: func

+

[method]output-stream.blocking-write-zeroes: func

Write multiple zero bytes to a stream, with blocking.

-

This is similar to write-zeroes, except that it blocks until at least +

This is similar to write-zeroes, except that it blocks until at least one byte can be written.

Params
Return values
-

splice: func

+

[method]output-stream.splice: func

Read from one stream and write to another.

This function returns the number of bytes transferred; it may be less than len.

@@ -439,29 +396,29 @@ than len.

read from the input stream has been written to the output stream.

Params
Return values
-

blocking-splice: func

+

[method]output-stream.blocking-splice: func

Read from one stream and write to another, with blocking.

-

This is similar to splice, except that it blocks until at least +

This is similar to splice, except that it blocks until at least one byte can be read.

Params
Return values
-

forward: func

+

[method]output-stream.forward: func

Forward the entire contents of an input stream to an output stream.

This function repeatedly reads from the input stream and writes the data to the output stream, until the end of the input stream @@ -472,30 +429,23 @@ the output stream.

This function returns the number of bytes transferred.

Params
Return values
-

subscribe-to-output-stream: func

+

[method]output-stream.subscribe-to-output-stream: func

Create a pollable which will resolve once either the specified stream is ready to accept bytes or the other end of the stream has been closed.

Params
Return values
-

drop-output-stream: func

-

Dispose of the specified output-stream, after which it may no longer -be used.

-
Params
-

Import interface wasi:filesystem/types

WASI filesystem is a filesystem API primarily intended to let users run WASI @@ -524,7 +474,108 @@ underlying filesystem, the function fails with `type datetime` [`datetime`](#datetime)

-#### `flags path-flags` +#### `type filesize` +`u64` +

File size or length of a region within a file. +

enum descriptor-type

+

The type of a filesystem object referenced by a descriptor.

+

Note: This was called filetype in earlier versions of WASI.

+
Enum Cases
+ +

flags descriptor-flags

+

Descriptor flags.

+

Note: This was called fdflags in earlier versions of WASI.

+
Flags members
+ +

flags path-flags

Flags determining the method of how paths are resolved.

Flags members

flags open-flags

-

Open flags used by open-at.

+

Open flags used by open-at.

Flags members

flags modes

-

Permissions mode used by open-at, change-file-permissions-at, and +

Permissions mode used by open-at, change-file-permissions-at, and similar.

Flags members
+

variant access-type

+

Access type used by access-at.

+
Variant Cases
+

type link-count

u64

Number of hard links to an inode. +

type device

+

u64

+

Identifier for a device containing a file system. Can be used in +combination with `inode` to uniquely identify a file or directory in +the filesystem.

type inode

u64

Filesystem object serial number that is unique within its file system. -

type filesize

-

u64

-

File size or length of a region within a file. +

record descriptor-stat

+

File attributes.

+

Note: This was called filestat in earlier versions of WASI.

+
Record Fields
+ +

variant new-timestamp

+

When setting a timestamp, this gives the value to set it to.

+
Variant Cases
+ +

record directory-entry

+

A directory entry.

+
Record Fields
+

enum error-code

Error codes returned by functions, similar to errno in POSIX. Not all of these error codes are returned by the functions provided by this @@ -675,259 +819,68 @@ merely for alignment with POSIX.

No such file or directory, similar to `ENOENT` in POSIX.

  • -

    no-lock

    -

    No locks available, similar to `ENOLCK` in POSIX. -

  • -
  • -

    insufficient-memory

    -

    Not enough space, similar to `ENOMEM` in POSIX. -

  • -
  • -

    insufficient-space

    -

    No space left on device, similar to `ENOSPC` in POSIX. -

  • -
  • -

    not-directory

    -

    Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. -

  • -
  • -

    not-empty

    -

    Directory not empty, similar to `ENOTEMPTY` in POSIX. -

  • -
  • -

    not-recoverable

    -

    State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. -

  • -
  • -

    unsupported

    -

    Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. -

  • -
  • -

    no-tty

    -

    Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. -

  • -
  • -

    no-such-device

    -

    No such device or address, similar to `ENXIO` in POSIX. -

  • -
  • -

    overflow

    -

    Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. -

  • -
  • -

    not-permitted

    -

    Operation not permitted, similar to `EPERM` in POSIX. -

  • -
  • -

    pipe

    -

    Broken pipe, similar to `EPIPE` in POSIX. -

  • -
  • -

    read-only

    -

    Read-only file system, similar to `EROFS` in POSIX. -

  • -
  • -

    invalid-seek

    -

    Invalid seek, similar to `ESPIPE` in POSIX. -

  • -
  • -

    text-file-busy

    -

    Text file busy, similar to `ETXTBSY` in POSIX. -

  • -
  • -

    cross-device

    -

    Cross-device link, similar to `EXDEV` in POSIX. -

  • - -

    type directory-entry-stream

    -

    u32

    -

    A stream of directory entries. -

    This represents a stream of dir-entry.

    -

    type device

    -

    u64

    -

    Identifier for a device containing a file system. Can be used in -combination with `inode` to uniquely identify a file or directory in -the filesystem. -

    enum descriptor-type

    -

    The type of a filesystem object referenced by a descriptor.

    -

    Note: This was called filetype in earlier versions of WASI.

    -
    Enum Cases
    - -

    record directory-entry

    -

    A directory entry.

    -
    Record Fields
    - -

    flags descriptor-flags

    -

    Descriptor flags.

    -

    Note: This was called fdflags in earlier versions of WASI.

    -
    Flags members
    - -

    type descriptor

    -

    u32

    -

    A descriptor is a reference to a filesystem object, which may be a file, -directory, named pipe, special file, or other object on which filesystem -calls may be made. -

    This represents a resource.

    -

    variant new-timestamp

    -

    When setting a timestamp, this gives the value to set it to.

    -
    Variant Cases
    - -

    record descriptor-stat

    -

    File attributes.

    -

    Note: This was called filestat in earlier versions of WASI.

    -
    Record Fields
    -

    enum advice

    @@ -965,158 +918,154 @@ in the near future. not reuse it thereafter. -

    variant access-type

    -

    Access type used by access-at.

    -
    Variant Cases
    - +

    resource descriptor

    +
    Resource Members
    +

    TODO

    +

    resource directory-entry-stream

    +
    Resource Members
    +

    TODO


    Functions

    -

    read-via-stream: func

    -

    Return a stream for reading from a file.

    +

    [method]descriptor.read-via-stream: func

    +

    Return a stream for reading from a file, if available.

    +

    May fail with an error-code describing why the file cannot be read.

    Multiple read, write, and append streams may be active on the same open file and they do not interfere with each other.

    -

    Note: This allows using read-stream, which is similar to read in POSIX.

    +

    Note: This allows using read-stream, which is similar to read in POSIX.

    Params
    Return values
    -

    write-via-stream: func

    -

    Return a stream for writing to a file.

    -

    Note: This allows using write-stream, which is similar to write in +

    [method]descriptor.write-via-stream: func

    +

    Return a stream for writing to a file, if available.

    +

    May fail with an error-code describing why the file cannot be written.

    +

    Note: This allows using write-stream, which is similar to write in POSIX.

    Params
    Return values
    -

    append-via-stream: func

    -

    Return a stream for appending to a file.

    -

    Note: This allows using write-stream, which is similar to write with +

    [method]descriptor.append-via-stream: func

    +

    Return a stream for appending to a file, if available.

    +

    May fail with an error-code describing why the file cannot be appended.

    +

    Note: This allows using write-stream, which is similar to write with O_APPEND in in POSIX.

    Params
    Return values
    -

    advise: func

    +

    [method]descriptor.advise: func

    Provide file advisory information on a descriptor.

    This is similar to posix_fadvise in POSIX.

    Params
    Return values
    -

    sync-data: func

    +

    [method]descriptor.sync-data: func

    Synchronize the data of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fdatasync in POSIX.

    Params
    Return values
    -

    get-flags: func

    +

    [method]descriptor.get-flags: func

    Get flags associated with a descriptor.

    Note: This returns similar flags to fcntl(fd, F_GETFL) in POSIX.

    Note: This returns the value that was the fs_flags value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    get-type: func

    +

    [method]descriptor.get-type: func

    Get the dynamic type of a descriptor.

    Note: This returns the same value as the type field of the fd-stat -returned by stat, stat-at and similar.

    +returned by stat, stat-at and similar.

    Note: This returns similar flags to the st_mode & S_IFMT value provided by fstat in POSIX.

    Note: This returns the value that was the fs_filetype value returned from fdstat_get in earlier versions of WASI.

    Params
    Return values
    -

    set-flags: func

    +

    [method]descriptor.set-flags: func

    Set status flags associated with a descriptor.

    This function may only change the non-blocking flag.

    Note: This is similar to fcntl(fd, F_SETFL, flags) in POSIX.

    Note: This was called fd_fdstat_set_flags in earlier versions of WASI.

    Params
    Return values
    -

    set-size: func

    +

    [method]descriptor.set-size: func

    Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.

    Note: This was called fd_filestat_set_size in earlier versions of WASI.

    Params
    Return values
    -

    set-times: func

    +

    [method]descriptor.set-times: func

    Adjust the timestamps of an open file or directory.

    Note: This is similar to futimens in POSIX.

    Note: This was called fd_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    read: func

    +

    [method]descriptor.read: func

    Read from a descriptor, without using and updating the descriptor's offset.

    This function returns a list of bytes containing the data that was read, along with a bool which, when true, indicates that the end of the @@ -1127,15 +1076,15 @@ if the I/O operation is interrupted.

    Note: This is similar to pread in POSIX.

    Params
    Return values
    -

    write: func

    +

    [method]descriptor.write: func

    Write to a descriptor, without using and updating the descriptor's offset.

    It is valid to write past the end of a file; the file is extended to the extent of the write, with bytes between the previous end and the start of @@ -1144,15 +1093,15 @@ the write set to zero.

    Note: This is similar to pwrite in POSIX.

    Params
    Return values
    -

    read-directory: func

    +

    [method]descriptor.read-directory: func

    Read directory entries from a directory.

    On filesystems where directories contain entries referring to themselves and their parents, often named . and .. respectively, these entries @@ -1162,96 +1111,96 @@ directory. Multiple streams may be active on the same directory, and they do not interfere with each other.

    Params
    Return values
    -

    sync: func

    +

    [method]descriptor.sync: func

    Synchronize the data and metadata of a file to disk.

    This function succeeds with no effect if the file descriptor is not opened for writing.

    Note: This is similar to fsync in POSIX.

    Params
    Return values
    -

    create-directory-at: func

    +

    [method]descriptor.create-directory-at: func

    Create a directory.

    Note: This is similar to mkdirat in POSIX.

    Params
    Return values
    -

    stat: func

    +

    [method]descriptor.stat: func

    Return the attributes of an open file or directory.

    Note: This is similar to fstat in POSIX.

    Note: This was called fd_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    stat-at: func

    +

    [method]descriptor.stat-at: func

    Return the attributes of a file or directory.

    Note: This is similar to fstatat in POSIX.

    Note: This was called path_filestat_get in earlier versions of WASI.

    Params
    Return values
    -

    set-times-at: func

    +

    [method]descriptor.set-times-at: func

    Adjust the timestamps of a file or directory.

    Note: This is similar to utimensat in POSIX.

    Note: This was called path_filestat_set_times in earlier versions of WASI.

    Params
    Return values
    -

    link-at: func

    +

    [method]descriptor.link-at: func

    Create a hard link.

    Note: This is similar to linkat in POSIX.

    Params
    Return values
    -

    open-at: func

    +

    [method]descriptor.open-at: func

    Open a file or directory.

    The returned descriptor is not guaranteed to be the lowest-numbered descriptor not currently open/ it is randomized to prevent applications @@ -1260,82 +1209,82 @@ error-prone in multi-threaded contexts. The returned descriptor is guaranteed to be less than 2**31.

    If flags contains descriptor-flags::mutate-directory, and the base descriptor doesn't have descriptor-flags::mutate-directory set, -open-at fails with error-code::read-only.

    -

    If flags contains write or mutate-directory, or open-flags +open-at fails with error-code::read-only.

    +

    If flags contains write or mutate-directory, or open-flags contains truncate or create, and the base descriptor doesn't have -descriptor-flags::mutate-directory set, open-at fails with +descriptor-flags::mutate-directory set, open-at fails with error-code::read-only.

    Note: This is similar to openat in POSIX.

    Params
    Return values
    -

    readlink-at: func

    +

    [method]descriptor.readlink-at: func

    Read the contents of a symbolic link.

    If the contents contain an absolute or rooted path in the underlying filesystem, this function fails with error-code::not-permitted.

    Note: This is similar to readlinkat in POSIX.

    Params
    Return values
    -

    remove-directory-at: func

    +

    [method]descriptor.remove-directory-at: func

    Remove a directory.

    Return error-code::not-empty if the directory is not empty.

    Note: This is similar to unlinkat(fd, path, AT_REMOVEDIR) in POSIX.

    Params
    Return values
    -

    rename-at: func

    +

    [method]descriptor.rename-at: func

    Rename a filesystem object.

    Note: This is similar to renameat in POSIX.

    Params
    Return values
    -

    symlink-at: func

    +

    [method]descriptor.symlink-at: func

    Create a symbolic link (also known as a "symlink").

    If old-path starts with /, the function fails with error-code::not-permitted.

    Note: This is similar to symlinkat in POSIX.

    Params
    Return values
    -

    access-at: func

    +

    [method]descriptor.access-at: func

    Check accessibility of a filesystem path.

    Check whether the given filesystem path names an object which is readable, writable, or executable, or whether it exists.

    @@ -1345,64 +1294,64 @@ entities.

    Note: This is similar to faccessat with the AT_EACCESS flag in POSIX.

    Params
    Return values
    -

    unlink-file-at: func

    +

    [method]descriptor.unlink-file-at: func

    Unlink a filesystem object that is not a directory.

    Return error-code::is-directory if the path refers to a directory. Note: This is similar to unlinkat(fd, path, 0) in POSIX.

    Params
    Return values
    -

    change-file-permissions-at: func

    +

    [method]descriptor.change-file-permissions-at: func

    Change the permissions of a filesystem object that is not a directory.

    Note that the ultimate meanings of these permissions is filesystem-specific.

    Note: This is similar to fchmodat in POSIX.

    Params
    Return values
    -

    change-directory-permissions-at: func

    +

    [method]descriptor.change-directory-permissions-at: func

    Change the permissions of a directory.

    Note that the ultimate meanings of these permissions is filesystem-specific.

    Unlike in POSIX, the executable flag is not reinterpreted as a "search" -flag. read on a directory implies readability and searchability, and +flag. read on a directory implies readability and searchability, and execute is not valid for directories.

    Note: This is similar to fchmodat in POSIX.

    Params
    Return values
    -

    lock-shared: func

    +

    [method]descriptor.lock-shared: func

    Request a shared advisory lock for an open file.

    This requests a shared lock; more than one shared lock can be held for a file at the same time.

    @@ -1418,13 +1367,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_SH) in Unix.

    Params
    Return values
    -

    lock-exclusive: func

    +

    [method]descriptor.lock-exclusive: func

    Request an exclusive advisory lock for an open file.

    This requests an exclusive lock; no other locks may be held for the file while an exclusive lock is held.

    @@ -1442,13 +1391,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_EX) in Unix.

    Params
    Return values
    -

    try-lock-shared: func

    +

    [method]descriptor.try-lock-shared: func

    Request a shared advisory lock for an open file.

    This requests a shared lock; more than one shared lock can be held for a file at the same time.

    @@ -1465,13 +1414,13 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_SH | LOCK_NB) in Unix.

    Params
    Return values
    -

    try-lock-exclusive: func

    +

    [method]descriptor.try-lock-exclusive: func

    Request an exclusive advisory lock for an open file.

    This requests an exclusive lock; no other locks may be held for the file while an exclusive lock is held.

    @@ -1490,114 +1439,39 @@ locking, this function returns error-cod

    Note: This is similar to flock(fd, LOCK_EX | LOCK_NB) in Unix.

    Params
    Return values
    -

    unlock: func

    +

    [method]descriptor.unlock: func

    Release a shared or exclusive lock on an open file.

    Note: This is similar to flock(fd, LOCK_UN) in Unix.

    Params
    Return values
    -

    drop-descriptor: func

    -

    Dispose of the specified descriptor, after which it may no longer -be used.

    -
    Params
    - -

    read-directory-entry: func

    +

    [method]directory-entry-stream.read-directory-entry: func

    Read a single directory entry from a directory-entry-stream.

    Params
    Return values
    -

    drop-directory-entry-stream: func

    -

    Dispose of the specified directory-entry-stream, after which it may no longer -be used.

    -
    Params
    -

    Import interface wasi:sockets/network


    Types

    -

    type network

    -

    u32

    -

    An opaque resource that represents access to (a subset of) the network. -This enables context-based security for networking. -There is no need for this to map 1:1 to a physical network interface. -

    FYI, In the future this will be replaced by handle types.

    -

    tuple ipv6-address

    -
    Tuple Fields
    -
      -
    • 0: u16
    • -
    • 1: u16
    • -
    • 2: u16
    • -
    • 3: u16
    • -
    • 4: u16
    • -
    • 5: u16
    • -
    • 6: u16
    • -
    • 7: u16
    • -
    -

    record ipv6-socket-address

    -
    Record Fields
    - -

    tuple ipv4-address

    -
    Tuple Fields
    -
      -
    • 0: u8
    • -
    • 1: u8
    • -
    • 2: u8
    • -
    • 3: u8
    • -
    -

    record ipv4-socket-address

    -
    Record Fields
    - -

    variant ip-socket-address

    -
    Variant Cases
    - -

    enum ip-address-family

    -
    Enum Cases
    -
      -
    • -

      ipv4

      -

      Similar to `AF_INET` in POSIX. -

    • -
    • -

      ipv6

      -

      Similar to `AF_INET6` in POSIX. -

    • -
    -

    variant ip-address

    -
    Variant Cases
    - +

    resource network

    +
    Resource Members
    +

    TODO

    enum error-code

    Error codes.

    In theory, every API can return any error code. @@ -1747,14 +1621,63 @@ combined with a couple of errors that are always possible:

    A permanent failure in name resolution occurred. -


    -

    Functions

    -

    drop-network: func

    -

    Dispose of the specified network, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    +

    enum ip-address-family

    +
    Enum Cases
    +
      +
    • +

      ipv4

      +

      Similar to `AF_INET` in POSIX. +

    • +
    • +

      ipv6

      +

      Similar to `AF_INET6` in POSIX. +

    • +
    +

    tuple ipv4-address

    +
    Tuple Fields
    +
      +
    • 0: u8
    • +
    • 1: u8
    • +
    • 2: u8
    • +
    • 3: u8
    • +
    +

    tuple ipv6-address

    +
    Tuple Fields
    +
      +
    • 0: u16
    • +
    • 1: u16
    • +
    • 2: u16
    • +
    • 3: u16
    • +
    • 4: u16
    • +
    • 5: u16
    • +
    • 6: u16
    • +
    • 7: u16
    • +
    +

    variant ip-address

    +
    Variant Cases
    + +

    record ipv4-socket-address

    +
    Record Fields
    + +

    record ipv6-socket-address

    +
    Record Fields
    + +

    variant ip-socket-address

    +
    Variant Cases

    Import interface wasi:sockets/instance-network

    This interface provides a value-export of the default network handle..

    @@ -1769,7 +1692,7 @@ combined with a couple of errors that are always possible:

    Get a handle to the default network.

    Return values

    Import interface wasi:sockets/ip-name-lookup


    @@ -1789,10 +1712,10 @@ combined with a couple of errors that are always possible:

    #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type resolve-address-stream` -`u32` -

    ----- +#### `resource resolve-address-stream` +

    Resource Members
    +

    TODO

    +

    Functions

    resolve-addresses: func

    Resolve an internet host name to a list of IP addresses.

    @@ -1801,7 +1724,7 @@ combined with a couple of errors that are always possible:

    • name: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted to ASCII using IDNA encoding.
    • -
    • address-family: If provided, limit the results to addresses of this specific address family.
    • +
    • address-family: If provided, limit the results to addresses of this specific address family.
    • include-unavailable: When set to true, this function will also return addresses of which the runtime thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on systems without an active IPv6 interface. Notes:
    • @@ -1811,12 +1734,12 @@ systems without an active IPv6 interface. Notes:

      This function never blocks. It either immediately fails or immediately returns successfully with a resolve-address-stream that can be used to (asynchronously) fetch the results.

      At the moment, the stream never completes successfully with 0 items. Ie. the first call -to resolve-next-address never returns ok(none). This may change in the future.

      +to resolve-next-address never returns ok(none). This may change in the future.

      Typical errors

      • invalid-name: name is a syntactically invalid domain name.
      • invalid-name: name is an IP address.
      • -
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)
      • +
      • address-family-not-supported: The specified address-family is not supported. (EAI_FAMILY)

      References:

      Params
      Return values
      -

      resolve-next-address: func

      +

      [method]resolve-address-stream.resolve-next-address: func

      Returns the next address from the resolver.

      This function should be called multiple times. On each call, it will return the next address in connection order preference. If all addresses have been exhausted, this function returns none. -After which, you should release the stream with drop-resolve-address-stream.

      +After which, you should release the stream with drop-resolve-address-stream.

      This function never returns IPv4-mapped IPv6 addresses.

      Typical errors

      Return values
      -

      drop-resolve-address-stream: func

      -

      Dispose of the specified resolve-address-stream, after which it may no longer be used.

      -

      Note: this function is scheduled to be removed when Resources are natively supported in Wit.

      -
      Params
      - -

      subscribe: func

      +

      [method]resolve-address-stream.subscribe: func

      Create a pollable which will resolve once the stream is ready for I/O.

      Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

      Params
      Return values

      Import interface wasi:sockets/tcp


      @@ -1901,18 +1817,15 @@ It's planned to be removed when future is natively supported in Pre #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

      -#### `type tcp-socket` -`u32` -

      A TCP socket handle. -

      enum shutdown-type

      +#### `enum shutdown-type`
      Enum Cases
      • -

        receive

        +

        receive

        Similar to `SHUT_RD` in POSIX.

      • -

        send

        +

        send

        Similar to `SHUT_WR` in POSIX.

      • @@ -1920,9 +1833,12 @@ It's planned to be removed when future is natively supported in Pre

        Similar to `SHUT_RDWR` in POSIX.

      +

      resource tcp-socket

      +
      Resource Members
      +

      TODO


      Functions

      -

      start-bind: func

      +

      [method]tcp-socket.start-bind: func

      Bind the socket to a specific network on the provided IP address and port.

      If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -1932,7 +1848,7 @@ implicitly bind the socket.

      Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

      Typical start errors

        -
      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
      • +
      • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
      • already-bound: The socket is already bound. (EINVAL)
      • concurrency-conflict: Another bind, connect or listen operation is already in progress. (EALREADY)
      @@ -1940,7 +1856,7 @@ implicitly bind the socket.

      • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
      • address-in-use: Address is already in use. (EADDRINUSE)
      • -
      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
      • +
      • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
      • not-in-progress: A bind operation is not in progress.
      • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
      @@ -1953,24 +1869,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]tcp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]tcp-socket.start-connect: func

    Connect to a remote endpoint.

    On success:

      @@ -1979,9 +1895,9 @@ implicitly bind the socket.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EADDRNOTAVAIL on Windows)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EADDRNOTAVAIL on Windows)
    • already-attached: The socket is already attached to a different network. The network passed to connect must be identical to the one passed to bind.
    • already-connected: The socket is already in the Connection state. (EISCONN)
    • already-listening: The socket is already in the Listener state. (EOPNOTSUPP, EINVAL on Windows)
    • @@ -2006,24 +1922,24 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]tcp-socket.finish-connect: func

    Params
    Return values
    -

    start-listen: func

    +

    [method]tcp-socket.start-listen: func

    Start listening for new connections.

    Transitions the socket into the Listener state.

    Unlike POSIX:

    @@ -2053,22 +1969,22 @@ implicitly bind the socket.

    Params
    Return values
    -

    finish-listen: func

    +

    [method]tcp-socket.finish-listen: func

    Params
    Return values
    -

    accept: func

    +

    [method]tcp-socket.accept: func

    Accept a new client socket.

    The returned socket is bound and in the Connection state.

    On success, this function returns the newly accepted client socket along with @@ -2088,13 +2004,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    local-address: func

    +

    [method]tcp-socket.local-address: func

    Get the bound local address.

    Typical errors

      @@ -2109,13 +2025,13 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    remote-address: func

    +

    [method]tcp-socket.remote-address: func

    Get the bound remote address.

    Typical errors

      @@ -2130,24 +2046,24 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    address-family: func

    +

    [method]tcp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]tcp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -2159,23 +2075,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]tcp-socket.set-ipv6-only: func

    Params
    Return values
    -

    set-listen-backlog-size: func

    +

    [method]tcp-socket.set-listen-backlog-size: func

    Hints the desired listen queue size. Implementations are free to ignore this.

    Typical errors

      @@ -2184,14 +2100,14 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    keep-alive: func

    +

    [method]tcp-socket.keep-alive: func

    Equivalent to the SO_KEEPALIVE socket option.

    Typical errors

      @@ -2199,23 +2115,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-keep-alive: func

    +

    [method]tcp-socket.set-keep-alive: func

    Params
    Return values
    -

    no-delay: func

    +

    [method]tcp-socket.no-delay: func

    Equivalent to the TCP_NODELAY socket option.

    Typical errors

      @@ -2223,23 +2139,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-no-delay: func

    +

    [method]tcp-socket.set-no-delay: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]tcp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

      @@ -2249,23 +2165,23 @@ a pair of streams that can be used to read & write to the connection.

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]tcp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]tcp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    @@ -2281,59 +2197,59 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]tcp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]tcp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]tcp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]tcp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    shutdown: func

    +

    [method]tcp-socket.shutdown: func

    Initiate a graceful shutdown.

    • receive: the socket is not expecting to receive any more data from the peer. All subsequent read operations on the input-stream associated with this socket will return an End Of Stream indication. -Any data still in the receive queue at time of calling shutdown will be discarded.
    • +Any data still in the receive queue at time of calling shutdown will be discarded.
    • send: the socket is not expecting to send any more data to the peer. All subsequent write operations on the output-stream associated with this socket will return an error.
    • both: same effect as receive & send combined.
    • @@ -2352,20 +2268,12 @@ operations on the output-stream associ
    Params
    Return values
    -

    drop-tcp-socket: func

    -

    Dispose of the specified tcp-socket, after which it may no longer be used.

    -

    Similar to the POSIX close function.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/tcp-create-socket


    @@ -2394,7 +2302,7 @@ is called, the socket is effectively an in-memory configuration object, unable t

    Typical errors

    • not-supported: The host does not support TCP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References

    @@ -2406,11 +2314,11 @@ is called, the socket is effectively an in-memory configuration object, unable t
    Params
    Return values

    Import interface wasi:sockets/udp


    @@ -2430,18 +2338,18 @@ is called, the socket is effectively an in-memory configuration object, unable t #### `type ip-address-family` [`ip-address-family`](#ip_address_family)

    -#### `type udp-socket` -`u32` -

    A UDP socket handle. -

    record datagram

    +#### `record datagram`
    Record Fields
    +

    resource udp-socket

    +
    Resource Members
    +

    TODO


    Functions

    -

    start-bind: func

    +

    [method]udp-socket.start-bind: func

    Bind the socket to a specific network on the provided IP address and port.

    If the IP address is zero (0.0.0.0 in IPv4, :: in IPv6), it is left to the implementation to decide which network interface(s) to bind to. @@ -2450,7 +2358,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • +
    • address-family-mismatch: The local-address has the wrong address family. (EINVAL)
    • already-bound: The socket is already bound. (EINVAL)
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    @@ -2458,7 +2366,7 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    • ephemeral-ports-exhausted: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)
    • address-in-use: Address is already in use. (EADDRINUSE)
    • -
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • +
    • address-not-bindable: local-address is not an address that the network can bind to. (EADDRNOTAVAIL)
    • not-in-progress: A bind operation is not in progress.
    • would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
    @@ -2471,38 +2379,38 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    finish-bind: func

    +

    [method]udp-socket.finish-bind: func

    Params
    Return values
    -

    start-connect: func

    +

    [method]udp-socket.start-connect: func

    Set the destination address.

    -

    The local-address is updated based on the best network path to remote-address.

    +

    The local-address is updated based on the best network path to remote-address.

    When a destination address is set:

      -
    • all receive operations will only return datagrams sent from the provided remote-address.
    • -
    • the send function can only be used to send to this destination.
    • +
    • all receive operations will only return datagrams sent from the provided remote-address.
    • +
    • the send function can only be used to send to this destination.

    Note that this function does not generate any network traffic and the peer is not aware of this "connection".

    Unlike in POSIX, this function is async. This enables interactive WASI hosts to inject permission prompts.

    Typical start errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-attached: The socket is already bound to a different network. The network passed to connect must be identical to the one passed to bind.
    • concurrency-conflict: Another bind or connect operation is already in progress. (EALREADY)
    @@ -2521,24 +2429,24 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    finish-connect: func

    +

    [method]udp-socket.finish-connect: func

    Params
    Return values
    -

    receive: func

    +

    [method]udp-socket.receive: func

    Receive a message.

    Returns:

      @@ -2563,21 +2471,21 @@ If the TCP/UDP port is zero, the socket will be bound to a random free port.

    Params
    Return values
    -

    send: func

    +

    [method]udp-socket.send: func

    Send a message to a specific destination address.

    The remote address option is required. To send a message to the "connected" peer, -call remote-address to get their address.

    +call remote-address to get their address.

    Typical errors

      -
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • -
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • -
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • address-family-mismatch: The remote-address has the wrong address family. (EAFNOSUPPORT)
    • +
    • invalid-remote-address: The IP address in remote-address is set to INADDR_ANY (0.0.0.0 / ::). (EDESTADDRREQ, EADDRNOTAVAIL)
    • +
    • invalid-remote-address: The port in remote-address is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)
    • already-connected: The socket is in "connected" mode and the datagram.remote-address does not match the address passed to connect. (EISCONN)
    • not-bound: The socket is not bound to any local address. Unlike POSIX, this function does not perform an implicit bind.
    • remote-unreachable: The remote address is not reachable. (ECONNREFUSED, ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN)
    • @@ -2596,14 +2504,14 @@ call remote-address to get their addr
    Params
    Return values
    -

    local-address: func

    +

    [method]udp-socket.local-address: func

    Get the current bound address.

    Typical errors

    Params
    Return values
    -

    remote-address: func

    +

    [method]udp-socket.remote-address: func

    Get the address set with connect.

    Typical errors

    Params
    Return values
    -

    address-family: func

    +

    [method]udp-socket.address-family: func

    Whether this is a IPv4 or IPv6 socket.

    Equivalent to the SO_DOMAIN socket option.

    Params
    Return values
    -

    ipv6-only: func

    +

    [method]udp-socket.ipv6-only: func

    Whether IPv4 compatibility (dual-stack) mode is disabled or not.

    Equivalent to the IPV6_V6ONLY socket option.

    Typical errors

    @@ -2668,23 +2576,23 @@ call remote-address to get their addr
    Params
    Return values
    -

    set-ipv6-only: func

    +

    [method]udp-socket.set-ipv6-only: func

    Params
    Return values
    -

    unicast-hop-limit: func

    +

    [method]udp-socket.unicast-hop-limit: func

    Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.

    Typical errors

    Params
    Return values
    -

    set-unicast-hop-limit: func

    +

    [method]udp-socket.set-unicast-hop-limit: func

    Params
    Return values
    -

    receive-buffer-size: func

    +

    [method]udp-socket.receive-buffer-size: func

    The kernel buffer space reserved for sends/receives on this socket.

    Note #1: an implementation may choose to cap or round the buffer size when setting the value. In other words, after setting a value, reading the same setting back may return a different value.

    @@ -2723,59 +2631,52 @@ for internal metadata structures.

    Params
    Return values
    -

    set-receive-buffer-size: func

    +

    [method]udp-socket.set-receive-buffer-size: func

    Params
    Return values
    -

    send-buffer-size: func

    +

    [method]udp-socket.send-buffer-size: func

    Params
    Return values
    -

    set-send-buffer-size: func

    +

    [method]udp-socket.set-send-buffer-size: func

    Params
    Return values
    -

    subscribe: func

    +

    [method]udp-socket.subscribe: func

    Create a pollable which will resolve once the socket is ready for I/O.

    Note: this function is here for WASI Preview2 only. It's planned to be removed when future is natively supported in Preview3.

    Params
    Return values
    -

    drop-udp-socket: func

    -

    Dispose of the specified udp-socket, after which it may no longer be used.

    -

    Note: this function is scheduled to be removed when Resources are natively supported in Wit.

    -
    Params
    -

    Import interface wasi:sockets/udp-create-socket


    @@ -2804,7 +2705,7 @@ the socket is effectively an in-memory configuration object, unable to communica

    Typical errors

    • not-supported: The host does not support UDP sockets. (EOPNOTSUPP)
    • -
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • +
    • address-family-not-supported: The specified address-family is not supported. (EAFNOSUPPORT)
    • new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)

    References:

    @@ -2816,11 +2717,11 @@ the socket is effectively an in-memory configuration object, unable to communica
    Params
    Return values

    Import interface wasi:random/random

    WASI Random is a random data API.

    @@ -2944,7 +2845,7 @@ values each time it is called.

    Return the set of of preopened directories, and their path.

    Return values

    initial-cwd: func

    Return a path that programs should use as their initial current working @@ -2957,7 +2858,7 @@ directory, interpreting . as shorthand for this.


    Functions

    exit: func

    -

    Exit the curerent instance and any linked instances.

    +

    Exit the current instance and any linked instances.

    Params
    • status: result
    • @@ -2973,7 +2874,7 @@ directory, interpreting . as shorthand for this.

      get-stdin: func

      Return values

      Import interface wasi:cli/stdout


      @@ -2986,7 +2887,7 @@ directory, interpreting . as shorthand for this.

      get-stdout: func

      Return values

      Import interface wasi:cli/stderr


      @@ -2999,7 +2900,7 @@ directory, interpreting . as shorthand for this.

      get-stderr: func

      Return values

      Export interface wasi:cli/run


      diff --git a/wit/deps/clocks/timezone.wit b/wit/deps/clocks/timezone.wit index 6628308..adb4037 100644 --- a/wit/deps/clocks/timezone.wit +++ b/wit/deps/clocks/timezone.wit @@ -6,25 +6,19 @@ interface timezone { /// In timezones that recognize daylight saving time, also known as daylight /// time and summer time, the information returned from the functions varies /// over time to reflect these adjustments. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type timezone = u32 - - /// Return information needed to display the given `datetime`. This includes - /// the UTC offset, the time zone name, and a flag indicating whether - /// daylight saving time is active. - /// - /// If the timezone cannot be determined for the given `datetime`, return a - /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight - /// saving time. - display: func(this: timezone, when: datetime) -> timezone-display - - /// The same as `display`, but only return the UTC offset. - utc-offset: func(this: timezone, when: datetime) -> s32 + resource timezone { + /// Return information needed to display the given `datetime`. This includes + /// the UTC offset, the time zone name, and a flag indicating whether + /// daylight saving time is active. + /// + /// If the timezone cannot be determined for the given `datetime`, return a + /// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight + /// saving time. + display: func(when: datetime) -> timezone-display - /// Dispose of the specified input-stream, after which it may no longer - /// be used. - drop-timezone: func(this: timezone) + /// The same as `display`, but only return the UTC offset. + utc-offset: func(when: datetime) -> s32 + } /// Information useful for displaying the timezone of a specific `datetime`. /// diff --git a/wit/deps/filesystem/preopens.wit b/wit/deps/filesystem/preopens.wit new file mode 100644 index 0000000..f45661b --- /dev/null +++ b/wit/deps/filesystem/preopens.wit @@ -0,0 +1,6 @@ +interface preopens { + use types.{descriptor} + + /// Return the set of preopened directories, and their path. + get-directories: func() -> list> +} diff --git a/wit/deps/filesystem/types.wit b/wit/deps/filesystem/types.wit index 627b638..a582dfa 100644 --- a/wit/deps/filesystem/types.wit +++ b/wit/deps/filesystem/types.wit @@ -102,10 +102,6 @@ interface types { /// /// Note: This was called `filestat` in earlier versions of WASI. record descriptor-stat { - /// Device ID of device containing the file. - device: device, - /// File serial number. - inode: inode, /// File type. %type: descriptor-type, /// Number of hard links to the file. @@ -166,14 +162,6 @@ interface types { /// Number of hard links to an inode. type link-count = u64 - /// Identifier for a device containing a file system. Can be used in - /// combination with `inode` to uniquely identify a file or directory in - /// the filesystem. - type device = u64 - - /// Filesystem object serial number that is unique within its file system. - type inode = u64 - /// When setting a timestamp, this gives the value to set it to. variant new-timestamp { /// Leave the timestamp set to its previous value. @@ -187,14 +175,6 @@ interface types { /// A directory entry. record directory-entry { - /// The serial number of the object referred to by this directory entry. - /// May be none if the inode value is not known. - /// - /// When this is none, libc implementations might do an extra `stat-at` - /// call to retrieve the inode number to fill their `d_ino` fields, so - /// implementations which can set this to a non-none value should do so. - inode: option, - /// The type of the file referred to by this directory entry. %type: descriptor-type, @@ -305,493 +285,519 @@ interface types { no-reuse, } + /// A 128-bit hash value, split into parts because wasm doesn't have a + /// 128-bit integer type. + record metadata-hash-value { + /// 64 bits of a 128-bit hash value. + lower: u64, + /// Another 64 bits of a 128-bit hash value. + upper: u64, + } + /// A descriptor is a reference to a filesystem object, which may be a file, /// directory, named pipe, special file, or other object on which filesystem /// calls may be made. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type descriptor = u32 - - /// Return a stream for reading from a file. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - read-via-stream: func( - this: descriptor, - /// The offset within the file at which to start reading. - offset: filesize, - ) -> input-stream - - /// Return a stream for writing to a file. - /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - write-via-stream: func( - this: descriptor, - /// The offset within the file at which to start writing. - offset: filesize, - ) -> output-stream - - /// Return a stream for appending to a file. - /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. - append-via-stream: func( - this: descriptor, - ) -> output-stream - - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - advise: func( - this: descriptor, - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice - ) -> result<_, error-code> - - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func(this: descriptor) -> result<_, error-code> - - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-flags: func(this: descriptor) -> result + resource descriptor { + /// Return a stream for reading from a file, if available. + /// + /// May fail with an error-code describing why the file cannot be read. + /// + /// Multiple read, write, and append streams may be active on the same open + /// file and they do not interfere with each other. + /// + /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. + read-via-stream: func( + /// The offset within the file at which to start reading. + offset: filesize, + ) -> result - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-type: func(this: descriptor) -> result + /// Return a stream for writing to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be written. + /// + /// Note: This allows using `write-stream`, which is similar to `write` in + /// POSIX. + write-via-stream: func( + /// The offset within the file at which to start writing. + offset: filesize, + ) -> result + + /// Return a stream for appending to a file, if available. + /// + /// May fail with an error-code describing why the file cannot be appended. + /// + /// Note: This allows using `write-stream`, which is similar to `write` with + /// `O_APPEND` in in POSIX. + append-via-stream: func() -> result - /// Set status flags associated with a descriptor. - /// - /// This function may only change the `non-blocking` flag. - /// - /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. - /// - /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. - set-flags: func(this: descriptor, %flags: descriptor-flags) -> result<_, error-code> + /// Provide file advisory information on a descriptor. + /// + /// This is similar to `posix_fadvise` in POSIX. + advise: func( + /// The offset within the file to which the advisory applies. + offset: filesize, + /// The length of the region to which the advisory applies. + length: filesize, + /// The advice. + advice: advice + ) -> result<_, error-code> + + /// Synchronize the data of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fdatasync` in POSIX. + sync-data: func() -> result<_, error-code> - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(this: descriptor, size: filesize) -> result<_, error-code> + /// Get flags associated with a descriptor. + /// + /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. + /// + /// Note: This returns the value that was the `fs_flags` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-flags: func() -> result - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - set-times: func( - this: descriptor, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - read: func( - this: descriptor, - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, - ) -> result, bool>, error-code> - - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - write: func( - this: descriptor, - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, - ) -> result - - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - read-directory: func( - this: descriptor - ) -> result - - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - sync: func(this: descriptor) -> result<_, error-code> + /// Get the dynamic type of a descriptor. + /// + /// Note: This returns the same value as the `type` field of the `fd-stat` + /// returned by `stat`, `stat-at` and similar. + /// + /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided + /// by `fstat` in POSIX. + /// + /// Note: This returns the value that was the `fs_filetype` value returned + /// from `fdstat_get` in earlier versions of WASI. + get-type: func() -> result - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - create-directory-at: func( - this: descriptor, - /// The relative path at which to create the directory. - path: string, - ) -> result<_, error-code> - - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func(this: descriptor) -> result + /// Set status flags associated with a descriptor. + /// + /// This function may only change the `non-blocking` flag. + /// + /// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX. + /// + /// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI. + set-flags: func(%flags: descriptor-flags) -> result<_, error-code> - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - stat-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result - - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - set-times-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code> - - /// Create a hard link. - /// - /// Note: This is similar to `linkat` in POSIX. - link-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path at which to create the hard link. - new-path: string, - ) -> result<_, error-code> - - /// Open a file or directory. - /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - open-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - /// Permissions to use when creating a new file. - modes: modes - ) -> result - - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - readlink-at: func( - this: descriptor, - /// The relative path of the symbolic link from which to read. - path: string, - ) -> result - - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - remove-directory-at: func( - this: descriptor, - /// The relative path to a directory to remove. - path: string, - ) -> result<_, error-code> - - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - rename-at: func( - this: descriptor, - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: descriptor, - /// The relative destination path to which to rename the file or directory. - new-path: string, - ) -> result<_, error-code> - - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - symlink-at: func( - this: descriptor, - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, - ) -> result<_, error-code> - - /// Check accessibility of a filesystem path. - /// - /// Check whether the given filesystem path names an object which is - /// readable, writable, or executable, or whether it exists. - /// - /// This does not a guarantee that subsequent accesses will succeed, as - /// filesystem permissions may be modified asynchronously by external - /// entities. - /// - /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. - access-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to check. - path: string, - /// The type of check to perform. - %type: access-type - ) -> result<_, error-code> - - /// Unlink a filesystem object that is not a directory. - /// - /// Return `error-code::is-directory` if the path refers to a directory. - /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - unlink-file-at: func( - this: descriptor, - /// The relative path to a file to unlink. - path: string, - ) -> result<_, error-code> - - /// Change the permissions of a filesystem object that is not a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-file-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the filesystem object. - modes: modes, - ) -> result<_, error-code> - - /// Change the permissions of a directory. - /// - /// Note that the ultimate meanings of these permissions is - /// filesystem-specific. - /// - /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" - /// flag. `read` on a directory implies readability and searchability, and - /// `execute` is not valid for directories. - /// - /// Note: This is similar to `fchmodat` in POSIX. - change-directory-permissions-at: func( - this: descriptor, - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path to operate on. - path: string, - /// The new permissions for the directory. - modes: modes, - ) -> result<_, error-code> - - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. - lock-shared: func(this: descriptor) -> result<_, error-code> + /// Adjust the size of an open file. If this increases the file's size, the + /// extra bytes are filled with zeros. + /// + /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. + set-size: func(size: filesize) -> result<_, error-code> - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function blocks until the lock can be acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. - lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Adjust the timestamps of an open file or directory. + /// + /// Note: This is similar to `futimens` in POSIX. + /// + /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. + set-times: func( + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Read from a descriptor, without using and updating the descriptor's offset. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a bool which, when true, indicates that the end of the + /// file was reached. The returned list will contain up to `length` bytes; it + /// may return fewer than requested, if the end of the file is reached or + /// if the I/O operation is interrupted. + /// + /// In the future, this may change to return a `stream`. + /// + /// Note: This is similar to `pread` in POSIX. + read: func( + /// The maximum number of bytes to read. + length: filesize, + /// The offset within the file at which to read. + offset: filesize, + ) -> result, bool>, error-code> + + /// Write to a descriptor, without using and updating the descriptor's offset. + /// + /// It is valid to write past the end of a file; the file is extended to the + /// extent of the write, with bytes between the previous end and the start of + /// the write set to zero. + /// + /// In the future, this may change to take a `stream`. + /// + /// Note: This is similar to `pwrite` in POSIX. + write: func( + /// Data to write + buffer: list, + /// The offset within the file at which to write. + offset: filesize, + ) -> result + + /// Read directory entries from a directory. + /// + /// On filesystems where directories contain entries referring to themselves + /// and their parents, often named `.` and `..` respectively, these entries + /// are omitted. + /// + /// This always returns a new stream which starts at the beginning of the + /// directory. Multiple streams may be active on the same directory, and they + /// do not interfere with each other. + read-directory: func() -> result - /// Request a shared advisory lock for an open file. - /// - /// This requests a *shared* lock; more than one shared lock can be held for - /// a file at the same time. - /// - /// If the open file has an exclusive lock, this function downgrades the lock - /// to a shared lock. If it has a shared lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified how shared locks interact with locks acquired by - /// non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. - try-lock-shared: func(this: descriptor) -> result<_, error-code> + /// Synchronize the data and metadata of a file to disk. + /// + /// This function succeeds with no effect if the file descriptor is not + /// opened for writing. + /// + /// Note: This is similar to `fsync` in POSIX. + sync: func() -> result<_, error-code> - /// Request an exclusive advisory lock for an open file. - /// - /// This requests an *exclusive* lock; no other locks may be held for the - /// file while an exclusive lock is held. - /// - /// If the open file has a shared lock and there are no exclusive locks held - /// for the file, this function upgrades the lock to an exclusive lock. If the - /// open file already has an exclusive lock, this function has no effect. - /// - /// This requests an *advisory* lock, meaning that the file could be accessed - /// by other programs that don't hold the lock. - /// - /// It is unspecified whether this function succeeds if the file descriptor - /// is not opened for writing. It is unspecified how exclusive locks interact - /// with locks acquired by non-WASI programs. - /// - /// This function returns `error-code::would-block` if the lock cannot be - /// acquired. - /// - /// Not all filesystems support locking; on filesystems which don't support - /// locking, this function returns `error-code::unsupported`. - /// - /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. - try-lock-exclusive: func(this: descriptor) -> result<_, error-code> + /// Create a directory. + /// + /// Note: This is similar to `mkdirat` in POSIX. + create-directory-at: func( + /// The relative path at which to create the directory. + path: string, + ) -> result<_, error-code> - /// Release a shared or exclusive lock on an open file. - /// - /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. - unlock: func(this: descriptor) -> result<_, error-code> + /// Return the attributes of an open file or directory. + /// + /// Note: This is similar to `fstat` in POSIX, except that it does not + /// return device and inode information. For testing whether two + /// descriptors refer to the same underlying filesystem object, use + /// `is-same-object`. To obtain additional data that can be used do + /// determine whether a file has been modified, use `metadata-hash`. + /// + /// Note: This was called `fd_filestat_get` in earlier versions of WASI. + stat: func() -> result - /// Dispose of the specified `descriptor`, after which it may no longer - /// be used. - drop-descriptor: func(this: descriptor) + /// Return the attributes of a file or directory. + /// + /// Note: This is similar to `fstatat` in POSIX, except that it does + /// not return device and inode information. See the `stat` description + /// for a discussion of alternatives. + /// + /// Note: This was called `path_filestat_get` in earlier versions of WASI. + stat-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + + /// Adjust the timestamps of a file or directory. + /// + /// Note: This is similar to `utimensat` in POSIX. + /// + /// Note: This was called `path_filestat_set_times` in earlier versions of + /// WASI. + set-times-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to operate on. + path: string, + /// The desired values of the data access timestamp. + data-access-timestamp: new-timestamp, + /// The desired values of the data modification timestamp. + data-modification-timestamp: new-timestamp, + ) -> result<_, error-code> + + /// Create a hard link. + /// + /// Note: This is similar to `linkat` in POSIX. + link-at: func( + /// Flags determining the method of how the path is resolved. + old-path-flags: path-flags, + /// The relative source path from which to link. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path at which to create the hard link. + new-path: string, + ) -> result<_, error-code> + + /// Open a file or directory. + /// + /// The returned descriptor is not guaranteed to be the lowest-numbered + /// descriptor not currently open/ it is randomized to prevent applications + /// from depending on making assumptions about indexes, since this is + /// error-prone in multi-threaded contexts. The returned descriptor is + /// guaranteed to be less than 2**31. + /// + /// If `flags` contains `descriptor-flags::mutate-directory`, and the base + /// descriptor doesn't have `descriptor-flags::mutate-directory` set, + /// `open-at` fails with `error-code::read-only`. + /// + /// If `flags` contains `write` or `mutate-directory`, or `open-flags` + /// contains `truncate` or `create`, and the base descriptor doesn't have + /// `descriptor-flags::mutate-directory` set, `open-at` fails with + /// `error-code::read-only`. + /// + /// Note: This is similar to `openat` in POSIX. + open-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the object to open. + path: string, + /// The method by which to open the file. + open-flags: open-flags, + /// Flags to use for the resulting descriptor. + %flags: descriptor-flags, + /// Permissions to use when creating a new file. + modes: modes + ) -> result + + /// Read the contents of a symbolic link. + /// + /// If the contents contain an absolute or rooted path in the underlying + /// filesystem, this function fails with `error-code::not-permitted`. + /// + /// Note: This is similar to `readlinkat` in POSIX. + readlink-at: func( + /// The relative path of the symbolic link from which to read. + path: string, + ) -> result + + /// Remove a directory. + /// + /// Return `error-code::not-empty` if the directory is not empty. + /// + /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. + remove-directory-at: func( + /// The relative path to a directory to remove. + path: string, + ) -> result<_, error-code> + + /// Rename a filesystem object. + /// + /// Note: This is similar to `renameat` in POSIX. + rename-at: func( + /// The relative source path of the file or directory to rename. + old-path: string, + /// The base directory for `new-path`. + new-descriptor: descriptor, + /// The relative destination path to which to rename the file or directory. + new-path: string, + ) -> result<_, error-code> + + /// Create a symbolic link (also known as a "symlink"). + /// + /// If `old-path` starts with `/`, the function fails with + /// `error-code::not-permitted`. + /// + /// Note: This is similar to `symlinkat` in POSIX. + symlink-at: func( + /// The contents of the symbolic link. + old-path: string, + /// The relative destination path at which to create the symbolic link. + new-path: string, + ) -> result<_, error-code> + + /// Check accessibility of a filesystem path. + /// + /// Check whether the given filesystem path names an object which is + /// readable, writable, or executable, or whether it exists. + /// + /// This does not a guarantee that subsequent accesses will succeed, as + /// filesystem permissions may be modified asynchronously by external + /// entities. + /// + /// Note: This is similar to `faccessat` with the `AT_EACCESS` flag in POSIX. + access-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to check. + path: string, + /// The type of check to perform. + %type: access-type + ) -> result<_, error-code> + + /// Unlink a filesystem object that is not a directory. + /// + /// Return `error-code::is-directory` if the path refers to a directory. + /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. + unlink-file-at: func( + /// The relative path to a file to unlink. + path: string, + ) -> result<_, error-code> + + /// Change the permissions of a filesystem object that is not a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-file-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the filesystem object. + modes: modes, + ) -> result<_, error-code> + + /// Change the permissions of a directory. + /// + /// Note that the ultimate meanings of these permissions is + /// filesystem-specific. + /// + /// Unlike in POSIX, the `executable` flag is not reinterpreted as a "search" + /// flag. `read` on a directory implies readability and searchability, and + /// `execute` is not valid for directories. + /// + /// Note: This is similar to `fchmodat` in POSIX. + change-directory-permissions-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path to operate on. + path: string, + /// The new permissions for the directory. + modes: modes, + ) -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH)` in Unix. + lock-shared: func() -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function blocks until the lock can be acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX)` in Unix. + lock-exclusive: func() -> result<_, error-code> + + /// Request a shared advisory lock for an open file. + /// + /// This requests a *shared* lock; more than one shared lock can be held for + /// a file at the same time. + /// + /// If the open file has an exclusive lock, this function downgrades the lock + /// to a shared lock. If it has a shared lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified how shared locks interact with locks acquired by + /// non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_SH | LOCK_NB)` in Unix. + try-lock-shared: func() -> result<_, error-code> + + /// Request an exclusive advisory lock for an open file. + /// + /// This requests an *exclusive* lock; no other locks may be held for the + /// file while an exclusive lock is held. + /// + /// If the open file has a shared lock and there are no exclusive locks held + /// for the file, this function upgrades the lock to an exclusive lock. If the + /// open file already has an exclusive lock, this function has no effect. + /// + /// This requests an *advisory* lock, meaning that the file could be accessed + /// by other programs that don't hold the lock. + /// + /// It is unspecified whether this function succeeds if the file descriptor + /// is not opened for writing. It is unspecified how exclusive locks interact + /// with locks acquired by non-WASI programs. + /// + /// This function returns `error-code::would-block` if the lock cannot be + /// acquired. + /// + /// Not all filesystems support locking; on filesystems which don't support + /// locking, this function returns `error-code::unsupported`. + /// + /// Note: This is similar to `flock(fd, LOCK_EX | LOCK_NB)` in Unix. + try-lock-exclusive: func() -> result<_, error-code> + + /// Release a shared or exclusive lock on an open file. + /// + /// Note: This is similar to `flock(fd, LOCK_UN)` in Unix. + unlock: func() -> result<_, error-code> + + /// Test whether two descriptors refer to the same filesystem object. + /// + /// In POSIX, this corresponds to testing whether the two descriptors have the + /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. + /// wasi-filesystem does not expose device and inode numbers, so this function + /// may be used instead. + is-same-object: func(other: descriptor) -> bool + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a descriptor. + /// + /// This returns a hash of the last-modification timestamp and file size, and + /// may also include the inode number, device number, birth timestamp, and + /// other metadata fields that may change when the file is modified or + /// replaced. It may also include a secret value chosen by the + /// implementation and not otherwise exposed. + /// + /// Implementations are encourated to provide the following properties: + /// + /// - If the file is not modified or replaced, the computed hash value should + /// usually not change. + /// - If the object is modified or replaced, the computed hash value should + /// usually change. + /// - The inputs to the hash should not be easily computable from the + /// computed hash. + /// + /// However, none of these is required. + metadata-hash: func() -> result + + /// Return a hash of the metadata associated with a filesystem object referred + /// to by a directory descriptor and a relative path. + /// + /// This performs the same hash computation as `metadata-hash`. + metadata-hash-at: func( + /// Flags determining the method of how the path is resolved. + path-flags: path-flags, + /// The relative path of the file or directory to inspect. + path: string, + ) -> result + } /// A stream of directory entries. /// /// This [represents a stream of `dir-entry`](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Streams). - type directory-entry-stream = u32 - - /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func( - this: directory-entry-stream - ) -> result, error-code> - - /// Dispose of the specified `directory-entry-stream`, after which it may no longer - /// be used. - drop-directory-entry-stream: func(this: directory-entry-stream) + resource directory-entry-stream { + /// Read a single directory entry from a `directory-entry-stream`. + read-directory-entry: func() -> result, error-code> + } } diff --git a/wit/deps/filesystem/world.wit b/wit/deps/filesystem/world.wit index f2ef782..b51f484 100644 --- a/wit/deps/filesystem/world.wit +++ b/wit/deps/filesystem/world.wit @@ -2,4 +2,5 @@ package wasi:filesystem world example-world { import types + import preopens } diff --git a/wit/deps/io/streams.wit b/wit/deps/io/streams.wit index 430c1d4..a7b17c6 100644 --- a/wit/deps/io/streams.wit +++ b/wit/deps/io/streams.wit @@ -10,8 +10,20 @@ interface streams { /// doesn't provide any additional information. record stream-error {} - /// An input bytestream. In the future, this will be replaced by handle - /// types. + /// Streams provide a sequence of data and then end; once they end, they + /// no longer provide any further data. + /// + /// For example, a stream reading from a file ends when the stream reaches + /// the end of the file. For another example, a stream reading from a + /// socket ends when the socket is closed. + enum stream-status { + /// The stream is open and may produce further data. + open, + /// The stream has ended and will not produce any further data. + ended, + } + + /// An input bytestream. /// /// This conceptually represents a `stream`. It's temporary /// scaffolding until component-model's async features are ready. @@ -22,86 +34,72 @@ interface streams { /// available, which could even be zero. To wait for data to be available, /// use the `subscribe-to-input-stream` function to obtain a `pollable` which /// can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type input-stream = u32 - - /// Read bytes from a stream. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// stream was reached. The returned list will contain up to `len` bytes; it - /// may return fewer than requested, but not more. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// If `len` is 0, it represents a request to read 0 bytes, which should - /// always succeed, assuming the stream hasn't reached its end yet, and - /// return an empty list. - /// - /// The len here is a `u64`, but some callees may not be able to allocate - /// a buffer as large as that would imply. - /// FIXME: describe what happens if allocation fails. - read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, bool>, stream-error> - - /// Read bytes from a stream, with blocking. - /// - /// This is similar to `read`, except that it blocks until at least one - /// byte can be read. - blocking-read: func( - this: input-stream, - /// The maximum number of bytes to read - len: u64 - ) -> result, bool>, stream-error> - - /// Skip bytes from a stream. - /// - /// This is similar to the `read` function, but avoids copying the - /// bytes into the instance. - /// - /// Once a stream has reached the end, subsequent calls to read or - /// `skip` will always report end-of-stream rather than producing more - /// data. - /// - /// This function returns the number of bytes skipped, along with a bool - /// indicating whether the end of the stream was reached. The returned - /// value will be at most `len`; it may be less. - skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Skip bytes from a stream, with blocking. - /// - /// This is similar to `skip`, except that it blocks until at least one - /// byte can be consumed. - blocking-skip: func( - this: input-stream, - /// The maximum number of bytes to skip. - len: u64, - ) -> result, stream-error> - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - subscribe-to-input-stream: func(this: input-stream) -> pollable - - /// Dispose of the specified `input-stream`, after which it may no longer - /// be used. - drop-input-stream: func(this: input-stream) - - /// An output bytestream. In the future, this will be replaced by handle - /// types. + resource input-stream { + /// Read bytes from a stream. + /// + /// This function returns a list of bytes containing the data that was + /// read, along with a `stream-status` which indicates whether the end of + /// the stream was reached. The returned list will contain up to `len` + /// bytes; it may return fewer than requested, but not more. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// If `len` is 0, it represents a request to read 0 bytes, which should + /// always succeed, assuming the stream hasn't reached its end yet, and + /// return an empty list. + /// + /// The len here is a `u64`, but some callees may not be able to allocate + /// a buffer as large as that would imply. + /// FIXME: describe what happens if allocation fails. + read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>, stream-error> + + /// Read bytes from a stream, with blocking. + /// + /// This is similar to `read`, except that it blocks until at least one + /// byte can be read. + blocking-read: func( + /// The maximum number of bytes to read + len: u64 + ) -> result, stream-status>, stream-error> + + /// Skip bytes from a stream. + /// + /// This is similar to the `read` function, but avoids copying the + /// bytes into the instance. + /// + /// Once a stream has reached the end, subsequent calls to read or + /// `skip` will always report end-of-stream rather than producing more + /// data. + /// + /// This function returns the number of bytes skipped, along with a + /// `stream-status` indicating whether the end of the stream was + /// reached. The returned value will be at most `len`; it may be less. + skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// Skip bytes from a stream, with blocking. + /// + /// This is similar to `skip`, except that it blocks until at least one + /// byte can be consumed. + blocking-skip: func( + /// The maximum number of bytes to skip. + len: u64, + ) -> result, stream-error> + + /// Create a `pollable` which will resolve once either the specified stream + /// has bytes available to read or the other end of the stream has been + /// closed. + subscribe-to-input-stream: func() -> pollable + } + + /// An output bytestream. /// /// This conceptually represents a `stream`. It's temporary /// scaffolding until component-model's async features are ready. @@ -112,102 +110,86 @@ interface streams { /// promptly, which could even be zero. To wait for the stream to be ready to /// accept data, the `subscribe-to-output-stream` function to obtain a /// `pollable` which can be polled for using `wasi_poll`. - /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type output-stream = u32 - - /// Write bytes to a stream. - /// - /// This function returns a `u64` indicating the number of bytes from - /// `buf` that were written; it may be less than the full list. - write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write bytes to a stream, with blocking. - /// - /// This is similar to `write`, except that it blocks until at least one - /// byte can be written. - blocking-write: func( - this: output-stream, - /// Data to write - buf: list - ) -> result - - /// Write multiple zero bytes to a stream. - /// - /// This function returns a `u64` indicating the number of zero bytes - /// that were written; it may be less than `len`. - write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Write multiple zero bytes to a stream, with blocking. - /// - /// This is similar to `write-zeroes`, except that it blocks until at least - /// one byte can be written. - blocking-write-zeroes: func( - this: output-stream, - /// The number of zero bytes to write - len: u64 - ) -> result - - /// Read from one stream and write to another. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - /// - /// Unlike other I/O functions, this function blocks until all the data - /// read from the input stream has been written to the output stream. - splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until at least - /// one byte can be read. - blocking-splice: func( - this: output-stream, - /// The stream to read from - src: input-stream, - /// The number of bytes to splice - len: u64, - ) -> result, stream-error> - - /// Forward the entire contents of an input stream to an output stream. - /// - /// This function repeatedly reads from the input stream and writes - /// the data to the output stream, until the end of the input stream - /// is reached, or an error is encountered. - /// - /// Unlike other I/O functions, this function blocks until the end - /// of the input stream is seen and all the data has been written to - /// the output stream. - /// - /// This function returns the number of bytes transferred. - forward: func( - this: output-stream, - /// The stream to read from - src: input-stream - ) -> result - - /// Create a `pollable` which will resolve once either the specified stream - /// is ready to accept bytes or the other end of the stream has been closed. - subscribe-to-output-stream: func(this: output-stream) -> pollable - - /// Dispose of the specified `output-stream`, after which it may no longer - /// be used. - drop-output-stream: func(this: output-stream) + resource output-stream { + /// Write bytes to a stream. + /// + /// This function returns a `u64` indicating the number of bytes from + /// `buf` that were written; it may be less than the full list. + write: func( + /// Data to write + buf: list + ) -> result + + /// Write bytes to a stream, with blocking. + /// + /// This is similar to `write`, except that it blocks until at least one + /// byte can be written. + blocking-write: func( + /// Data to write + buf: list + ) -> result + + /// Write multiple zero bytes to a stream. + /// + /// This function returns a `u64` indicating the number of zero bytes + /// that were written; it may be less than `len`. + write-zeroes: func( + /// The number of zero bytes to write + len: u64 + ) -> result + + /// Write multiple zero bytes to a stream, with blocking. + /// + /// This is similar to `write-zeroes`, except that it blocks until at least + /// one byte can be written. + blocking-write-zeroes: func( + /// The number of zero bytes to write + len: u64 + ) -> result + + /// Read from one stream and write to another. + /// + /// This function returns the number of bytes transferred; it may be less + /// than `len`. + /// + /// Unlike other I/O functions, this function blocks until all the data + /// read from the input stream has been written to the output stream. + splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Read from one stream and write to another, with blocking. + /// + /// This is similar to `splice`, except that it blocks until at least + /// one byte can be read. + blocking-splice: func( + /// The stream to read from + src: input-stream, + /// The number of bytes to splice + len: u64, + ) -> result, stream-error> + + /// Forward the entire contents of an input stream to an output stream. + /// + /// This function repeatedly reads from the input stream and writes + /// the data to the output stream, until the end of the input stream + /// is reached, or an error is encountered. + /// + /// Unlike other I/O functions, this function blocks until the end + /// of the input stream is seen and all the data has been written to + /// the output stream. + /// + /// This function returns the number of bytes transferred. + forward: func( + /// The stream to read from + src: input-stream + ) -> result + + /// Create a `pollable` which will resolve once either the specified stream + /// is ready to accept bytes or the other end of the stream has been closed. + subscribe-to-output-stream: func() -> pollable + } } diff --git a/wit/deps/poll/poll.wit b/wit/deps/poll/poll.wit index 55eee00..8f6fa20 100644 --- a/wit/deps/poll/poll.wit +++ b/wit/deps/poll/poll.wit @@ -2,26 +2,25 @@ /// at once. interface poll { /// A "pollable" handle. + resource pollable + + /// Poll for completion on a set of pollables. /// - /// This is conceptually represents a `stream<_, _>`, or in other words, - /// a stream that one can wait on, repeatedly, but which does not itself - /// produce any data. It's temporary scaffolding until component-model's - /// async features are ready. + /// This function takes a list of pollables, which identify I/O sources of + /// interest, and waits until one or more of the events is ready for I/O. /// - /// And at present, it is a `u32` instead of being an actual handle, until - /// the wit-bindgen implementation of handles and resources is ready. + /// The result `list` is the same length as the argument + /// `list`, and indicates the readiness of each corresponding + /// element in that list, with true indicating ready. A single call can + /// return multiple true elements. /// - /// `pollable` lifetimes are not automatically managed. Users must ensure - /// that they do not outlive the resource they reference. + /// A timeout can be implemented by adding a pollable from the + /// wasi-clocks API to the list. /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type pollable = u32 - - /// Dispose of the specified `pollable`, after which it may no longer - /// be used. - drop-pollable: func(this: pollable) - - /// Poll for completion on a set of pollables. + /// This function does not return a `result`; polling in itself does not + /// do any I/O so it doesn't fail. If any of the I/O sources identified by + /// the pollables has an error, it is indicated by marking the source as + /// ready in the `list`. /// /// The "oneoff" in the name refers to the fact that this function must do a /// linear scan through the entire list of subscriptions, which may be @@ -29,11 +28,5 @@ interface poll { /// many times. In the future, this is expected to be obsoleted by the /// component model async proposal, which will include a scalable waiting /// facility. - /// - /// Note that the return type would ideally be `list`, but that would - /// be more difficult to polyfill given the current state of `wit-bindgen`. - /// See - /// for details. For now, we use zero to mean "not ready" and non-zero to - /// mean "ready". - poll-oneoff: func(in: list) -> list + poll-oneoff: func(in: list) -> list } diff --git a/wit/deps/sockets/ip-name-lookup.wit b/wit/deps/sockets/ip-name-lookup.wit index f15d19d..c396c88 100644 --- a/wit/deps/sockets/ip-name-lookup.wit +++ b/wit/deps/sockets/ip-name-lookup.wit @@ -38,14 +38,12 @@ interface ip-name-lookup { - type resolve-address-stream = u32 - + resource resolve-address-stream { /// Returns the next address from the resolver. /// /// This function should be called multiple times. On each call, it will /// return the next address in connection order preference. If all /// addresses have been exhausted, this function returns `none`. - /// After which, you should release the stream with `drop-resolve-address-stream`. /// /// This function never returns IPv4-mapped IPv6 addresses. /// @@ -54,16 +52,12 @@ interface ip-name-lookup { /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func(this: resolve-address-stream) -> result, error-code> - - /// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-resolve-address-stream: func(this: resolve-address-stream) + resolve-next-address: func() -> result, error-code> /// Create a `pollable` which will resolve once the stream is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: resolve-address-stream) -> pollable + subscribe: func() -> pollable + } } diff --git a/wit/deps/sockets/network.wit b/wit/deps/sockets/network.wit index 2d09bcb..967ccec 100644 --- a/wit/deps/sockets/network.wit +++ b/wit/deps/sockets/network.wit @@ -3,15 +3,7 @@ interface network { /// An opaque resource that represents access to (a subset of) the network. /// This enables context-based security for networking. /// There is no need for this to map 1:1 to a physical network interface. - /// - /// FYI, In the future this will be replaced by handle types. - type network = u32 - - /// Dispose of the specified `network`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-network: func(this: network) - + resource network /// Error codes. /// @@ -183,4 +175,4 @@ interface network { ipv6(ipv6-socket-address), } -} \ No newline at end of file +} diff --git a/wit/deps/sockets/tcp.wit b/wit/deps/sockets/tcp.wit index 4edb1db..4d95f9e 100644 --- a/wit/deps/sockets/tcp.wit +++ b/wit/deps/sockets/tcp.wit @@ -4,10 +4,6 @@ interface tcp { use wasi:poll/poll.{pollable} use network.{network, error-code, ip-socket-address, ip-address-family} - /// A TCP socket handle. - type tcp-socket = u32 - - enum shutdown-type { /// Similar to `SHUT_RD` in POSIX. receive, @@ -19,6 +15,8 @@ interface tcp { both, } + /// A TCP socket handle. + resource tcp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -48,8 +46,8 @@ interface tcp { /// - /// - /// - - start-bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: tcp-socket) -> result<_, error-code> + start-bind: func(network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func() -> result<_, error-code> /// Connect to a remote endpoint. /// @@ -80,8 +78,8 @@ interface tcp { /// - /// - /// - - start-connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: tcp-socket) -> result, error-code> + start-connect: func(network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func() -> result, error-code> /// Start listening for new connections. /// @@ -107,8 +105,8 @@ interface tcp { /// - /// - /// - - start-listen: func(this: tcp-socket) -> result<_, error-code> - finish-listen: func(this: tcp-socket) -> result<_, error-code> + start-listen: func() -> result<_, error-code> + finish-listen: func() -> result<_, error-code> /// Accept a new client socket. /// @@ -128,7 +126,7 @@ interface tcp { /// - /// - /// - - accept: func(this: tcp-socket) -> result, error-code> + accept: func() -> result, error-code> /// Get the bound local address. /// @@ -140,7 +138,7 @@ interface tcp { /// - /// - /// - - local-address: func(this: tcp-socket) -> result + local-address: func() -> result /// Get the bound remote address. /// @@ -152,12 +150,12 @@ interface tcp { /// - /// - /// - - remote-address: func(this: tcp-socket) -> result + remote-address: func() -> result /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: tcp-socket) -> ip-address-family + address-family: func() -> ip-address-family /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -168,29 +166,29 @@ interface tcp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - ipv6-only: func(this: tcp-socket) -> result - set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error-code> + ipv6-only: func() -> result + set-ipv6-only: func(value: bool) -> result<_, error-code> /// Hints the desired listen queue size. Implementations are free to ignore this. /// /// # Typical errors /// - `already-connected`: (set) The socket is already in the Connection state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + set-listen-backlog-size: func(value: u64) -> result<_, error-code> /// Equivalent to the SO_KEEPALIVE socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - keep-alive: func(this: tcp-socket) -> result - set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error-code> + keep-alive: func() -> result + set-keep-alive: func(value: bool) -> result<_, error-code> /// Equivalent to the TCP_NODELAY socket option. /// /// # Typical errors /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - no-delay: func(this: tcp-socket) -> result - set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error-code> + no-delay: func() -> result + set-no-delay: func(value: bool) -> result<_, error-code> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// @@ -198,8 +196,8 @@ interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: tcp-socket) -> result - set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error-code> + unicast-hop-limit: func() -> result + set-unicast-hop-limit: func(value: u8) -> result<_, error-code> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -216,16 +214,16 @@ interface tcp { /// - `already-connected`: (set) The socket is already in the Connection state. /// - `already-listening`: (set) The socket is already in the Listener state. /// - `concurrency-conflict`: (set) A `bind`, `connect` or `listen` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: tcp-socket) -> result - set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: tcp-socket) -> result - set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error-code> + receive-buffer-size: func() -> result + set-receive-buffer-size: func(value: u64) -> result<_, error-code> + send-buffer-size: func() -> result + set-send-buffer-size: func(value: u64) -> result<_, error-code> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: tcp-socket) -> pollable + subscribe: func() -> pollable /// Initiate a graceful shutdown. /// @@ -246,12 +244,7 @@ interface tcp { /// - /// - /// - - shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error-code> + shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code> - /// Dispose of the specified `tcp-socket`, after which it may no longer be used. - /// - /// Similar to the POSIX `close` function. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-tcp-socket: func(this: tcp-socket) + } } diff --git a/wit/deps/sockets/udp.wit b/wit/deps/sockets/udp.wit index 3a0c1bd..01e3d0c 100644 --- a/wit/deps/sockets/udp.wit +++ b/wit/deps/sockets/udp.wit @@ -4,10 +4,6 @@ interface udp { use network.{network, error-code, ip-socket-address, ip-address-family} - /// A UDP socket handle. - type udp-socket = u32 - - record datagram { data: list, // Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. remote-address: ip-socket-address, @@ -20,7 +16,8 @@ interface udp { /// ecn: u2, // IP_RECVTOS } - + /// A UDP socket handle. + resource udp-socket { /// Bind the socket to a specific network on the provided IP address and port. /// @@ -49,8 +46,8 @@ interface udp { /// - /// - /// - - start-bind: func(this: udp-socket, network: network, local-address: ip-socket-address) -> result<_, error-code> - finish-bind: func(this: udp-socket) -> result<_, error-code> + start-bind: func(network: network, local-address: ip-socket-address) -> result<_, error-code> + finish-bind: func() -> result<_, error-code> /// Set the destination address. /// @@ -81,8 +78,8 @@ interface udp { /// - /// - /// - - start-connect: func(this: udp-socket, network: network, remote-address: ip-socket-address) -> result<_, error-code> - finish-connect: func(this: udp-socket) -> result<_, error-code> + start-connect: func(network: network, remote-address: ip-socket-address) -> result<_, error-code> + finish-connect: func() -> result<_, error-code> /// Receive a message. /// @@ -103,7 +100,7 @@ interface udp { /// - /// - /// - - receive: func(this: udp-socket) -> result + receive: func() -> result /// Send a message to a specific destination address. /// @@ -128,7 +125,7 @@ interface udp { /// - /// - /// - - send: func(this: udp-socket, datagram: datagram) -> result<_, error-code> + send: func(datagram: datagram) -> result<_, error-code> /// Get the current bound address. /// @@ -140,7 +137,7 @@ interface udp { /// - /// - /// - - local-address: func(this: udp-socket) -> result + local-address: func() -> result /// Get the address set with `connect`. /// @@ -152,12 +149,12 @@ interface udp { /// - /// - /// - - remote-address: func(this: udp-socket) -> result + remote-address: func() -> result /// Whether this is a IPv4 or IPv6 socket. /// /// Equivalent to the SO_DOMAIN socket option. - address-family: func(this: udp-socket) -> ip-address-family + address-family: func() -> ip-address-family /// Whether IPv4 compatibility (dual-stack) mode is disabled or not. /// @@ -168,15 +165,15 @@ interface udp { /// - `already-bound`: (set) The socket is already bound. /// - `not-supported`: (set) Host does not support dual-stack sockets. (Implementations are not required to.) /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - ipv6-only: func(this: udp-socket) -> result - set-ipv6-only: func(this: udp-socket, value: bool) -> result<_, error-code> + ipv6-only: func() -> result + set-ipv6-only: func(value: bool) -> result<_, error-code> /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - unicast-hop-limit: func(this: udp-socket) -> result - set-unicast-hop-limit: func(this: udp-socket, value: u8) -> result<_, error-code> + unicast-hop-limit: func() -> result + set-unicast-hop-limit: func(value: u8) -> result<_, error-code> /// The kernel buffer space reserved for sends/receives on this socket. /// @@ -193,19 +190,16 @@ interface udp { /// /// # Typical errors /// - `concurrency-conflict`: (set) Another `bind` or `connect` operation is already in progress. (EALREADY) - receive-buffer-size: func(this: udp-socket) -> result - set-receive-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> - send-buffer-size: func(this: udp-socket) -> result - set-send-buffer-size: func(this: udp-socket, value: u64) -> result<_, error-code> + receive-buffer-size: func() -> result + set-receive-buffer-size: func(value: u64) -> result<_, error-code> + send-buffer-size: func() -> result + set-send-buffer-size: func(value: u64) -> result<_, error-code> /// Create a `pollable` which will resolve once the socket is ready for I/O. /// /// Note: this function is here for WASI Preview2 only. /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func(this: udp-socket) -> pollable + subscribe: func() -> pollable - /// Dispose of the specified `udp-socket`, after which it may no longer be used. - /// - /// Note: this function is scheduled to be removed when Resources are natively supported in Wit. - drop-udp-socket: func(this: udp-socket) + } } diff --git a/wit/terminal.wit b/wit/terminal.wit index f32e744..b62c012 100644 --- a/wit/terminal.wit +++ b/wit/terminal.wit @@ -1,31 +1,19 @@ interface terminal-input { /// The input side of a terminal. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type terminal-input = u32 - - // In the future, this may include functions for disabling echoing, - // disabling input buffering so that keyboard events are sent through - // immediately, querying supported features, and so on. - - /// Dispose of the specified terminal-input after which it may no longer - /// be used. - drop-terminal-input: func(this: terminal-input) + resource terminal-input { + // In the future, this may include functions for disabling echoing, + // disabling input buffering so that keyboard events are sent through + // immediately, querying supported features, and so on. + } } interface terminal-output { /// The output side of a terminal. - /// - /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources). - type terminal-output = u32 - - // In the future, this may include functions for querying the terminal - // size, being notified of terminal size changes, querying supported - // features, and so on. - - /// Dispose of the specified terminal-output, after which it may no longer - /// be used. - drop-terminal-output: func(this: terminal-output) + resource terminal-output { + // In the future, this may include functions for querying the terminal + // size, being notified of terminal size changes, querying supported + // features, and so on. + } } /// An interface providing an optional `terminal-input` for stdin as a From 77e2126752d0febec82f20ad5c9ab3560d571e55 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 20 Jul 2023 08:32:36 -0700 Subject: [PATCH 2/2] Sketch up a simple terminal API. Add a simple terminal API defining functions for querying and configuring terminal attributes, as well as a preliminary description of escape sequences along with a set of recommendations for implementors. --- wit/terminal.wit | 271 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 265 insertions(+), 6 deletions(-) diff --git a/wit/terminal.wit b/wit/terminal.wit index b62c012..230a532 100644 --- a/wit/terminal.wit +++ b/wit/terminal.wit @@ -1,18 +1,277 @@ +/// Support for terminal input. +/// +/// See the comments on the terminal-output interface for more background +/// on terminal support. interface terminal-input { /// The input side of a terminal. + /// + /// Implementations are encouraged to reset terminals to default settings + /// when terminal resources are dropped. + /// + /// The full feature is not yet fully defined, however implementations + /// are encouraged to emit the following control codes and input sequences: + /// + /// Control codes: + /// + /// | Code | Meaning | + /// | -----| ------------------------------------------------------------ | + /// | U+8 | Ctrl-H; despite U+8 being historically called "backspace" in ASCII, this isn't the backspace key | + /// | U+9 | Tab | + /// | U+A | Enter | + /// | U+C | Ctrl-L, in immediate mode, requests applications refresh the screen | + /// | U+1B | Escape | + /// | U+7F | Backspace; this is the backspace key | + /// + /// Escape sequences: + /// + /// | Sequence | Meaning | + /// | ------------ | ---------------------------------------------------- | + /// | `␛[A` | Up | + /// | `␛[B` | Down | + /// | `␛[C` | Right | + /// | `␛[D` | Left | + /// | `␛[F` | End | + /// | `␛[H` | Home | + /// | `␛[2~` | Insert | + /// | `␛[3~` | Delete | + /// | `␛[5~` | Page Up | + /// | `␛[6~` | Page Down | + /// | `␛OP` | F1 | + /// | `␛OQ` | F2 | + /// | `␛OR` | F3 | + /// | `␛OS` | F4 | + /// | `␛[15~` | F5 | + /// | `␛[17~` | F6 | + /// | `␛[18~` | F7 | + /// | `␛[19~` | F8 | + /// | `␛[20~` | F9 | + /// | `␛[21~` | F10 | + /// | `␛[23~` | F11 | + /// | `␛[24~` | F12 | + /// | `␛[200~` | Begin Paste; only emitted when bracketed paste mode is activated | + /// | `␛[201~` | End Paste; only emitted when bracketed paste mode is activated | resource terminal-input { - // In the future, this may include functions for disabling echoing, - // disabling input buffering so that keyboard events are sent through - // immediately, querying supported features, and so on. + /// Enable or disable *immediate* mode. + /// + /// Immediate mode makes input key sequences available to be read on + /// the input stream immediately, rather than buffering them up + /// until the end of the line is seen. + /// + /// This may fail if the implementation doesn't support immediate mode. + set-immediate: func(mode: bool) -> result + + /// Disable or enable *echo* mode. + /// + /// Echo mode retransmits input key sequences back to the output of the + /// terminal, so that users can see what they're typing. Echoing is the + /// default behavior in terminals, but disabling can be useful for + /// entering passwords or for combining with immediate mode to make + /// interactive terminal interfaces. + /// + /// This may fail if the implementation doesn't support echo mode. + set-echo: func(mode: bool) -> result } } +/// Support for terminal output. +/// +/// This includes support for a basic terminal interactions, including +/// functions for getting and setting basic "termios" terminal attributes, and +/// support for control codes and "ANSI" escape sequences. +/// +/// The "ANSI" here refers to ANSI X3.64, which later became ECMA-48 +/// (ISO/IEC 6429). However, ECMA-48 was last updated in 1991, it has many +/// features which are no longer relevant, it has no awareness of Unicode +/// or UTF-8, it leaves many behaviors implementation-dependent, and it lacks +/// many extensions that modern implementations have added and have become +/// popular in modern use cases. So while this "ANSI" is the original source +/// for a lot of the terminology used, it's not a normative reference. +/// +/// For now, out of practicality, this document starts by describing features +/// which are widely supported and widely used in modern implementations and +/// use cases. Over time, this could grow to become more complete. interface terminal-output { + use wasi:poll/poll.{pollable} + /// The output side of a terminal. + /// + /// Terminal feature sets and behavior vary between implementations, and + /// this specification does not yet describe a specific set of escape + /// sequences or semantics, so applications are encouraged to stick to + /// widely-supported features. + /// + /// Implementations are encouraged to reset terminals to default settings + /// when terminal resources are dropped, or before writing log messages or + /// other output to the terminal, to prevent applications from modifying + /// the appearance of or reading unrelated output. + /// + /// Terminal emulators are encouraged to: + /// - avoid interpreting escape sequences which cause writes to files, + /// cause pre-existing terminal contents to be echoed back to the + /// application, or disconnect the terminal, + /// - give a visual indication, such as a terminal window title change, + /// when entering and exiting full-screen mode, + /// - support UTF-8, + /// - recognize '␛\' as a ST (String Terminator) sequence, + /// - emit `␛OP`, `␛OQ`, `␛OR`, and `␛OS` for F1-F4 keypresses, and + /// - avoid interpreting the 8-bit encodings of the C1 control codes. resource terminal-output { - // In the future, this may include functions for querying the terminal - // size, being notified of terminal size changes, querying supported - // features, and so on. + /// Return the current number of rows and columns in the terminal. + /// + /// Not all terminals have a set size, and not all that do know their + /// size, so this function may fail the size cannot be determined. + window-size: func() -> result + + /// Return the current number of columns in the terminal. + /// + /// Not all terminals have a set size, and not all that do know their + /// size, so this function may fail if the size cannot be determined. + window-columns: func() -> result + + /// Return a `pollable` listening for window size changes. + /// + /// This `pollable` can be used with `poll_oneoff` to listen for + /// changes to the window size. On implementations which don't + /// support size changes, they just never happen. + subscribe-to-size-changes: func() -> pollable + + /// What kinds of colors are supported, and preferred? + /// + /// This returns a set of flags indicating which families of + /// escape sequences for displaying color are supported. + /// + /// Some terminals support "OSC 4" as a way to detect color support, + /// however this API is preferred. + color: func() -> color-flags + + /// Does this terminal support line-editing features? + /// + /// These include the control codes and escape sequences for moving + /// the cursor around the current line, clearing all or part of the + /// current line, as well as the "alert" code (U+7) which should + /// produce an acoustic or visual notification. This reflects the + /// functionality commonly used for command-line prompts. + /// + /// The full feature is not yet fully defined, however implementations + /// advertising line-editing support are encouraged to support the + /// following control codes and escape sequences: + /// + /// Control codes: + /// + /// | Code | Meaning | + /// | ---- | -------------------------------------------------------- | + /// | U+7 | Alert | + /// | U+8 | Move cursor back one column | + /// | U+9 | Tab | + /// | U+A | End of line | + /// | U+C | FF Terminal Compatibility | + /// | U+D | Carriage Return | + /// | U+7F | No Effect | + /// + /// Escape sequences: + /// + /// | Sequence | Meaning | + /// | -------- | ---------------------------------------------------- | + /// | `␛[K` | Clear to end of line | + /// | `␛[0K` | Clear to end of line | + /// | `␛[2K` | Clear entire line | + line-editing-supported: func() -> bool + + /// Does this terminal support full-screen features? + /// + /// These include moving the cursor to arbitrary positions on the + /// full screen, and clearing all or part of the full screen. + /// This reflects the functionality commonly used for interactive + /// terminal user interfaces. + /// + /// The full feature is not yet fully defined, however implementations + /// advertising full-screen support are encouraged to support the + /// following escape sequences: + /// + /// Escape sequences: + /// + /// | Sequence | Meaning | + /// | ----------- | ------------------------------------------------- | + /// | `␛[?1049h` | Enter full-screen mode | + /// + /// Escape sequences when full-screen mode has been entered: + /// + /// | Sequence | Meaning | + /// | ----------- | ------------------------------------------------- | + /// | `␛[«n»A` | Move the cursor up `«n»` rows | + /// | `␛[«n»B` | Move the cursor down `«n»` rows | + /// | `␛[«n»C` | Move the cursor right `«n»` column | + /// | `␛[«n»D` | Move the cursor left `«n»` columns | + /// | `␛[«n»G` | Move the cursor to column `«n»` | + /// | `␛[«row»;«column»H` | Move the cursor to row `«row»` and column `«column»` | + /// | `␛[0J` | Clear from the cursor to the end of the screen | + /// | `␛[1J` | Clear the screen from the beginning to the current cursor position | + /// | `␛[2J` | Clear the whole screen | + /// | `␛[«n»d` | Move the cursor to row `«n»` | + /// | `␛[«row»;«column»f` | Move the cursor to row `«row»` and column `«column»` | + /// | `␛[?25h` | Set the cursor as visible | + /// | `␛[?1049h` | Clear the screen and reset full-screen settings to defaults | + /// | `␛[?2004h` | Begin bracketed paste mode | + /// | `␛[?25l` | Set the cursor as invisible | + /// | `␛[?1049l` | Exit full-screen mode and restore the terminal to its prior state | + /// | `␛[?2004l` | End bracketed paste mode | + /// | `␛[!p` | Reset the terminal to default settings, without clearing the screen | + full-screen-supported: func() -> bool + } + + /// Flags indicating support for different sets of color escape + /// sequences, and the user's preference for whether they should + /// be used by default. + /// + /// Other color features, including 88-color and 256-color are not + /// included here, as the associated escape sequences are not as + /// portable, and they're effectively obviated by truecolor support. + flags color-flags { + /// Are the classic "4-bit color" escape sequences supported? + /// + /// This indicates support for up to 16 colors, on foreground and + /// background, using the widely-supported (and ECMA-48) "SGR" + /// color escape sequences of the form `␛[…m`. See + /// [here] for more information. + /// + /// Before using color in your user interface, also consider + /// checking `color-desired` to obtain the user's preference for + /// enabling color by default. + /// + /// [here]: https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit + ansi, + + /// Are the 24-bit "true color" escape sequences supported? + /// + /// This indicates support for up to 16 colors, on foreground and + /// background, using "true color" escape sequences of the form + /// `␛[38;2;«r»;«g»;«b»m` (foreground) and `␛[48;2;«r»;«g»;«b»m` + /// (background). The `«r»`, `«g»`, and `«b»` fields are integers + /// in the range [0,256) indicating red, green, and blue values + /// respectively. See /// [here] for more information. + /// + /// Before using color in your user interface, also consider + /// checking `color-desired` to obtain the user's preference for + /// enabling color by default. + /// + /// [here]: https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit + truecolor, + + /// Does the user with color to be used by default? + /// + /// Some users have a terminal which supports color, but prefer + /// applications not use it by default; this flag indicates + /// this preference. + /// + /// See the [`NO_COLOR` website](http://no-color.org/) for more + /// information. + color-desired-by-default, + } + + /// A pair of rows and columns. + record rows-and-columns { + rows: u16, + columns: u16, } }