Skip to content

fcntl cannot clear O_NONBLOCK once it has been set #26705

@hly2019

Description

@hly2019

Version of emscripten/emsdk:

5.0.6

Basically, the pattern:

int fl = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, fl | O_NONBLOCK);
/* ... */
fcntl(fd, F_SETFL, fl & ~O_NONBLOCK); // switch back to blocking

works on Linux but not under Emscripten. The subsequent F_GETFL still reports O_NONBLOCK set.

Failing command line in full:

$ emcc -O0 -Wall fsetfl.c -o a.out.js
$ node a.out.js
after-set   O_NONBLOCK=1 (expect 1)
after-clear O_NONBLOCK=1 (expect 0)

The same program under native clang prints after-clear O_NONBLOCK=0 as expected.

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
    int fd = open("/tmp/x", O_RDWR | O_CREAT | O_TRUNC, 0644);
    int fl0 = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, fl0 | O_NONBLOCK);
    int fl1 = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, fl1 & ~O_NONBLOCK);
    int fl2 = fcntl(fd, F_GETFL, 0);
    printf("after-set   O_NONBLOCK=%d (expect 1)\n", (fl1 & O_NONBLOCK) != 0);
    printf("after-clear O_NONBLOCK=%d (expect 0)\n", (fl2 & O_NONBLOCK) != 0);
    close(fd);
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions