emscripten-core / emscripten-core/emscripten

pipe() doesn't create a blocking pipe

Open
#13,214 14 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

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.
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
#include
#include
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.