diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index 19319d9c8b..b3d2d2a3db 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -151,7 +151,9 @@ RKTIO_EXTERN rktio_bool_t rktio_fd_is_text_converted(rktio_t *rktio, rktio_fd_t RKTIO_OPEN_TEXT flag has an effect only on Windows. */ RKTIO_EXTERN int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd); -/* Returns all of the recorded mode flags. */ +/* Returns all of the recorded mode flags, including those provided to + `rktio_system_fd` and those that are inferred. The + `RKTIO_OPEN_INIT` flag is not recorded, however. */ RKTIO_EXTERN rktio_fd_t *rktio_open(rktio_t *rktio, const char *src, int modes); /* Can report `RKTIO_ERROR_DOES_NOT_EXIST` in place of a system error diff --git a/racket/src/rktio/rktio_fd.c b/racket/src/rktio/rktio_fd.c index 5125d9364c..5dbbbf57e4 100644 --- a/racket/src/rktio/rktio_fd.c +++ b/racket/src/rktio/rktio_fd.c @@ -135,7 +135,7 @@ rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes) rktio_fd_t *rfd; rfd = calloc(1, sizeof(rktio_fd_t)); - rfd->modes = modes; + rfd->modes = (modes - (modes & RKTIO_OPEN_INIT)); #ifdef RKTIO_SYSTEM_UNIX rfd->fd = system_fd; @@ -288,8 +288,13 @@ rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd) if (nfd == -1) { get_posix_error(); return NULL; - } else - return rktio_system_fd(rktio, nfd, rfd->modes); + } else { + /* Set the `RKTIO_OPEN_INIT` flag, because dup()ing a file + descriptor does not keep all of its properties on some + platforms (e.g., the non-blocking property on sockets on + Linux). */ + return rktio_system_fd(rktio, nfd, rfd->modes | RKTIO_OPEN_INIT); + } #endif #ifdef RKTIO_SYSTEM_WINDOWS if (rfd->modes & RKTIO_OPEN_SOCKET) {