rktio: reset non-blocking on sockets after dup

On Linux, is appears that duping a socket doesn't give the
new one the same non-blocking option as the original.
This commit is contained in:
Matthew Flatt 2017-06-18 09:51:27 -06:00
parent c1416d07d6
commit a13bfd25d0
2 changed files with 11 additions and 4 deletions

View File

@ -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_OPEN_TEXT flag has an effect only on Windows. */
RKTIO_EXTERN int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd); 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); 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 /* Can report `RKTIO_ERROR_DOES_NOT_EXIST` in place of a system error

View File

@ -135,7 +135,7 @@ rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes)
rktio_fd_t *rfd; rktio_fd_t *rfd;
rfd = calloc(1, sizeof(rktio_fd_t)); rfd = calloc(1, sizeof(rktio_fd_t));
rfd->modes = modes; rfd->modes = (modes - (modes & RKTIO_OPEN_INIT));
#ifdef RKTIO_SYSTEM_UNIX #ifdef RKTIO_SYSTEM_UNIX
rfd->fd = system_fd; rfd->fd = system_fd;
@ -288,8 +288,13 @@ rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd)
if (nfd == -1) { if (nfd == -1) {
get_posix_error(); get_posix_error();
return NULL; return NULL;
} else } else {
return rktio_system_fd(rktio, nfd, rfd->modes); /* 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 #endif
#ifdef RKTIO_SYSTEM_WINDOWS #ifdef RKTIO_SYSTEM_WINDOWS
if (rfd->modes & RKTIO_OPEN_SOCKET) { if (rfd->modes & RKTIO_OPEN_SOCKET) {