-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Open
Description
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.
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.
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.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels