Stream: git-wasmtime

Topic: wasmtime / issue #10713 How to map and r/w to a fifo file?


view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 18:50):

ST-Saint opened issue #10713:

I am trying to use a pipe to achieve IPC in wasm. However, it seems like fifo is not mapped as a fifo, and I failed to open it.

I am not sure if the fifo type is supported or if I did it wrong.

Here is how I run it:

mkfifo /tmp/fifo

ls /tmp/fifo
> |rw-r--r-- - x  2 May 11:42 /tmp/fifo

clang --target=wasm32-wasi --sysroot=/usr/share/wasi-sysroot -o test_fifo.wasm test_fifo.c

wasmtime run --dir=/tmp::/tmp test_fifo.wasm
> /tmp/fifo is not a FIFO

// test_fifo.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
        const char *fifo_path = "/tmp/fifo";
        struct stat st;

        if (stat(fifo_path, &st) == -1) {
                perror("stat");
                exit(EXIT_FAILURE);
        }

        if (S_ISFIFO(st.st_mode)) {
                printf("%s is a FIFO\n", fifo_path);

                int fd = open(fifo_path, O_RDONLY);
                if (fd == -1) {
                        perror("open");
                        exit(EXIT_FAILURE);
                }

                char buffer[128];
                ssize_t bytes_read;
                while ((bytes_read = read(fd, buffer, sizeof(buffer) - 1)) > 0) {
                        buffer[bytes_read] = '\0';
                        printf("Received: %s\n", buffer);
                }

                if (bytes_read == -1) {
                        perror("read");
                }

                close(fd);
        } else {
                printf("%s is not a FIFO\n", fifo_path);
        }

        return 0;
}

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:23):

pchickey commented on issue #10713:

You're using WASI Preview 1, where the system call interface underlying your program won't be able to tell it the host file is a FIFO.

Support for representing a FIFO was added in WASI Preview 2 aka 0.2. However, we still don't have full support in wasi-libc for WASI 0.2, so the libc is falling back on the Preview 1 bindings even when compiled to 0.2 at this time. And furthermore, nobody ever added tests to show that FIFO works with WASI 0.2 filesystems in Wasmtime, so while it might work, it also might be broken. (You're welcome to investigate this - using the wasi crate to call the bindings directly would work, but the libc interfaces will not.)

We are working on support for WASI 0.2 in wasi-libc soon. Once that work is complete and also we add FIFO to the test suite for Wasmtime, the above code example should fully work. Until then, you'll just have to ignore the libc S_ISFIFO and treat the files you know to be FIFO as FIFOs.

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:32):

ST-Saint commented on issue #10713:

Thanks for the quick reply.

I also tried reading the FIFO file blindly (without checking the file stat), but I still got seek errors:

# shell 1
wasmtime run --dir=/tmp::/tmp test_fifo.wasm
> ... # pending

# shell 2
echo "test" > /tmp/fifo

# shell 1

read: Invalid seek

Yet, if I simply compile the test to native code, I do receive the message from the FIFO file.

clang -o test_fifo test_fifo.c
> Received: test

so it seems the FIFO support is not ready yet?

// test_fifo.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
        const char *fifo_path = "/tmp/fifo";
        struct stat st;

        int fd = open(fifo_path, O_RDONLY);
        if (fd == -1) {
                perror("open");
                exit(EXIT_FAILURE);
        }

        char buffer[128];
        ssize_t bytes_read;
        while ((bytes_read = read(fd, buffer, sizeof(buffer) - 1)) > 0) {
                buffer[bytes_read] = '\0';
                printf("Received: %s\n", buffer);
        }

        if (bytes_read == -1) {
                perror("read");
        }

        close(fd);
        return 0;
}

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:34):

ST-Saint edited a comment on issue #10713:

Thanks for the quick reply.

I also tried reading the FIFO file blindly (without checking the file stat), but I still got seek errors:

# shell 1
wasmtime run --dir=/tmp::/tmp test_fifo.wasm
> ... # pending

# shell 2
echo "test" > /tmp/fifo

# shell 1

read: Invalid seek

Yet, if I simply compile the test to native code, I do receive the message from the FIFO file.

clang -o test_fifo test_fifo.c
> Received: test

so it seems that I cannot operate the FIFO files with wasi 0.1?

// test_fifo.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
        const char *fifo_path = "/tmp/fifo";
        struct stat st;

        int fd = open(fifo_path, O_RDONLY);
        if (fd == -1) {
                perror("open");
                exit(EXIT_FAILURE);
        }

        char buffer[128];
        ssize_t bytes_read;
        while ((bytes_read = read(fd, buffer, sizeof(buffer) - 1)) > 0) {
                buffer[bytes_read] = '\0';
                printf("Received: %s\n", buffer);
        }

        if (bytes_read == -1) {
                perror("read");
        }

        close(fd);
        return 0;
}

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:46):

