Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge recv/send into read/write. #240

Closed
wants to merge 1 commit into from

Conversation

sunfishcode
Copy link
Member

I'm marking this as a draft PR for now, as this is a significant enough change that I don't think we want to do this until at least after modularization has made it into a snapshot.

This is a proposal for the idea in #4, merging recv/send into read/write. POSIX says that recv and send are equivalent to read and write on sockets when no flags are set, so this isn't as radical a change as it may first seem. But one thing it does do is provide more encapsulation around what the remote end of a file descriptor is connected to, which will be useful as we add new kinds of sockets and file-like objects.

Interesting bits:

  • End-of-stream (EOS, aka EOF) is indicated by returning the
    $success_eos errno value.

    • This differs from POSIX, where EOS is indicated by having read
      return 0, which is ambiguous in several cases. Of course, WASI
      libc will continue to provide POSIX semantics to C users.

    • This is a success condition being indicated with a non-zero errno
      value, which does not have precedent in POSIX.

  • $fdstat's $filetype field is removed. The $filetype is still
    available through the $filestat type, though note that it's now
    protected by a rights flag. The goal is to start abstracting away more
    of the differences between files and sockets.

  • The $peek and $waitall flags are now available on $read, and can
    be used on files. This differs from POSIX.

  • POSIX says that recv and send fail if the stream is not a socket,
    but with recv/send merged into read/write, this restriction
    will no longer be automatically enforced. It could be manually enforced
    in WASI libc if needed, but in most cases, it's probably not important.

  • There is a new $fd_line_oriented_terminal right, to support
    isatty. I also anticipate expanding on this right in my upcoming
    terminal I/O proposal.

  • $read's $nread result can be larger than the provided buffer to
    indicate a truncate message on a message-oriented socket (see also
    $recv_data_truncated in the current API, or MSG_TRUNC in POSIX
    recv. This avoids the need for a separate output value, but is
    it too surprising?

Out of scope for this proposal (but maybe in scope in the future!):

  • Streams vs datagrams - Having these merged is tricky, but this isn't
    new here; both read and recv already support both streams and
    datagrams.

  • Streams vs arrays - POSIX unifies the concept of a file as an array
    of bytes with the concept of file as a stream of data, which creates
    some tricky situations, but this also isn't new here.

  • Out-of-band messages and connectionless sockets aren't in WASI, and
    this proposal doesn't change that. They may be added by other proposals
    in the future.

This implements #4.

Interesting bits:

 - End-of-stream (EOS, aka EOF) is indicated by returning the
  `$success_eos` errno value.

     - This differs from POSIX, where EOS is indicated by having `read`
       return 0, which is ambiguous in several cases. Of course, WASI
       libc will continue to provide POSIX semantics to C users.

     - This is a success condition being indicated with a non-zero errno
       value, which does not have precedent in POSIX.

 - `$fdstat`'s `$filetype` field is removed. The `$filetype` is still
   available through the `$filestat` type, though note that it's now
   protected by a rights flag. The goal is to start abstracting away more
   of the differences between files and sockets.

 - The `$peek` and `$waitall` flags are now available on `$read`, and can
   be used on files. This differs from POSIX.

 - POSIX says that `recv` and `send` fail if the stream is not a socket,
   but with `recv`/`send` merged into `read`/`write`, this restriction
   will no longer be automatically enforced. It could be manually enforced
   in WASI libc if needed, but in most cases, it's probably not important.

 - There is a new `$fd_line_oriented_terminal` right, to support
   `isatty`. I also anticipate expanding on this right in my upcoming
   terminal I/O proposal.

 - `$read`'s `$nread` result can be larger than the provided buffer to
   indicate a truncate message on a message-oriented socket (see also
   `$recv_data_truncated` in the current API, or `MSG_TRUNC` in POSIX
   `recv`. This avoids the need for a separate output value, but is
   it too surprising?

Out of scope for this proposal (but maybe in scope in the future!):

 - Streams vs datagrams - Having these merged is tricky, but this isn't
   new here; both `read` and `recv` already support both streams and
   datagrams.

 - Streams vs arrays - POSIX unifies the concept of a file as an array
   of bytes with the concept of file as a stream of data, which creates
   some tricky situations, but this also isn't new here.

 - Out-of-band messages and connectionless sockets aren't in WASI, and
   this proposal doesn't change that.

This implements WebAssembly#4.
;;; The right to invoke `fd_shutdown`.
$fd_shutdown
;;; The output supports line-oriented terminal output.
$fd_line_oriented_terminal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a little strange to call this a right.

@@ -638,25 +640,23 @@
;;; Exit code generated by a process when exiting.
(typename $exitcode u32)

;;; Flags provided to `sock_recv`.
;;; Flags provided to `fd_read`.
(typename $riflags
(flags u16
;;; Returns the message without removing it from the socket's receive queue.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this say something like When reading from a datagram socket?

@MarkMcCaskey
Copy link

Just read over this in depth now. Thanks for working on this! It looks pretty good to me but I have a few questions and comments:

Does the waitall flag on read imply that reads should be guaranteed non-blocking by default now? Does this flag also need to be added to pread?

Speaking of pread what's the status of it in regards to sockets? Peek functionality is a subset of Seek + Read so could be implemented with pread, but then we'd have to make sockets seekable generally, which may be odd. Alternatively, with the peek flag being a way to make read stateless (the same function as pread), perhaps it makes sense to combine pread and read.

@lygstate
Copy link
Contributor

What's the situation of this?
Does it waiting for sockets?

@sunfishcode
Copy link
Member Author

I'm working on developing a version of this idea in wasi-io.

@sunfishcode
Copy link
Member Author

Closing this, as the ideas are now incorporated in WebAssembly/wasi-io#4; see WebAssembly/wasi-io#3 for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants