-
Notifications
You must be signed in to change notification settings - Fork 257
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 sock_send
/sock_recv
with fd_write
/fd_read
#4
Comments
This all sounds like a great idea to me, funneling these through the same syscall seems pretty natural fits well with the existing capabilities and such. I'm curious about a few parts though:
I was initially wondering how this affects Otherwise, is this something that we'd have to add more rights for in the future? In that would new kinds of file descriptors get their own rights? (just wondering if this is a "slippery slope" or pretty contained)
I was curious about this and wondering how we'd manage that. Is it the intention that |
My theory is that this isn't a slippery slope because
Yes, that's right. Another option is to add a bool output parameter to |
Ah ok, if For |
When you use these rights for double duty, how does the caller determine the difference between, expressed in POSIX errno terms, I would expect that using the flags on |
I haven't actually looked at the error handling part of WASI yet. However, I presume the libc implementation would return 15 in this case and expect a second |
For what it's worth, we should encourage implementations to support the full set of operations even on files - no reason you couldn't support peek on seekable data, for example. |
One option is to rewrite the errno value to
POSIX read() and write() work on both files and sockets. POSIX defines recv() and send() with no flags to be equivalent to read() and write(), except that they fail with
Yes. You can always keep calling read after you reach EOF, and it'll return 0 (as long as the file isn't modified), so programs that expect to read until they get a 0 will work as intended. |
It sucks to consume a (likely) second context switch on
I think that is exactly my question. That behavior is very well known. I definitely imagine there are libraries that are using that behavior instead of a more explicit test. However, I don't have a good sense of the actual cost in choosing not to preserve that behavior.
+1 |
I don't see why there would be a second switch - the socket-ness just has to be tracked by the libc (and probably should). |
At @wasmerio we are very interested in moving sockets forward in WASI. Are there any companies already working on this (or interested in working on it in the future), so we can start collaborating? (Mozilla? Fastly?) Following that thought. I'd like to offer Wasmer workforce to start the development on the wasi-libc repo.
|
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.
This issue has been subsumed by the component model, which is adding a |
WASI's sock_send and sock_recv are very similar to fd_write and fd_read, but with an extra flag parameter. This CL makes sock_send/sock_recv delegate to fd_write/fd_read if no flags are passed in. See github.com/WebAssembly/WASI/issues/4 for additional context. Bug: b/276352391 Change-Id: I52af0213bb928fb284adf6c74521cdaf451f10fc Reviewed-on: https://chromium-review.googlesource.com/c/apps/libapps/+/4389201 Reviewed-by: Mike Frysinger <[email protected]> Tested-by: kokoro <[email protected]>
WASI currently has two pairs of functions which are similar to each other:
sock_send
/sock_recv
andfd_write
/fd_read
. This PR describes a plan for merging them, in favor offd_write
/fd_read
.Background
The reason why
send
andrecv
are separate in POSIX is that they add flags arguments. POSIX says that send and recv are equivalent to write and read when no flags are set.WASI's
sock_send
doesn't currently support any flags. WASI'ssock_recv
supports__WASI_SOCK_RECV_PEEK
and__WASI_SOCK_RECV_WAITALL
which correspond toMSG_PEEK
andMSG_WAITALL
in POSIX. Both of these operations conceptually could work on files, however typical operating systems only support them on sockets.On Linux, there is a subtle difference between
recv
andread
: "If a zero-length datagram is pending, read(2) and recv() with a flags argument of zero provide different behavior. In this circumstance, read(2) has no effect (the datagram remains pending), while recv() consumes the pending datagram." It is possible that applications could depend on this subtle difference, but the only reference to it I've been able to find is the git commit which added this line to the man page, which describes a bug where "[...] we would end up in a busy loop when we were using read(2). Changing to recv(2) fixed the issue [...]". Therecv
behavior, is what the code in that bug wanted, and is the more intuitive behavior.The cause of this subtlety is that
read
special-cases a 0 return value to mean the end-of-file/stream has been reached. That creates an ambiguity when reading a zero-length datagram.Proposal
sock_send
andsock_recv
.__wasi_siflags_t
and__wasi_riflags_t
arguments tofd_write
andfd_read
, respectively.fd_read
return__WASI_EMSGSIZE
when receiving a datagram which is larger than the provided buffer. And remove__WASI_SOCK_RECV_DATA_TRUNCATED
, which is whatsock_recv
used in that case. WASI libc will check for this and to continue to implement the POSIX API (MSG_TRUNC
).fd_read
return__WASI_EEOS
, a new errno code, when the end-of-file/stream is reached. This eliminates the ambiguity of the special case for 0. WASI libc will check for this and continue to implement the POSIX API with 0 being a special case.__WASI_RIGHT_FD_READ_PEEK
and__WASI_RIGHT_FD_READ_WAITALL
, which are required to use the__WASI_SOCK_RECV_PEEK
and__WASI_SOCK_RECV_WAITALL
flags, respectively. These rights would not be granted for file-based file descriptors on OS's that don't support these features on files.fs_filetype
field from thefdstat_t
struct. This further hides unnecessary differences between sockets and files.fd_fdstat_get
is an otherwise ambient authority, meaning anyone can do it on any open file descriptor. The file type is still accessible, viafd_filestat_get
, but that requires (__WASI_RIGHT_FD_FILESTAT_GET
).isatty
, so add a__WASI_RIGHT_FD_ISATTY
right, to indicate whether a file descriptor is known to be a terminal. This is a little unusual as it's not a typical right, as it's not associated with an operation. However, this right makes it simple to implementisatty
, which is used by libc to do line buffering for stdout when it's on a tty.And some minor tidying:
sock_shutdown
tofd_shutdown
, and make it a file descriptor operation that happens to depend on the__WASI_RIGHT_SOCK_SHUTDOWN
right, which on typical implementations will only get granted for sockets. This is the last remainingsock_*
function.__WASI_RIGHT_SOCK_SHUTDOWN
to__WASI_RIGHT_FD_SHUTDOWN
.__WASI_SOCK_RECV_PEEK
and__WASI_SOCK_RECV_WAITALL
to sayFD_READ
instead ofSOCK_RECV
.Miscellaneous notes
The change to make
fd_read
return__WASI_EEOS
on end-of-file/stream also fixes an oddity in POSIX in which many applications do an extraread
call after the EOF is encountered, in order to get a 0 return fromread
to confirm they've actually reached the end. That said, implementations on POSIX hosts won't be able to report__WASI_EEOS
until they get a 0 fromread
themselves, so in practice there will still be an extraread
on such systems.The text was updated successfully, but these errors were encountered: