Skip to content

Commit 6629886

Browse files
authored
wasip3: Fix zero-length reads/writes on streams (#792)
Previously this trapped internally due to state not getting lined up right and/or returned the wrong result. Now this tries to follow posix and not actually do any I/O for zero-length reads/writes.
1 parent d381a1f commit 6629886

3 files changed

Lines changed: 19 additions & 1 deletion

File tree

libc-bottom-half/sources/file_utils.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ ssize_t __wasilibc_write(wasi_write_t *write, const void *buffer,
363363
assert((state->flags & WASIP3_IO_INPROGRESS) == 0);
364364
assert((state->flags & WASIP3_IO_ZERO_INPROGRESS) == 0);
365365

366+
// Follow posix semantics for zero-length writes which appear to return 0
367+
// without actually doing any I/O.
368+
if (length == 0)
369+
return 0;
370+
366371
// If this stream is complete, then delegate to EOF.
367372
if (state->flags & WASIP3_IO_DONE)
368373
return write->eof(write->eof_data);
@@ -588,6 +593,11 @@ ssize_t __wasilibc_read(wasi_read_t *read, void *buffer, size_t length) {
588593
if (state->buf)
589594
return wasip3_read_complete_internally(state, buffer, length);
590595

596+
// Implement posix-like semantics where a `read` of 0 bytes doesn't do
597+
// anything and just returns 0.
598+
if (length == 0)
599+
return 0;
600+
591601
// If this stream has finished, then delegate to EOF.
592602
if (state->flags & WASIP3_IO_DONE)
593603
return read->eof(read->eof_data);

test/src/sockets-client.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ void test_tcp_client(int server_port) {
4848
TEST(bytes_received == len);
4949

5050
// Message received should be the same as message sent
51-
TEST(strcmp(message, client_buffer) == 0);
51+
TEST(memcmp(message, client_buffer, len) == 0);
52+
53+
TEST(read(socket_fd, NULL, 0) == 0);
54+
TEST(write(socket_fd, NULL, 0) == 0);
5255

5356
// Shut down client
5457
close(socket_fd);

test/src/sockets-nonblocking.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ void test_tcp_client() {
138138
TEST(poll(&poll_fd, 1, -1) != -1);
139139
}
140140

141+
TEST(read(client_socket_fd, NULL, 0) == 0);
142+
TEST(write(client_socket_fd, NULL, 0) == 0);
143+
TEST(read(socket_fd, NULL, 0) == 0);
144+
TEST(write(socket_fd, NULL, 0) == 0);
145+
141146
// Message received should be the same as message sent
142147
TEST(strcmp(message, client_buffer) == 0);
143148

0 commit comments

Comments
 (0)