diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index a3ccd9d58b..8a64a26b24 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -229,6 +229,7 @@ struct fast_fallback_inetsock_arg rb_nativethread_lock_t *lock; struct fast_fallback_getaddrinfo_entry *getaddrinfo_entries[2]; struct fast_fallback_getaddrinfo_shared *getaddrinfo_shared; + int wait; int connection_attempt_fds_size; int *connection_attempt_fds; VALUE test_mode_settings; @@ -313,7 +314,7 @@ cancel_fast_fallback(void *ptr) { arg->cancelled = true; char notification = SELECT_CANCELLED; - if ((write(arg->notify, ¬ification, 1)) < 0) { + if (arg->notify != -1 && (write(arg->notify, ¬ification, 1)) < 0) { rb_syserr_fail(errno, "write(2)"); } } @@ -554,7 +555,7 @@ init_fast_fallback_inetsock_internal(VALUE v) pthread_t threads[arg->family_size]; char resolved_type[2]; ssize_t resolved_type_size; - int hostname_resolution_waiter = 0, hostname_resolution_notifier = 0; + int hostname_resolution_waiter = -1, hostname_resolution_notifier = -1; int pipefd[2]; fd_set readfds, writefds; @@ -587,6 +588,7 @@ init_fast_fallback_inetsock_internal(VALUE v) if ((fcntl(hostname_resolution_waiter, F_SETFL, waiter_flags | O_NONBLOCK)) < 0) { rb_syserr_fail(errno, "fcntl(2)"); } + arg->wait = hostname_resolution_waiter; hostname_resolution_notifier = pipefd[1]; wait_arg.readfds = &readfds; @@ -599,7 +601,6 @@ init_fast_fallback_inetsock_internal(VALUE v) rb_nativethread_lock_initialize(arg->getaddrinfo_shared->lock); arg->getaddrinfo_shared->notify = hostname_resolution_notifier; - arg->getaddrinfo_shared->wait = hostname_resolution_waiter; arg->getaddrinfo_shared->connection_attempt_fds = arg->connection_attempt_fds; arg->getaddrinfo_shared->connection_attempt_fds_size = arg->connection_attempt_fds_size; arg->getaddrinfo_shared->cancelled = false; @@ -1191,6 +1192,10 @@ fast_fallback_inetsock_cleanup(VALUE v) arg->local.res = 0; } + if (arg->wait != -1) close(arg->wait); + if (getaddrinfo_shared->notify != -1) close(getaddrinfo_shared->notify); + getaddrinfo_shared->notify = -1; + if (getaddrinfo_shared) { if (arg->family_size == 1) { free_fast_fallback_getaddrinfo_shared(&getaddrinfo_shared); diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index b5926d2e71..5759960e5a 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -3033,8 +3033,6 @@ free_fast_fallback_getaddrinfo_shared(struct fast_fallback_getaddrinfo_shared ** (*shared)->node = NULL; free((*shared)->service); (*shared)->service = NULL; - close((*shared)->notify); - close((*shared)->wait); rb_nativethread_lock_destroy((*shared)->lock); free(*shared); *shared = NULL; @@ -3057,6 +3055,11 @@ do_fast_fallback_getaddrinfo(void *ptr) struct fast_fallback_getaddrinfo_shared *shared = entry->shared; int err = 0, need_free = 0, shared_need_free = 0; + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &set, NULL); + err = numeric_getaddrinfo(shared->node, shared->service, &entry->hints, &entry->ai); if (err != 0) { @@ -3101,7 +3104,7 @@ do_fast_fallback_getaddrinfo(void *ptr) const char notification = entry->family == AF_INET6 ? IPV6_HOSTNAME_RESOLVED : IPV4_HOSTNAME_RESOLVED; - if ((write(shared->notify, ¬ification, 1)) < 0) { + if (shared->notify != -1 && (write(shared->notify, ¬ification, 1)) < 0) { entry->err = errno; entry->has_syserr = true; } diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h index 3b62dd370a..d1ea3f98b7 100644 --- a/ext/socket/rubysocket.h +++ b/ext/socket/rubysocket.h @@ -440,7 +440,7 @@ struct fast_fallback_getaddrinfo_entry struct fast_fallback_getaddrinfo_shared { - int wait, notify, refcount, connection_attempt_fds_size; + int notify, refcount, connection_attempt_fds_size; int cancelled; int *connection_attempt_fds; char *node, *service;