pchickey commented on issue #10713:

Try running wasmtime with WASMTIME_LOG=wasmtime_wasi=trace and see if the messages from there are any help

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:52):

ST-Saint commented on issue #10713:

here it is

2025-05-02T19:50:16.080456Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3)
2025-05-02T19:50:16.080504Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(Dir(PrestatDir { pr_name_len: 4 }))
2025-05-02T19:50:16.080525Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_dir_name"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3) path=*guest 0x114c0 path_len=4
2025-05-02T19:50:16.080534Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_dir_name"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(())
2025-05-02T19:50:16.080541Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(4)
2025-05-02T19:50:16.080547Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Err(Error { inner: Badf })
2025-05-02T19:50:16.080568Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_fdstat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3)
2025-05-02T19:50:16.080582Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_fdstat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(Fdstat { fs_filetype: Directory, fs_flags: Fdflags(0x0), fs_rights_base: Rights(PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE), fs_rights_inheriting: Rights(FD_DATASYNC | FD_READ | FD_SEEK | FD_FDSTAT_SET_FLAGS | FD_SYNC | FD_TELL | FD_WRITE | FD_ADVISE | FD_ALLOCATE | PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_SIZE | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE) })
2025-05-02T19:50:16.080607Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="path_open"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3) dirflags=Lookupflags(SYMLINK_FOLLOW) path=*guest 0x422/4 oflags=Oflags(0x0) fs_rights_base=Rights(FD_READ | FD_SEEK | FD_FDSTAT_SET_FLAGS | FD_SYNC | FD_TELL | FD_ADVISE | PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE) fs_rights_inheriting=Rights(FD_DATASYNC | FD_READ | FD_SEEK | FD_FDSTAT_SET_FLAGS | FD_SYNC | FD_TELL | FD_WRITE | FD_ADVISE | FD_ALLOCATE | PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_SIZE | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE) fdflags=Fdflags(0x0)
2025-05-02T19:50:22.351325Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="path_open"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(Fd(4))
2025-05-02T19:50:22.351364Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_read"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(4) iovs=*guest 0x11378/1
2025-05-02T19:50:22.351380Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_read"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Err(Error { inner: Spipe })
2025-05-02T19:50:22.351402Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11370/2
read2025-05-02T19:50:22.351416Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(4)
2025-05-02T19:50:22.351422Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11360/2
:2025-05-02T19:50:22.351430Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(1)
2025-05-02T19:50:22.351436Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11360/2
 2025-05-02T19:50:22.351443Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(1)
2025-05-02T19:50:22.351450Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11370/2

Invalid seek

2025-05-02T19:50:22.351457Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(12)
2025-05-02T19:50:22.351463Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11360/2

2025-05-02T19:50:22.351471Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(1)
2025-05-02T19:50:22.351486Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_close"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(4)
2025-05-02T19:50:22.351499Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_close"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(())

I might just try with wasi 0.2 then

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:53):

ST-Saint edited a comment on issue #10713:

here it is

2025-05-02T19:50:16.080456Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3)
2025-05-02T19:50:16.080504Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(Dir(PrestatDir { pr_name_len: 4 }))
2025-05-02T19:50:16.080525Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_dir_name"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3) path=*guest 0x114c0 path_len=4
2025-05-02T19:50:16.080534Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_dir_name"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(())
2025-05-02T19:50:16.080541Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(4)
2025-05-02T19:50:16.080547Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_prestat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Err(Error { inner: Badf })
2025-05-02T19:50:16.080568Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_fdstat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3)
2025-05-02T19:50:16.080582Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_fdstat_get"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(Fdstat { fs_filetype: Directory, fs_flags: Fdflags(0x0), fs_rights_base: Rights(PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE), fs_rights_inheriting: Rights(FD_DATASYNC | FD_READ | FD_SEEK | FD_FDSTAT_SET_FLAGS | FD_SYNC | FD_TELL | FD_WRITE | FD_ADVISE | FD_ALLOCATE | PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_SIZE | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE) })
2025-05-02T19:50:16.080607Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="path_open"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(3) dirflags=Lookupflags(SYMLINK_FOLLOW) path=*guest 0x422/4 oflags=Oflags(0x0) fs_rights_base=Rights(FD_READ | FD_SEEK | FD_FDSTAT_SET_FLAGS | FD_SYNC | FD_TELL | FD_ADVISE | PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE) fs_rights_inheriting=Rights(FD_DATASYNC | FD_READ | FD_SEEK | FD_FDSTAT_SET_FLAGS | FD_SYNC | FD_TELL | FD_WRITE | FD_ADVISE | FD_ALLOCATE | PATH_CREATE_DIRECTORY | PATH_CREATE_FILE | PATH_LINK_SOURCE | PATH_LINK_TARGET | PATH_OPEN | FD_READDIR | PATH_READLINK | PATH_RENAME_SOURCE | PATH_RENAME_TARGET | PATH_FILESTAT_GET | PATH_FILESTAT_SET_TIMES | FD_FILESTAT_GET | FD_FILESTAT_SET_SIZE | FD_FILESTAT_SET_TIMES | PATH_SYMLINK | PATH_REMOVE_DIRECTORY | PATH_UNLINK_FILE | POLL_FD_READWRITE) fdflags=Fdflags(0x0)
2025-05-02T19:50:22.351325Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="path_open"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(Fd(4))
2025-05-02T19:50:22.351364Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_read"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(4) iovs=*guest 0x11378/1
2025-05-02T19:50:22.351380Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_read"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Err(Error { inner: Spipe })
2025-05-02T19:50:22.351402Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11370/2

