Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions expected/wasm32-wasip3/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,7 @@ optopt
optreset
pathconf
perror
pipe
poll
posix_close
posix_fadvise
Expand Down
1 change: 1 addition & 0 deletions libc-bottom-half/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ if (WASI STREQUAL "p3")
sources/wasip3_block_on.c
sources/wasip3_file.c
sources/wasip3_file_utils.c
sources/wasip3_pipe.c
sources/wasip3_stdio.c
sources/wasip3_tcp.c
sources/wasip3_udp.c
Expand Down
102 changes: 102 additions & 0 deletions libc-bottom-half/sources/wasip3_pipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include <wasi/version.h>

#ifdef __wasip3__
#include <common/errors.h>
#include <stdlib.h>
#include <wasi/api.h>
#include <wasi/descriptor_table.h>

typedef struct {
wasip3_write_t output;
} pipe3w_t;

typedef struct {
filesystem_tuple2_stream_u8_future_result_void_error_code_t input;
} pipe3r_t;

static int pipe_read_stream(
void *data,
filesystem_tuple2_stream_u8_future_result_void_error_code_t **out,
off_t **offs) {
pipe3r_t *file = (pipe3r_t *)data;
*out = &file->input;
*offs = 0;
return 0;
}

static void pipe_r_free(void *data) {
pipe3r_t *file = (pipe3r_t *)data;
filesystem_stream_u8_drop_readable(file->input.f0);
free(file);
}

static int pipe_write_stream(void *data, wasip3_write_t **out, off_t **offs) {
pipe3w_t *file = (pipe3w_t *)data;
*out = &file->output;
*offs = 0;
return 0;
}

static void pipe_w_free(void *data) {
pipe3w_t *file = (pipe3w_t *)data;
filesystem_stream_u8_drop_writable(file->output.output);
free(file);
}

static descriptor_vtable_t pipe_r_vtable = {
.free = pipe_r_free,
.get_read_stream3 = pipe_read_stream,
};

static descriptor_vtable_t pipe_w_vtable = {
.free = pipe_w_free,
.get_write_stream3 = pipe_write_stream,
};

int pipe(int pipefd[2]) {
pipe3w_t *writehandle = calloc(1, sizeof(pipe3w_t));
if (!writehandle) {
errno = ENOMEM;
return -1;
}
pipe3r_t *readhandle = calloc(1, sizeof(pipe3r_t));
if (!readhandle) {
free(writehandle);
errno = ENOMEM;
return -1;
}
readhandle->input.f0 = filesystem_stream_u8_new(&writehandle->output.output);
descriptor_table_entry_t entry;
entry.vtable = &pipe_r_vtable;
entry.data = readhandle;
int pipefd0 = descriptor_table_insert(entry);
if (pipefd0 < 0) {
pipe_r_free(readhandle);
pipe_w_free(writehandle);
return -1;
}
entry.vtable = &pipe_w_vtable;
entry.data = writehandle;
int pipefd1 = descriptor_table_insert(entry);
if (pipefd1 < 0) {
pipe_r_free(readhandle);
pipe_w_free(writehandle);
descriptor_table_remove(pipefd0);
return -1;
}
// signal non-eof condition
writehandle->output.subtask = WASIP3_SUBTASK_STARTING;
pipefd[0] = pipefd0;
pipefd[1] = pipefd1;
return 0;
}

int pipe2(int pipefd[2], int flags) {
if (flags != 0) {
errno = EOPNOTSUPP;
return -1;
}
return pipe(pipefd);
}

#endif
3 changes: 2 additions & 1 deletion libc-top-half/musl/include/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern "C" {
#define SEEK_HOLE 4
#else
#include <__header_unistd.h>
#include <wasi/version.h> // for pipe availability
#endif

#ifdef __wasilibc_unmodified_upstream /* Use the compiler's definition of NULL */
Expand All @@ -45,7 +46,7 @@ extern "C" {

#include <bits/alltypes.h>

#ifdef __wasilibc_unmodified_upstream /* WASI has no pipe */
#if defined(__wasilibc_unmodified_upstream) || defined(__wasip3__) /* WASI<0.3 has no pipe */
int pipe(int [2]);
int pipe2(int [2], int);
#endif
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ add_wasilibc_test(memchr.c LDFLAGS -Wl,--stack-first -Wl,--initial-memory=327680
add_wasilibc_test(memcmp.c LDFLAGS -Wl,--stack-first -Wl,--initial-memory=327680)
add_wasilibc_test(opendir.c FS FAILP3 ARGV /)
add_wasilibc_test(open_relative_path.c FS FAILP3 ARGV /)
add_wasilibc_test(pipe.c)
add_wasilibc_test(poll.c FS FAILP3)
add_wasilibc_test(preadvwritev.c FS FAILP3)
add_wasilibc_test(preadwrite.c FS FAILP3)
Expand Down
28 changes: 28 additions & 0 deletions test/src/pipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define PATTERNSIZE 16
static const char PATTERN[PATTERNSIZE] = {
'A', 'B', 'C', 'D', '0', '1', '2', '3', 'a', 'b', 'c', 'd', 0, 1, 2, 3};

#define TEST(c, ...) ((c) ? 1 : (t_error(#c " failed: " __VA_ARGS__), 0))

int main(void) {
#ifdef __wasip3__ // pipe only works on wasip3 or up
int pipefd[2];
char buf[PATTERNSIZE];
int res;

TEST(pipe(pipefd) >= 0);

TEST(write(pipefd[1], PATTERN, PATTERNSIZE) == PATTERNSIZE);

TEST(read(pipefd[0], buf, PATTERNSIZE) == PATTERNSIZE);

TEST(close(pipefd[0]) >= 0);
TEST(close(pipefd[1]) >= 0);
#endif
return 0;
}
Loading