On Emscripten, when reading from a pipe created via pipe(), the read() call returns immediately with EAGAIN when there's no data in the pipe. This contradicts the standard behavior specified by POSIX:
EAGAIN The file descriptor fd refers to a file other than a
socket and has been marked nonblocking (O_NONBLOCK), and
the read would block. See open(2) for further details on
the O_NONBLOCK flag.
EAGAIN or EWOULDBLOCK
The file descriptor fd refers to a socket and has been
marked nonblocking (O_NONBLOCK), and the read would block.
https://man7.org/linux/man-pages/man2/read.2.html
If a process attempts to read from an empty pipe, then read(2)
will block until data is available. <...>
Nonblocking I/O is possible by using the fcntl(2)
F_SETFL operation to enable the O_NONBLOCK open file status flag.
https://man7.org/linux/man-pages/man7/pipe.7.html
Given that pipe() doesn't set the O_NONBLOCK flag, I believe the Emscripten's behavior with returning EAGAIN is wrong.
Sample program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {
int pipefd[2];
if (pipe(pipefd)) {
perror("pipe() failed");
exit(-1);
}
if (argc > 1) {
char c = 0;
if (write(pipefd[1], &c, 1) != 1) {
perror("write() failed");
exit(-1);
}
}
char c;
if (read(pipefd[0], &c, 1) != 1) {
perror("read() failed");
exit(-1);
}
exit(0);
}
This program, when run under Emscripten, fails with "Resource temporarily unavailable". When the same program is run on Linux using standard g++ and libc, it correctly blocks in read().
P.S. The program also demonstrates that, in case write() was previously called, the data is successfully read from it under Emscripten.
On Emscripten, when reading from a pipe created via
pipe(), theread()call returns immediately withEAGAINwhen there's no data in the pipe. This contradicts the standard behavior specified by POSIX:https://man7.org/linux/man-pages/man2/read.2.html
https://man7.org/linux/man-pages/man7/pipe.7.html
Given that
pipe()doesn't set theO_NONBLOCKflag, I believe the Emscripten's behavior with returningEAGAINis wrong.Sample program:
This program, when run under Emscripten, fails with "Resource temporarily unavailable". When the same program is run on Linux using standard g++ and libc, it correctly blocks in
read().P.S. The program also demonstrates that, in case
write()was previously called, the data is successfully read from it under Emscripten.