read

2025-05-02T19:50:22.351416Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(4)
2025-05-02T19:50:22.351422Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11360/2

:

2025-05-02T19:50:22.351430Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(1)
2025-05-02T19:50:22.351436Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11360/2
 2025-05-02T19:50:22.351443Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(1)
2025-05-02T19:50:22.351450Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11370/2

Invalid seek

2025-05-02T19:50:22.351457Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(12)
2025-05-02T19:50:22.351463Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(2) iovs=*guest 0x11360/2

2025-05-02T19:50:22.351471Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_write"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(1)
2025-05-02T19:50:22.351486Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_close"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: fd=Fd(4)
2025-05-02T19:50:22.351499Z TRACE wiggle abi{module="wasi_snapshot_preview1" function="fd_close"}: wasmtime_wasi::preview1::wasi_snapshot_preview1: result=Ok(())

I might just try with wasi 0.2 then

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:57):

bjorn3 commented on issue #10713:

Looks like wasip2 only provides an equivalent to pread and expects the guest to keep the file position itself. Pread requires the file to be seekable however, which pipes are not. (confusingly the docs on descriptor#read-via-stream and descriptor#write-via-stream say that they are similar to read/write when they are actually more similar to pread/pwrite as they have an offset argument.

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:57):

pchickey commented on issue #10713:

Ok, it looks like the read isnt blocking and instead is failing with ESPIPE, and then wasi-libc doesn't know how to deal with that because wasi-libc doesn't know about FIFOs (for previously described reasons).

One way you could work around this would be to write your own read function, rather than use wasi-libcs, that gets the blocking behavior (if desired) by using poll_oneoff after an SPIPE to block until readable.

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 19:59):

bjorn3 commented on issue #10713:

Ok, it looks like the read isnt blocking and instead is failing with ESPIPE, and then wasi-libc doesn't know how to deal with that because wasi-libc doesn't know about FIFOs (for previously described reasons).

ESPIPE is an error documented as being returned by fseek/pread, not by read. Wasip2 doesn't provide any way to use read, and Wasmtime layers wasip1 on top of wasip2 so it too can't use read.

view this post on Zulip Wasmtime GitHub notifications bot (May 02 2025 at 20:03):

pchickey commented on issue #10713:

Ah right thats an implementation detail of wasi p1 on p2 that I forgot about, probably because its never been tested on FIFOs.

So, for now, FIFOs wont work under either p1 or p2. Someone will have to do some work to get them working. I can guide someone if theyre willing to dig into the implementations to contribute, but I can't prioritize it for myself for a while.

view this post on Zulip Wasmtime GitHub notifications bot (May 03 2025 at 04:43):

ST-Saint edited a comment on issue #10713:

Thanks for the quick reply.

I also tried reading the FIFO file blindly (without checking the file stat), but I still got seek errors:

# shell 1
wasmtime run --dir=/tmp::/tmp test_fifo.wasm
> ... # pending

# shell 2
echo "test" > /tmp/fifo

# shell 1

read: Invalid seek

Yet, if I simply compile the test to native code, I do receive the message from the FIFO file.

clang -o test_fifo test_fifo.c

# shell 1
./test_fifo
> ... # pending

# shell 2
echo "test" > /tmp/fifo

# shell 1
> Received: test

so it seems that I cannot operate the FIFO files with wasi 0.1?

// test_fifo.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

int main()
{
        const char *fifo_path = "/tmp/fifo";
        struct stat st;

        int fd = open(fifo_path, O_RDONLY);
        if (fd == -1) {
                perror("open");
                exit(EXIT_FAILURE);
        }

        char buffer[128];
        ssize_t bytes_read;
        while ((bytes_read = read(fd, buffer, sizeof(buffer) - 1)) > 0) {
                buffer[bytes_read] = '\0';
                printf("Received: %s\n", buffer);
        }

        if (bytes_read == -1) {
                perror("read");
        }

        close(fd);
        return 0;
}

Last updated: Dec 06 2025 at 07:03 UTC