diff options
Diffstat (limited to 'ext/socket')
-rw-r--r-- | ext/socket/addrinfo.h | 36 | ||||
-rw-r--r-- | ext/socket/ancdata.c | 266 | ||||
-rw-r--r-- | ext/socket/basicsocket.c | 76 | ||||
-rw-r--r-- | ext/socket/constants.c | 6 | ||||
-rw-r--r-- | ext/socket/depend | 390 | ||||
-rw-r--r-- | ext/socket/extconf.rb | 55 | ||||
-rw-r--r-- | ext/socket/getaddrinfo.c | 897 | ||||
-rw-r--r-- | ext/socket/getnameinfo.c | 226 | ||||
-rw-r--r-- | ext/socket/ifaddr.c | 8 | ||||
-rw-r--r-- | ext/socket/init.c | 232 | ||||
-rw-r--r-- | ext/socket/ipsocket.c | 190 | ||||
-rw-r--r-- | ext/socket/lib/socket.rb | 542 | ||||
-rw-r--r-- | ext/socket/mkconstants.rb | 53 | ||||
-rw-r--r-- | ext/socket/option.c | 98 | ||||
-rw-r--r-- | ext/socket/raddrinfo.c | 796 | ||||
-rw-r--r-- | ext/socket/rubysocket.h | 30 | ||||
-rw-r--r-- | ext/socket/socket.c | 464 | ||||
-rw-r--r-- | ext/socket/sockssocket.c | 4 | ||||
-rw-r--r-- | ext/socket/tcpserver.c | 2 | ||||
-rw-r--r-- | ext/socket/tcpsocket.c | 18 | ||||
-rw-r--r-- | ext/socket/udpsocket.c | 30 | ||||
-rw-r--r-- | ext/socket/unixserver.c | 8 | ||||
-rw-r--r-- | ext/socket/unixsocket.c | 150 |
23 files changed, 2948 insertions, 1629 deletions
diff --git a/ext/socket/addrinfo.h b/ext/socket/addrinfo.h index f0b977d79c..eb9eb8ae0e 100644 --- a/ext/socket/addrinfo.h +++ b/ext/socket/addrinfo.h @@ -129,14 +129,14 @@ #ifndef HAVE_TYPE_STRUCT_ADDRINFO struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ }; #endif @@ -158,18 +158,18 @@ struct addrinfo { #endif extern int getaddrinfo __P(( - const char *hostname, const char *servname, - const struct addrinfo *hints, - struct addrinfo **res)); + const char *hostname, const char *servname, + const struct addrinfo *hints, + struct addrinfo **res)); extern int getnameinfo __P(( - const struct sockaddr *sa, - socklen_t salen, - char *host, - socklen_t hostlen, - char *serv, - socklen_t servlen, - int flags)); + const struct sockaddr *sa, + socklen_t salen, + char *host, + socklen_t hostlen, + char *serv, + socklen_t servlen, + int flags)); extern void freehostent __P((struct hostent *)); extern void freeaddrinfo __P((struct addrinfo *)); diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index aa62cab0ec..6ef040b692 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -333,11 +333,11 @@ ancillary_timestamp(VALUE self) if (level == SOL_SOCKET && type == SCM_BINTIME && RSTRING_LEN(data) == sizeof(struct bintime)) { struct bintime bt; - VALUE d, timev; + VALUE d, timev; memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt)); - d = ULL2NUM(0x100000000ULL); - d = mul(d,d); - timev = add(TIMET2NUM(bt.sec), quo(ULL2NUM(bt.frac), d)); + d = ULL2NUM(0x100000000ULL); + d = mul(d,d); + timev = add(TIMET2NUM(bt.sec), quo(ULL2NUM(bt.frac), d)); result = rb_time_num_new(timev, Qnil); } # endif @@ -697,7 +697,7 @@ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret) struct ucred cred; memcpy(&cred, RSTRING_PTR(data), sizeof(struct ucred)); rb_str_catf(ret, " pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid); - rb_str_cat2(ret, " (ucred)"); + rb_str_cat2(ret, " (ucred)"); return 1; } else { @@ -712,7 +712,7 @@ static int anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret) { if (level != SOL_SOCKET && type != SCM_CREDS) - return 0; + return 0; /* * FreeBSD has struct cmsgcred and struct sockcred. @@ -727,46 +727,46 @@ anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret) #if defined(HAVE_TYPE_STRUCT_CMSGCRED) /* FreeBSD */ if (RSTRING_LEN(data) == sizeof(struct cmsgcred)) { - struct cmsgcred cred; + struct cmsgcred cred; memcpy(&cred, RSTRING_PTR(data), sizeof(struct cmsgcred)); rb_str_catf(ret, " pid=%u", cred.cmcred_pid); rb_str_catf(ret, " uid=%u", cred.cmcred_uid); rb_str_catf(ret, " euid=%u", cred.cmcred_euid); rb_str_catf(ret, " gid=%u", cred.cmcred_gid); - if (cred.cmcred_ngroups) { - int i; - const char *sep = " groups="; - for (i = 0; i < cred.cmcred_ngroups; i++) { - rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]); - sep = ","; - } - } - rb_str_cat2(ret, " (cmsgcred)"); + if (cred.cmcred_ngroups) { + int i; + const char *sep = " groups="; + for (i = 0; i < cred.cmcred_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]); + sep = ","; + } + } + rb_str_cat2(ret, " (cmsgcred)"); return 1; } #endif #if defined(HAVE_TYPE_STRUCT_SOCKCRED) /* FreeBSD, NetBSD */ if ((size_t)RSTRING_LEN(data) >= SOCKCREDSIZE(0)) { - struct sockcred cred0, *cred; + struct sockcred cred0, *cred; memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0)); - if ((size_t)RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) { - cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups)); - memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups)); - rb_str_catf(ret, " uid=%u", cred->sc_uid); - rb_str_catf(ret, " euid=%u", cred->sc_euid); - rb_str_catf(ret, " gid=%u", cred->sc_gid); - rb_str_catf(ret, " egid=%u", cred->sc_egid); - if (cred0.sc_ngroups) { - int i; - const char *sep = " groups="; - for (i = 0; i < cred0.sc_ngroups; i++) { - rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]); - sep = ","; - } - } - rb_str_cat2(ret, " (sockcred)"); - return 1; - } + if ((size_t)RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) { + cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups)); + memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups)); + rb_str_catf(ret, " uid=%u", cred->sc_uid); + rb_str_catf(ret, " euid=%u", cred->sc_euid); + rb_str_catf(ret, " gid=%u", cred->sc_gid); + rb_str_catf(ret, " egid=%u", cred->sc_egid); + if (cred0.sc_ngroups) { + int i; + const char *sep = " groups="; + for (i = 0; i < cred0.sc_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]); + sep = ","; + } + } + rb_str_cat2(ret, " (sockcred)"); + return 1; + } } #endif return 0; @@ -906,37 +906,37 @@ inspect_bintime_as_abstime(int level, int optname, VALUE data, VALUE ret) if (RSTRING_LEN(data) == sizeof(struct bintime)) { struct bintime bt; struct tm tm; - uint64_t frac_h, frac_l; - uint64_t scale_h, scale_l; - uint64_t tmp1, tmp2; - uint64_t res_h, res_l; + uint64_t frac_h, frac_l; + uint64_t scale_h, scale_l; + uint64_t tmp1, tmp2; + uint64_t res_h, res_l; char buf[32]; memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt)); LOCALTIME(bt.sec, tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); - /* res_h = frac * 10**19 / 2**64 */ + /* res_h = frac * 10**19 / 2**64 */ - frac_h = bt.frac >> 32; - frac_l = bt.frac & 0xffffffff; + frac_h = bt.frac >> 32; + frac_l = bt.frac & 0xffffffff; - scale_h = 0x8ac72304; /* 0x8ac7230489e80000 == 10**19 */ - scale_l = 0x89e80000; + scale_h = 0x8ac72304; /* 0x8ac7230489e80000 == 10**19 */ + scale_l = 0x89e80000; - res_h = frac_h * scale_h; - res_l = frac_l * scale_l; + res_h = frac_h * scale_h; + res_l = frac_l * scale_l; - tmp1 = frac_h * scale_l; - res_h += tmp1 >> 32; - tmp2 = res_l; - res_l += tmp1 & 0xffffffff; - if (res_l < tmp2) res_h++; + tmp1 = frac_h * scale_l; + res_h += tmp1 >> 32; + tmp2 = res_l; + res_l += tmp1 & 0xffffffff; + if (res_l < tmp2) res_h++; - tmp1 = frac_l * scale_h; - res_h += tmp1 >> 32; - tmp2 = res_l; - res_l += tmp1 & 0xffffffff; - if (res_l < tmp2) res_h++; + tmp1 = frac_l * scale_h; + res_h += tmp1 >> 32; + tmp2 = res_l; + res_l += tmp1 & 0xffffffff; + if (res_l < tmp2) res_h++; rb_str_catf(ret, " %s.%019"PRIu64, buf, res_h); return 1; @@ -1136,8 +1136,8 @@ rb_sendmsg(int fd, const struct msghdr *msg, int flags) static VALUE bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, - VALUE dest_sockaddr, VALUE controls, VALUE ex, - int nonblock) + VALUE dest_sockaddr, VALUE controls, VALUE ex, + int nonblock) { rb_io_t *fptr; struct msghdr mh; @@ -1160,15 +1160,15 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, tmp = rb_str_tmp_frozen_acquire(data); if (!RB_TYPE_P(controls, T_ARRAY)) { - controls = rb_ary_new(); + controls = rb_ary_new(); } controls_num = RARRAY_LENINT(controls); if (controls_num) { #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - int i; - size_t last_pad = 0; - const VALUE *controls_ptr = RARRAY_CONST_PTR(controls); + int i; + size_t last_pad = 0; + const VALUE *controls_ptr = RARRAY_CONST_PTR(controls); #if defined(__NetBSD__) int last_level = 0; int last_type = 0; @@ -1215,9 +1215,9 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, last_level = cmh.cmsg_level; last_type = cmh.cmsg_type; #endif - last_pad = cspace - cmh.cmsg_len; + last_pad = cspace - cmh.cmsg_len; } - if (last_pad) { + if (last_pad) { /* * This code removes the last padding from msg_controllen. * @@ -1242,10 +1242,10 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS) rb_str_set_len(controls_str, RSTRING_LEN(controls_str)-last_pad); #endif - } - RB_GC_GUARD(controls); + } + RB_GC_GUARD(controls); #else - rb_raise(rb_eNotImpError, "control message for sendmsg is unimplemented"); + rb_raise(rb_eNotImpError, "control message for sendmsg is unimplemented"); #endif } @@ -1256,7 +1256,7 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, #endif if (!NIL_P(dest_sockaddr)) - SockAddrStringValue(dest_sockaddr); + SockAddrStringValue(dest_sockaddr); rb_io_check_closed(fptr); @@ -1284,20 +1284,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, ss = rb_sendmsg(fptr->fd, &mh, flags); if (ss == -1) { - int e; - if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + int e; + if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(fptr); goto retry; } - e = errno; - if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { - if (ex == Qfalse) { - return sym_wait_writable; - } - rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, - "sendmsg(2) would block"); - } - rb_syserr_fail(e, "sendmsg(2)"); + e = errno; + if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { + if (ex == Qfalse) { + return sym_wait_writable; + } + rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, + "sendmsg(2) would block"); + } + rb_syserr_fail(e, "sendmsg(2)"); } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) RB_GC_GUARD(controls_str); @@ -1311,20 +1311,20 @@ bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, #if defined(HAVE_SENDMSG) VALUE rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, VALUE dest_sockaddr, - VALUE controls) + VALUE controls) { return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, controls, - Qtrue, 0); + Qtrue, 0); } #endif #if defined(HAVE_SENDMSG) VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, - VALUE dest_sockaddr, VALUE controls, VALUE ex) + VALUE dest_sockaddr, VALUE controls, VALUE ex) { return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, - controls, ex, 1); + controls, ex, 1); } #endif @@ -1422,12 +1422,12 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end) { if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) { int *fdp, *end; - VALUE ary = rb_ary_new(); - rb_ivar_set(ctl, rb_intern("unix_rights"), ary); + VALUE ary = rb_ary_new(); + rb_ivar_set(ctl, rb_intern("unix_rights"), ary); fdp = (int *)CMSG_DATA(cmh); end = (int *)((char *)cmh + cmh->cmsg_len); while ((char *)fdp + sizeof(int) <= (char *)end && - (char *)fdp + sizeof(int) <= msg_end) { + (char *)fdp + sizeof(int) <= msg_end) { int fd = *fdp; struct stat stbuf; VALUE io; @@ -1443,15 +1443,15 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end) rb_ary_push(ary, io); fdp++; } - OBJ_FREEZE(ary); + OBJ_FREEZE(ary); } } #endif static VALUE bsock_recvmsg_internal(VALUE sock, - VALUE vmaxdatlen, VALUE vflags, VALUE vmaxctllen, - VALUE scm_rights, VALUE ex, int nonblock) + VALUE vmaxdatlen, VALUE vflags, VALUE vmaxctllen, + VALUE scm_rights, VALUE ex, int nonblock) { rb_io_t *fptr; int grow_buffer; @@ -1505,28 +1505,28 @@ bsock_recvmsg_internal(VALUE sock, #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (grow_buffer) { - int socktype; - socklen_t optlen = (socklen_t)sizeof(socktype); + int socktype; + socklen_t optlen = (socklen_t)sizeof(socktype); if (getsockopt(fptr->fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen) == -1) { - rb_sys_fail("getsockopt(SO_TYPE)"); - } - if (socktype == SOCK_STREAM) - grow_buffer = 0; + rb_sys_fail("getsockopt(SO_TYPE)"); + } + if (socktype == SOCK_STREAM) + grow_buffer = 0; } #endif retry: if (NIL_P(dat_str)) - dat_str = rb_str_tmp_new(maxdatlen); + dat_str = rb_str_tmp_new(maxdatlen); else - rb_str_resize(dat_str, maxdatlen); + rb_str_resize(dat_str, maxdatlen); datbuf = RSTRING_PTR(dat_str); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (NIL_P(ctl_str)) - ctl_str = rb_str_tmp_new(maxctllen); + ctl_str = rb_str_tmp_new(maxctllen); else - rb_str_resize(ctl_str, maxctllen); + rb_str_resize(ctl_str, maxctllen); ctlbuf = RSTRING_PTR(ctl_str); #endif @@ -1555,21 +1555,25 @@ bsock_recvmsg_internal(VALUE sock, ss = rb_recvmsg(fptr->fd, &mh, flags); + if (ss == 0 && !rsock_is_dgram(fptr)) { + return Qnil; + } + if (ss == -1) { - int e; - if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, Qnil)) { + int e; + if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { rb_io_check_closed(fptr); goto retry; } - e = errno; - if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { + e = errno; + if (nonblock && (e == EWOULDBLOCK || e == EAGAIN)) { if (ex == Qfalse) { return sym_wait_readable; } - rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvmsg(2) would block"); + rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvmsg(2) would block"); } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (!gc_done && (e == EMFILE || e == EMSGSIZE)) { + if (!gc_done && (e == EMFILE || e == EMSGSIZE)) { /* * When SCM_RIGHTS hit the file descriptors limit: * - Linux 2.6.18 causes success with MSG_CTRUNC @@ -1579,24 +1583,24 @@ bsock_recvmsg_internal(VALUE sock, gc_and_retry: rb_gc(); gc_done = 1; - goto retry; + goto retry; } #else - if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE) - ss = (ssize_t)iov.iov_len; - else + if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE) + ss = (ssize_t)iov.iov_len; + else #endif - rb_syserr_fail(e, "recvmsg(2)"); + rb_syserr_fail(e, "recvmsg(2)"); } if (grow_buffer) { - int grown = 0; - if (NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) { + int grown = 0; + if (NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) { if (SIZE_MAX/2 < maxdatlen) rb_raise(rb_eArgError, "max data length too big"); - maxdatlen *= 2; - grown = 1; - } + maxdatlen *= 2; + grown = 1; + } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (NIL_P(vmaxctllen) && (mh.msg_flags & MSG_CTRUNC)) { #define BIG_ENOUGH_SPACE 65536 @@ -1605,9 +1609,9 @@ bsock_recvmsg_internal(VALUE sock, /* there are big space bug truncated. * file descriptors limit? */ if (!gc_done) { - rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); goto gc_and_retry; - } + } } else { if (SIZE_MAX/2 < maxctllen) @@ -1616,13 +1620,13 @@ bsock_recvmsg_internal(VALUE sock, grown = 1; } #undef BIG_ENOUGH_SPACE - } + } #endif - if (grown) { + if (grown) { rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); - goto retry; - } - else { + goto retry; + } + else { grow_buffer = 0; if (flags != orig_flags) { rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); @@ -1636,31 +1640,31 @@ bsock_recvmsg_internal(VALUE sock, dat_str = rb_str_new(datbuf, ss); else { rb_str_resize(dat_str, ss); - rb_obj_reveal(dat_str, rb_cString); + rb_obj_reveal(dat_str, rb_cString); } ret = rb_ary_new3(3, dat_str, rsock_io_socket_addrinfo(sock, mh.msg_name, mh.msg_namelen), #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - INT2NUM(mh.msg_flags) + INT2NUM(mh.msg_flags) #else - Qnil + Qnil #endif - ); + ); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) family = rsock_getfamily(fptr); if (mh.msg_controllen) { - char *msg_end = (char *)mh.msg_control + mh.msg_controllen; + char *msg_end = (char *)mh.msg_control + mh.msg_controllen; for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) { VALUE ctl; - char *ctl_end; + char *ctl_end; size_t clen; if (cmh->cmsg_len == 0) { rb_raise(rb_eTypeError, "invalid control message (cmsg_len == 0)"); } ctl_end = (char*)cmh + cmh->cmsg_len; - clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh); + clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh); ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_str_new((char*)CMSG_DATA(cmh), clen)); if (request_scm_rights) make_io_for_unix_rights(ctl, cmh, msg_end); @@ -1679,7 +1683,7 @@ bsock_recvmsg_internal(VALUE sock, #if defined(HAVE_RECVMSG) VALUE rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, - VALUE scm_rights) + VALUE scm_rights) { VALUE ex = Qtrue; return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 0); @@ -1689,7 +1693,7 @@ rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, #if defined(HAVE_RECVMSG) VALUE rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, - VALUE scm_rights, VALUE ex) + VALUE scm_rights, VALUE ex) { return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 1); } diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 44fb7a4eb7..54c369f6fc 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -94,16 +94,16 @@ bsock_shutdown(int argc, VALUE *argv, VALUE sock) rb_scan_args(argc, argv, "01", &howto); if (howto == Qnil) - how = SHUT_RDWR; + how = SHUT_RDWR; else { - how = rsock_shutdown_how_arg(howto); + how = rsock_shutdown_how_arg(howto); if (how != SHUT_WR && how != SHUT_RD && how != SHUT_RDWR) { - rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR"); - } + rb_raise(rb_eArgError, "`how' should be either :SHUT_RD, :SHUT_WR, :SHUT_RDWR"); + } } GetOpenFile(sock, fptr); if (shutdown(fptr->fd, how) == -1) - rb_sys_fail("shutdown(2)"); + rb_sys_fail("shutdown(2)"); return INT2FIX(0); } @@ -126,7 +126,7 @@ bsock_close_read(VALUE sock) GetOpenFile(sock, fptr); shutdown(fptr->fd, 0); if (!(fptr->mode & FMODE_WRITABLE)) { - return rb_io_close(sock); + return rb_io_close(sock); } fptr->mode &= ~FMODE_READABLE; @@ -155,7 +155,7 @@ bsock_close_write(VALUE sock) GetOpenFile(sock, fptr); if (!(fptr->mode & FMODE_READABLE)) { - return rb_io_close(sock); + return rb_io_close(sock); } shutdown(fptr->fd, 1); fptr->mode &= ~FMODE_WRITABLE; @@ -246,21 +246,21 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock) switch (TYPE(val)) { case T_FIXNUM: - i = FIX2INT(val); - goto numval; + i = FIX2INT(val); + goto numval; case T_FALSE: - i = 0; - goto numval; + i = 0; + goto numval; case T_TRUE: - i = 1; + i = 1; numval: - v = (char*)&i; vlen = (int)sizeof(i); - break; + v = (char*)&i; vlen = (int)sizeof(i); + break; default: - StringValue(val); - v = RSTRING_PTR(val); - vlen = RSTRING_SOCKLEN(val); - break; + StringValue(val); + v = RSTRING_PTR(val); + vlen = RSTRING_SOCKLEN(val); + break; } rb_io_check_closed(fptr); @@ -357,7 +357,7 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname) rb_io_check_closed(fptr); if (getsockopt(fptr->fd, level, option, buf, &len) < 0) - rsock_sys_fail_path("getsockopt(2)", fptr->pathv); + rsock_sys_fail_path("getsockopt(2)", fptr->pathv); return rsock_sockopt_new(family, level, option, rb_str_new(buf, len)); } @@ -385,7 +385,7 @@ bsock_getsockname(VALUE sock) GetOpenFile(sock, fptr); if (getsockname(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); + rb_sys_fail("getsockname(2)"); if (len0 < len) len = len0; return rb_str_new((char*)&buf, len); } @@ -416,7 +416,7 @@ bsock_getpeername(VALUE sock) GetOpenFile(sock, fptr); if (getpeername(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); + rb_sys_fail("getpeername(2)"); if (len0 < len) len = len0; return rb_str_new((char*)&buf, len); } @@ -453,7 +453,7 @@ bsock_getpeereid(VALUE self) gid_t egid; GetOpenFile(self, fptr); if (getpeereid(fptr->fd, &euid, &egid) == -1) - rb_sys_fail("getpeereid(3)"); + rb_sys_fail("getpeereid(3)"); return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid)); #elif defined(SO_PEERCRED) /* GNU/Linux */ rb_io_t *fptr; @@ -461,7 +461,7 @@ bsock_getpeereid(VALUE self) socklen_t len = sizeof(cred); GetOpenFile(self, fptr); if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1) - rb_sys_fail("getsockopt(SO_PEERCRED)"); + rb_sys_fail("getsockopt(SO_PEERCRED)"); return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid)); #elif defined(HAVE_GETPEERUCRED) /* Solaris */ rb_io_t *fptr; @@ -469,7 +469,7 @@ bsock_getpeereid(VALUE self) VALUE ret; GetOpenFile(self, fptr); if (getpeerucred(fptr->fd, &uc) == -1) - rb_sys_fail("getpeerucred(3C)"); + rb_sys_fail("getpeerucred(3C)"); ret = rb_assoc_new(UIDT2NUM(ucred_geteuid(uc)), GIDT2NUM(ucred_getegid(uc))); ucred_free(uc); return ret; @@ -506,7 +506,7 @@ bsock_local_address(VALUE sock) GetOpenFile(sock, fptr); if (getsockname(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); + rb_sys_fail("getsockname(2)"); if (len0 < len) len = len0; return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len); } @@ -540,7 +540,7 @@ bsock_remote_address(VALUE sock) GetOpenFile(sock, fptr); if (getpeername(fptr->fd, &buf.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); + rb_sys_fail("getpeername(2)"); if (len0 < len) len = len0; return rsock_fd_socket_addrinfo(fptr->fd, &buf.addr, len); } @@ -601,7 +601,7 @@ rsock_bsock_send(int argc, VALUE *argv, VALUE socket) if (n >= 0) return SSIZET2NUM(n); - if (rb_io_maybe_wait_writable(errno, socket, Qnil)) { + if (rb_io_maybe_wait_writable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT)) { continue; } @@ -656,10 +656,10 @@ bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state) GetOpenFile(sock, fptr); if (RTEST(state)) { - fptr->mode |= FMODE_NOREVLOOKUP; + fptr->mode |= FMODE_NOREVLOOKUP; } else { - fptr->mode &= ~FMODE_NOREVLOOKUP; + fptr->mode &= ~FMODE_NOREVLOOKUP; } return sock; } @@ -747,9 +747,9 @@ rsock_init_basicsocket(void) rb_undef_method(rb_cBasicSocket, "initialize"); rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup", - bsock_do_not_rev_lookup, 0); + bsock_do_not_rev_lookup, 0); rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup=", - bsock_do_not_rev_lookup_set, 1); + bsock_do_not_rev_lookup_set, 1); rb_define_singleton_method(rb_cBasicSocket, "for_fd", bsock_s_for_fd, 1); rb_define_method(rb_cBasicSocket, "close_read", bsock_close_read, 0); @@ -770,23 +770,23 @@ rsock_init_basicsocket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cBasicSocket, - "__recv_nonblock", bsock_recv_nonblock, 4); + "__recv_nonblock", bsock_recv_nonblock, 4); #if MSG_DONTWAIT_RELIABLE rb_define_private_method(rb_cBasicSocket, - "__read_nonblock", rsock_read_nonblock, 3); + "__read_nonblock", rsock_read_nonblock, 3); rb_define_private_method(rb_cBasicSocket, - "__write_nonblock", rsock_write_nonblock, 2); + "__write_nonblock", rsock_write_nonblock, 2); #endif /* in ancdata.c */ rb_define_private_method(rb_cBasicSocket, "__sendmsg", - rsock_bsock_sendmsg, 4); + rsock_bsock_sendmsg, 4); rb_define_private_method(rb_cBasicSocket, "__sendmsg_nonblock", - rsock_bsock_sendmsg_nonblock, 5); + rsock_bsock_sendmsg_nonblock, 5); rb_define_private_method(rb_cBasicSocket, "__recvmsg", - rsock_bsock_recvmsg, 4); + rsock_bsock_recvmsg, 4); rb_define_private_method(rb_cBasicSocket, "__recvmsg_nonblock", - rsock_bsock_recvmsg_nonblock, 5); + rsock_bsock_recvmsg_nonblock, 5); } diff --git a/ext/socket/constants.c b/ext/socket/constants.c index 1bbb53b173..1213f2ae17 100644 --- a/ext/socket/constants.c +++ b/ext/socket/constants.c @@ -26,14 +26,14 @@ constant_arg(VALUE arg, int (*str_to_int)(const char*, long, int*), const char * goto str; } else if (!NIL_P(tmp = rb_check_string_type(arg))) { - arg = tmp; + arg = tmp; str: ptr = RSTRING_PTR(arg); if (str_to_int(ptr, RSTRING_LEN(arg), &ret) == -1) - rb_raise(rb_eSocket, "%s: %s", errmsg, ptr); + rb_raise(rb_eSocket, "%s: %s", errmsg, ptr); } else { - ret = NUM2INT(arg); + ret = NUM2INT(arg); } return ret; } diff --git a/ext/socket/depend b/ext/socket/depend index f2d7a67bcb..750bb0734f 100644 --- a/ext/socket/depend +++ b/ext/socket/depend @@ -12,8 +12,8 @@ constdefs.c: constdefs.h # AUTOGENERATED DEPENDENCIES START ancdata.o: $(RUBY_EXTCONF_H) ancdata.o: $(arch_hdrdir)/ruby/config.h -ancdata.o: $(hdrdir)/ruby.h ancdata.o: $(hdrdir)/ruby/assert.h +ancdata.o: $(hdrdir)/ruby/atomic.h ancdata.o: $(hdrdir)/ruby/backward.h ancdata.o: $(hdrdir)/ruby/backward/2/assume.h ancdata.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -28,6 +28,7 @@ ancdata.o: $(hdrdir)/ruby/defines.h ancdata.o: $(hdrdir)/ruby/encoding.h ancdata.o: $(hdrdir)/ruby/fiber/scheduler.h ancdata.o: $(hdrdir)/ruby/intern.h +ancdata.o: $(hdrdir)/ruby/internal/abi.h ancdata.o: $(hdrdir)/ruby/internal/anyargs.h ancdata.o: $(hdrdir)/ruby/internal/arithmetic.h ancdata.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -65,6 +66,7 @@ ancdata.o: $(hdrdir)/ruby/internal/attr/noexcept.h ancdata.o: $(hdrdir)/ruby/internal/attr/noinline.h ancdata.o: $(hdrdir)/ruby/internal/attr/nonnull.h ancdata.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ancdata.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ancdata.o: $(hdrdir)/ruby/internal/attr/pure.h ancdata.o: $(hdrdir)/ruby/internal/attr/restrict.h ancdata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -133,7 +135,6 @@ ancdata.o: $(hdrdir)/ruby/internal/intern/enumerator.h ancdata.o: $(hdrdir)/ruby/internal/intern/error.h ancdata.o: $(hdrdir)/ruby/internal/intern/eval.h ancdata.o: $(hdrdir)/ruby/internal/intern/file.h -ancdata.o: $(hdrdir)/ruby/internal/intern/gc.h ancdata.o: $(hdrdir)/ruby/internal/intern/hash.h ancdata.o: $(hdrdir)/ruby/internal/intern/io.h ancdata.o: $(hdrdir)/ruby/internal/intern/load.h @@ -164,12 +165,12 @@ ancdata.o: $(hdrdir)/ruby/internal/memory.h ancdata.o: $(hdrdir)/ruby/internal/method.h ancdata.o: $(hdrdir)/ruby/internal/module.h ancdata.o: $(hdrdir)/ruby/internal/newobj.h -ancdata.o: $(hdrdir)/ruby/internal/rgengc.h ancdata.o: $(hdrdir)/ruby/internal/scan_args.h ancdata.o: $(hdrdir)/ruby/internal/special_consts.h ancdata.o: $(hdrdir)/ruby/internal/static_assert.h ancdata.o: $(hdrdir)/ruby/internal/stdalign.h ancdata.o: $(hdrdir)/ruby/internal/stdbool.h +ancdata.o: $(hdrdir)/ruby/internal/stdckdint.h ancdata.o: $(hdrdir)/ruby/internal/symbol.h ancdata.o: $(hdrdir)/ruby/internal/value.h ancdata.o: $(hdrdir)/ruby/internal/value_type.h @@ -184,27 +185,46 @@ ancdata.o: $(hdrdir)/ruby/ruby.h ancdata.o: $(hdrdir)/ruby/st.h ancdata.o: $(hdrdir)/ruby/subst.h ancdata.o: $(hdrdir)/ruby/thread.h +ancdata.o: $(hdrdir)/ruby/thread_native.h ancdata.o: $(hdrdir)/ruby/util.h +ancdata.o: $(hdrdir)/ruby/version.h +ancdata.o: $(top_srcdir)/ccan/check_type/check_type.h +ancdata.o: $(top_srcdir)/ccan/container_of/container_of.h +ancdata.o: $(top_srcdir)/ccan/list/list.h +ancdata.o: $(top_srcdir)/ccan/str/str.h ancdata.o: $(top_srcdir)/internal.h ancdata.o: $(top_srcdir)/internal/array.h +ancdata.o: $(top_srcdir)/internal/basic_operators.h ancdata.o: $(top_srcdir)/internal/compilers.h ancdata.o: $(top_srcdir)/internal/error.h ancdata.o: $(top_srcdir)/internal/gc.h +ancdata.o: $(top_srcdir)/internal/imemo.h ancdata.o: $(top_srcdir)/internal/io.h +ancdata.o: $(top_srcdir)/internal/sanitizers.h ancdata.o: $(top_srcdir)/internal/serial.h ancdata.o: $(top_srcdir)/internal/static_assert.h ancdata.o: $(top_srcdir)/internal/string.h ancdata.o: $(top_srcdir)/internal/thread.h ancdata.o: $(top_srcdir)/internal/vm.h ancdata.o: $(top_srcdir)/internal/warnings.h +ancdata.o: $(top_srcdir)/method.h +ancdata.o: $(top_srcdir)/node.h +ancdata.o: $(top_srcdir)/ruby_assert.h +ancdata.o: $(top_srcdir)/ruby_atomic.h +ancdata.o: $(top_srcdir)/rubyparser.h +ancdata.o: $(top_srcdir)/shape.h +ancdata.o: $(top_srcdir)/thread_pthread.h +ancdata.o: $(top_srcdir)/vm_core.h +ancdata.o: $(top_srcdir)/vm_opts.h ancdata.o: ancdata.c ancdata.o: constdefs.h ancdata.o: rubysocket.h ancdata.o: sockport.h +ancdata.o: {$(VPATH)}id.h basicsocket.o: $(RUBY_EXTCONF_H) basicsocket.o: $(arch_hdrdir)/ruby/config.h -basicsocket.o: $(hdrdir)/ruby.h basicsocket.o: $(hdrdir)/ruby/assert.h +basicsocket.o: $(hdrdir)/ruby/atomic.h basicsocket.o: $(hdrdir)/ruby/backward.h basicsocket.o: $(hdrdir)/ruby/backward/2/assume.h basicsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -219,6 +239,7 @@ basicsocket.o: $(hdrdir)/ruby/defines.h basicsocket.o: $(hdrdir)/ruby/encoding.h basicsocket.o: $(hdrdir)/ruby/fiber/scheduler.h basicsocket.o: $(hdrdir)/ruby/intern.h +basicsocket.o: $(hdrdir)/ruby/internal/abi.h basicsocket.o: $(hdrdir)/ruby/internal/anyargs.h basicsocket.o: $(hdrdir)/ruby/internal/arithmetic.h basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -256,6 +277,7 @@ basicsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h basicsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h basicsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h basicsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h basicsocket.o: $(hdrdir)/ruby/internal/attr/pure.h basicsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h basicsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -324,7 +346,6 @@ basicsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h basicsocket.o: $(hdrdir)/ruby/internal/intern/error.h basicsocket.o: $(hdrdir)/ruby/internal/intern/eval.h basicsocket.o: $(hdrdir)/ruby/internal/intern/file.h -basicsocket.o: $(hdrdir)/ruby/internal/intern/gc.h basicsocket.o: $(hdrdir)/ruby/internal/intern/hash.h basicsocket.o: $(hdrdir)/ruby/internal/intern/io.h basicsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -355,12 +376,12 @@ basicsocket.o: $(hdrdir)/ruby/internal/memory.h basicsocket.o: $(hdrdir)/ruby/internal/method.h basicsocket.o: $(hdrdir)/ruby/internal/module.h basicsocket.o: $(hdrdir)/ruby/internal/newobj.h -basicsocket.o: $(hdrdir)/ruby/internal/rgengc.h basicsocket.o: $(hdrdir)/ruby/internal/scan_args.h basicsocket.o: $(hdrdir)/ruby/internal/special_consts.h basicsocket.o: $(hdrdir)/ruby/internal/static_assert.h basicsocket.o: $(hdrdir)/ruby/internal/stdalign.h basicsocket.o: $(hdrdir)/ruby/internal/stdbool.h +basicsocket.o: $(hdrdir)/ruby/internal/stdckdint.h basicsocket.o: $(hdrdir)/ruby/internal/symbol.h basicsocket.o: $(hdrdir)/ruby/internal/value.h basicsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -375,27 +396,46 @@ basicsocket.o: $(hdrdir)/ruby/ruby.h basicsocket.o: $(hdrdir)/ruby/st.h basicsocket.o: $(hdrdir)/ruby/subst.h basicsocket.o: $(hdrdir)/ruby/thread.h +basicsocket.o: $(hdrdir)/ruby/thread_native.h basicsocket.o: $(hdrdir)/ruby/util.h +basicsocket.o: $(hdrdir)/ruby/version.h +basicsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +basicsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +basicsocket.o: $(top_srcdir)/ccan/list/list.h +basicsocket.o: $(top_srcdir)/ccan/str/str.h basicsocket.o: $(top_srcdir)/internal.h basicsocket.o: $(top_srcdir)/internal/array.h +basicsocket.o: $(top_srcdir)/internal/basic_operators.h basicsocket.o: $(top_srcdir)/internal/compilers.h basicsocket.o: $(top_srcdir)/internal/error.h basicsocket.o: $(top_srcdir)/internal/gc.h +basicsocket.o: $(top_srcdir)/internal/imemo.h basicsocket.o: $(top_srcdir)/internal/io.h +basicsocket.o: $(top_srcdir)/internal/sanitizers.h basicsocket.o: $(top_srcdir)/internal/serial.h basicsocket.o: $(top_srcdir)/internal/static_assert.h basicsocket.o: $(top_srcdir)/internal/string.h basicsocket.o: $(top_srcdir)/internal/thread.h basicsocket.o: $(top_srcdir)/internal/vm.h basicsocket.o: $(top_srcdir)/internal/warnings.h +basicsocket.o: $(top_srcdir)/method.h +basicsocket.o: $(top_srcdir)/node.h +basicsocket.o: $(top_srcdir)/ruby_assert.h +basicsocket.o: $(top_srcdir)/ruby_atomic.h +basicsocket.o: $(top_srcdir)/rubyparser.h +basicsocket.o: $(top_srcdir)/shape.h +basicsocket.o: $(top_srcdir)/thread_pthread.h +basicsocket.o: $(top_srcdir)/vm_core.h +basicsocket.o: $(top_srcdir)/vm_opts.h basicsocket.o: basicsocket.c basicsocket.o: constdefs.h basicsocket.o: rubysocket.h basicsocket.o: sockport.h +basicsocket.o: {$(VPATH)}id.h constants.o: $(RUBY_EXTCONF_H) constants.o: $(arch_hdrdir)/ruby/config.h -constants.o: $(hdrdir)/ruby.h constants.o: $(hdrdir)/ruby/assert.h +constants.o: $(hdrdir)/ruby/atomic.h constants.o: $(hdrdir)/ruby/backward.h constants.o: $(hdrdir)/ruby/backward/2/assume.h constants.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -410,6 +450,7 @@ constants.o: $(hdrdir)/ruby/defines.h constants.o: $(hdrdir)/ruby/encoding.h constants.o: $(hdrdir)/ruby/fiber/scheduler.h constants.o: $(hdrdir)/ruby/intern.h +constants.o: $(hdrdir)/ruby/internal/abi.h constants.o: $(hdrdir)/ruby/internal/anyargs.h constants.o: $(hdrdir)/ruby/internal/arithmetic.h constants.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -447,6 +488,7 @@ constants.o: $(hdrdir)/ruby/internal/attr/noexcept.h constants.o: $(hdrdir)/ruby/internal/attr/noinline.h constants.o: $(hdrdir)/ruby/internal/attr/nonnull.h constants.o: $(hdrdir)/ruby/internal/attr/noreturn.h +constants.o: $(hdrdir)/ruby/internal/attr/packed_struct.h constants.o: $(hdrdir)/ruby/internal/attr/pure.h constants.o: $(hdrdir)/ruby/internal/attr/restrict.h constants.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -515,7 +557,6 @@ constants.o: $(hdrdir)/ruby/internal/intern/enumerator.h constants.o: $(hdrdir)/ruby/internal/intern/error.h constants.o: $(hdrdir)/ruby/internal/intern/eval.h constants.o: $(hdrdir)/ruby/internal/intern/file.h -constants.o: $(hdrdir)/ruby/internal/intern/gc.h constants.o: $(hdrdir)/ruby/internal/intern/hash.h constants.o: $(hdrdir)/ruby/internal/intern/io.h constants.o: $(hdrdir)/ruby/internal/intern/load.h @@ -546,12 +587,12 @@ constants.o: $(hdrdir)/ruby/internal/memory.h constants.o: $(hdrdir)/ruby/internal/method.h constants.o: $(hdrdir)/ruby/internal/module.h constants.o: $(hdrdir)/ruby/internal/newobj.h -constants.o: $(hdrdir)/ruby/internal/rgengc.h constants.o: $(hdrdir)/ruby/internal/scan_args.h constants.o: $(hdrdir)/ruby/internal/special_consts.h constants.o: $(hdrdir)/ruby/internal/static_assert.h constants.o: $(hdrdir)/ruby/internal/stdalign.h constants.o: $(hdrdir)/ruby/internal/stdbool.h +constants.o: $(hdrdir)/ruby/internal/stdckdint.h constants.o: $(hdrdir)/ruby/internal/symbol.h constants.o: $(hdrdir)/ruby/internal/value.h constants.o: $(hdrdir)/ruby/internal/value_type.h @@ -566,28 +607,47 @@ constants.o: $(hdrdir)/ruby/ruby.h constants.o: $(hdrdir)/ruby/st.h constants.o: $(hdrdir)/ruby/subst.h constants.o: $(hdrdir)/ruby/thread.h +constants.o: $(hdrdir)/ruby/thread_native.h constants.o: $(hdrdir)/ruby/util.h +constants.o: $(hdrdir)/ruby/version.h +constants.o: $(top_srcdir)/ccan/check_type/check_type.h +constants.o: $(top_srcdir)/ccan/container_of/container_of.h +constants.o: $(top_srcdir)/ccan/list/list.h +constants.o: $(top_srcdir)/ccan/str/str.h constants.o: $(top_srcdir)/internal.h constants.o: $(top_srcdir)/internal/array.h +constants.o: $(top_srcdir)/internal/basic_operators.h constants.o: $(top_srcdir)/internal/compilers.h constants.o: $(top_srcdir)/internal/error.h constants.o: $(top_srcdir)/internal/gc.h +constants.o: $(top_srcdir)/internal/imemo.h constants.o: $(top_srcdir)/internal/io.h +constants.o: $(top_srcdir)/internal/sanitizers.h constants.o: $(top_srcdir)/internal/serial.h constants.o: $(top_srcdir)/internal/static_assert.h constants.o: $(top_srcdir)/internal/string.h constants.o: $(top_srcdir)/internal/thread.h constants.o: $(top_srcdir)/internal/vm.h constants.o: $(top_srcdir)/internal/warnings.h +constants.o: $(top_srcdir)/method.h +constants.o: $(top_srcdir)/node.h +constants.o: $(top_srcdir)/ruby_assert.h +constants.o: $(top_srcdir)/ruby_atomic.h +constants.o: $(top_srcdir)/rubyparser.h +constants.o: $(top_srcdir)/shape.h +constants.o: $(top_srcdir)/thread_pthread.h +constants.o: $(top_srcdir)/vm_core.h +constants.o: $(top_srcdir)/vm_opts.h constants.o: constants.c constants.o: constdefs.c constants.o: constdefs.h constants.o: rubysocket.h constants.o: sockport.h +constants.o: {$(VPATH)}id.h ifaddr.o: $(RUBY_EXTCONF_H) ifaddr.o: $(arch_hdrdir)/ruby/config.h -ifaddr.o: $(hdrdir)/ruby.h ifaddr.o: $(hdrdir)/ruby/assert.h +ifaddr.o: $(hdrdir)/ruby/atomic.h ifaddr.o: $(hdrdir)/ruby/backward.h ifaddr.o: $(hdrdir)/ruby/backward/2/assume.h ifaddr.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -602,6 +662,7 @@ ifaddr.o: $(hdrdir)/ruby/defines.h ifaddr.o: $(hdrdir)/ruby/encoding.h ifaddr.o: $(hdrdir)/ruby/fiber/scheduler.h ifaddr.o: $(hdrdir)/ruby/intern.h +ifaddr.o: $(hdrdir)/ruby/internal/abi.h ifaddr.o: $(hdrdir)/ruby/internal/anyargs.h ifaddr.o: $(hdrdir)/ruby/internal/arithmetic.h ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -639,6 +700,7 @@ ifaddr.o: $(hdrdir)/ruby/internal/attr/noexcept.h ifaddr.o: $(hdrdir)/ruby/internal/attr/noinline.h ifaddr.o: $(hdrdir)/ruby/internal/attr/nonnull.h ifaddr.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ifaddr.o: $(hdrdir)/ruby/internal/attr/pure.h ifaddr.o: $(hdrdir)/ruby/internal/attr/restrict.h ifaddr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -707,7 +769,6 @@ ifaddr.o: $(hdrdir)/ruby/internal/intern/enumerator.h ifaddr.o: $(hdrdir)/ruby/internal/intern/error.h ifaddr.o: $(hdrdir)/ruby/internal/intern/eval.h ifaddr.o: $(hdrdir)/ruby/internal/intern/file.h -ifaddr.o: $(hdrdir)/ruby/internal/intern/gc.h ifaddr.o: $(hdrdir)/ruby/internal/intern/hash.h ifaddr.o: $(hdrdir)/ruby/internal/intern/io.h ifaddr.o: $(hdrdir)/ruby/internal/intern/load.h @@ -738,12 +799,12 @@ ifaddr.o: $(hdrdir)/ruby/internal/memory.h ifaddr.o: $(hdrdir)/ruby/internal/method.h ifaddr.o: $(hdrdir)/ruby/internal/module.h ifaddr.o: $(hdrdir)/ruby/internal/newobj.h -ifaddr.o: $(hdrdir)/ruby/internal/rgengc.h ifaddr.o: $(hdrdir)/ruby/internal/scan_args.h ifaddr.o: $(hdrdir)/ruby/internal/special_consts.h ifaddr.o: $(hdrdir)/ruby/internal/static_assert.h ifaddr.o: $(hdrdir)/ruby/internal/stdalign.h ifaddr.o: $(hdrdir)/ruby/internal/stdbool.h +ifaddr.o: $(hdrdir)/ruby/internal/stdckdint.h ifaddr.o: $(hdrdir)/ruby/internal/symbol.h ifaddr.o: $(hdrdir)/ruby/internal/value.h ifaddr.o: $(hdrdir)/ruby/internal/value_type.h @@ -758,27 +819,46 @@ ifaddr.o: $(hdrdir)/ruby/ruby.h ifaddr.o: $(hdrdir)/ruby/st.h ifaddr.o: $(hdrdir)/ruby/subst.h ifaddr.o: $(hdrdir)/ruby/thread.h +ifaddr.o: $(hdrdir)/ruby/thread_native.h ifaddr.o: $(hdrdir)/ruby/util.h +ifaddr.o: $(hdrdir)/ruby/version.h +ifaddr.o: $(top_srcdir)/ccan/check_type/check_type.h +ifaddr.o: $(top_srcdir)/ccan/container_of/container_of.h +ifaddr.o: $(top_srcdir)/ccan/list/list.h +ifaddr.o: $(top_srcdir)/ccan/str/str.h ifaddr.o: $(top_srcdir)/internal.h ifaddr.o: $(top_srcdir)/internal/array.h +ifaddr.o: $(top_srcdir)/internal/basic_operators.h ifaddr.o: $(top_srcdir)/internal/compilers.h ifaddr.o: $(top_srcdir)/internal/error.h ifaddr.o: $(top_srcdir)/internal/gc.h +ifaddr.o: $(top_srcdir)/internal/imemo.h ifaddr.o: $(top_srcdir)/internal/io.h +ifaddr.o: $(top_srcdir)/internal/sanitizers.h ifaddr.o: $(top_srcdir)/internal/serial.h ifaddr.o: $(top_srcdir)/internal/static_assert.h ifaddr.o: $(top_srcdir)/internal/string.h ifaddr.o: $(top_srcdir)/internal/thread.h ifaddr.o: $(top_srcdir)/internal/vm.h ifaddr.o: $(top_srcdir)/internal/warnings.h +ifaddr.o: $(top_srcdir)/method.h +ifaddr.o: $(top_srcdir)/node.h +ifaddr.o: $(top_srcdir)/ruby_assert.h +ifaddr.o: $(top_srcdir)/ruby_atomic.h +ifaddr.o: $(top_srcdir)/rubyparser.h +ifaddr.o: $(top_srcdir)/shape.h +ifaddr.o: $(top_srcdir)/thread_pthread.h +ifaddr.o: $(top_srcdir)/vm_core.h +ifaddr.o: $(top_srcdir)/vm_opts.h ifaddr.o: constdefs.h ifaddr.o: ifaddr.c ifaddr.o: rubysocket.h ifaddr.o: sockport.h +ifaddr.o: {$(VPATH)}id.h init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h -init.o: $(hdrdir)/ruby.h init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/atomic.h init.o: $(hdrdir)/ruby/backward.h init.o: $(hdrdir)/ruby/backward/2/assume.h init.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -793,6 +873,7 @@ init.o: $(hdrdir)/ruby/defines.h init.o: $(hdrdir)/ruby/encoding.h init.o: $(hdrdir)/ruby/fiber/scheduler.h init.o: $(hdrdir)/ruby/intern.h +init.o: $(hdrdir)/ruby/internal/abi.h init.o: $(hdrdir)/ruby/internal/anyargs.h init.o: $(hdrdir)/ruby/internal/arithmetic.h init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -830,6 +911,7 @@ init.o: $(hdrdir)/ruby/internal/attr/noexcept.h init.o: $(hdrdir)/ruby/internal/attr/noinline.h init.o: $(hdrdir)/ruby/internal/attr/nonnull.h init.o: $(hdrdir)/ruby/internal/attr/noreturn.h +init.o: $(hdrdir)/ruby/internal/attr/packed_struct.h init.o: $(hdrdir)/ruby/internal/attr/pure.h init.o: $(hdrdir)/ruby/internal/attr/restrict.h init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -898,7 +980,6 @@ init.o: $(hdrdir)/ruby/internal/intern/enumerator.h init.o: $(hdrdir)/ruby/internal/intern/error.h init.o: $(hdrdir)/ruby/internal/intern/eval.h init.o: $(hdrdir)/ruby/internal/intern/file.h -init.o: $(hdrdir)/ruby/internal/intern/gc.h init.o: $(hdrdir)/ruby/internal/intern/hash.h init.o: $(hdrdir)/ruby/internal/intern/io.h init.o: $(hdrdir)/ruby/internal/intern/load.h @@ -929,12 +1010,12 @@ init.o: $(hdrdir)/ruby/internal/memory.h init.o: $(hdrdir)/ruby/internal/method.h init.o: $(hdrdir)/ruby/internal/module.h init.o: $(hdrdir)/ruby/internal/newobj.h -init.o: $(hdrdir)/ruby/internal/rgengc.h init.o: $(hdrdir)/ruby/internal/scan_args.h init.o: $(hdrdir)/ruby/internal/special_consts.h init.o: $(hdrdir)/ruby/internal/static_assert.h init.o: $(hdrdir)/ruby/internal/stdalign.h init.o: $(hdrdir)/ruby/internal/stdbool.h +init.o: $(hdrdir)/ruby/internal/stdckdint.h init.o: $(hdrdir)/ruby/internal/symbol.h init.o: $(hdrdir)/ruby/internal/value.h init.o: $(hdrdir)/ruby/internal/value_type.h @@ -949,27 +1030,46 @@ init.o: $(hdrdir)/ruby/ruby.h init.o: $(hdrdir)/ruby/st.h init.o: $(hdrdir)/ruby/subst.h init.o: $(hdrdir)/ruby/thread.h +init.o: $(hdrdir)/ruby/thread_native.h init.o: $(hdrdir)/ruby/util.h +init.o: $(hdrdir)/ruby/version.h +init.o: $(top_srcdir)/ccan/check_type/check_type.h +init.o: $(top_srcdir)/ccan/container_of/container_of.h +init.o: $(top_srcdir)/ccan/list/list.h +init.o: $(top_srcdir)/ccan/str/str.h init.o: $(top_srcdir)/internal.h init.o: $(top_srcdir)/internal/array.h +init.o: $(top_srcdir)/internal/basic_operators.h init.o: $(top_srcdir)/internal/compilers.h init.o: $(top_srcdir)/internal/error.h init.o: $(top_srcdir)/internal/gc.h +init.o: $(top_srcdir)/internal/imemo.h init.o: $(top_srcdir)/internal/io.h +init.o: $(top_srcdir)/internal/sanitizers.h init.o: $(top_srcdir)/internal/serial.h init.o: $(top_srcdir)/internal/static_assert.h init.o: $(top_srcdir)/internal/string.h init.o: $(top_srcdir)/internal/thread.h init.o: $(top_srcdir)/internal/vm.h init.o: $(top_srcdir)/internal/warnings.h +init.o: $(top_srcdir)/method.h +init.o: $(top_srcdir)/node.h +init.o: $(top_srcdir)/ruby_assert.h +init.o: $(top_srcdir)/ruby_atomic.h +init.o: $(top_srcdir)/rubyparser.h +init.o: $(top_srcdir)/shape.h +init.o: $(top_srcdir)/thread_pthread.h +init.o: $(top_srcdir)/vm_core.h +init.o: $(top_srcdir)/vm_opts.h init.o: constdefs.h init.o: init.c init.o: rubysocket.h init.o: sockport.h +init.o: {$(VPATH)}id.h ipsocket.o: $(RUBY_EXTCONF_H) ipsocket.o: $(arch_hdrdir)/ruby/config.h -ipsocket.o: $(hdrdir)/ruby.h ipsocket.o: $(hdrdir)/ruby/assert.h +ipsocket.o: $(hdrdir)/ruby/atomic.h ipsocket.o: $(hdrdir)/ruby/backward.h ipsocket.o: $(hdrdir)/ruby/backward/2/assume.h ipsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -984,6 +1084,7 @@ ipsocket.o: $(hdrdir)/ruby/defines.h ipsocket.o: $(hdrdir)/ruby/encoding.h ipsocket.o: $(hdrdir)/ruby/fiber/scheduler.h ipsocket.o: $(hdrdir)/ruby/intern.h +ipsocket.o: $(hdrdir)/ruby/internal/abi.h ipsocket.o: $(hdrdir)/ruby/internal/anyargs.h ipsocket.o: $(hdrdir)/ruby/internal/arithmetic.h ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1021,6 +1122,7 @@ ipsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h ipsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h ipsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h ipsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h ipsocket.o: $(hdrdir)/ruby/internal/attr/pure.h ipsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h ipsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1089,7 +1191,6 @@ ipsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h ipsocket.o: $(hdrdir)/ruby/internal/intern/error.h ipsocket.o: $(hdrdir)/ruby/internal/intern/eval.h ipsocket.o: $(hdrdir)/ruby/internal/intern/file.h -ipsocket.o: $(hdrdir)/ruby/internal/intern/gc.h ipsocket.o: $(hdrdir)/ruby/internal/intern/hash.h ipsocket.o: $(hdrdir)/ruby/internal/intern/io.h ipsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1120,12 +1221,12 @@ ipsocket.o: $(hdrdir)/ruby/internal/memory.h ipsocket.o: $(hdrdir)/ruby/internal/method.h ipsocket.o: $(hdrdir)/ruby/internal/module.h ipsocket.o: $(hdrdir)/ruby/internal/newobj.h -ipsocket.o: $(hdrdir)/ruby/internal/rgengc.h ipsocket.o: $(hdrdir)/ruby/internal/scan_args.h ipsocket.o: $(hdrdir)/ruby/internal/special_consts.h ipsocket.o: $(hdrdir)/ruby/internal/static_assert.h ipsocket.o: $(hdrdir)/ruby/internal/stdalign.h ipsocket.o: $(hdrdir)/ruby/internal/stdbool.h +ipsocket.o: $(hdrdir)/ruby/internal/stdckdint.h ipsocket.o: $(hdrdir)/ruby/internal/symbol.h ipsocket.o: $(hdrdir)/ruby/internal/value.h ipsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -1140,27 +1241,46 @@ ipsocket.o: $(hdrdir)/ruby/ruby.h ipsocket.o: $(hdrdir)/ruby/st.h ipsocket.o: $(hdrdir)/ruby/subst.h ipsocket.o: $(hdrdir)/ruby/thread.h +ipsocket.o: $(hdrdir)/ruby/thread_native.h ipsocket.o: $(hdrdir)/ruby/util.h +ipsocket.o: $(hdrdir)/ruby/version.h +ipsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +ipsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +ipsocket.o: $(top_srcdir)/ccan/list/list.h +ipsocket.o: $(top_srcdir)/ccan/str/str.h ipsocket.o: $(top_srcdir)/internal.h ipsocket.o: $(top_srcdir)/internal/array.h +ipsocket.o: $(top_srcdir)/internal/basic_operators.h ipsocket.o: $(top_srcdir)/internal/compilers.h ipsocket.o: $(top_srcdir)/internal/error.h ipsocket.o: $(top_srcdir)/internal/gc.h +ipsocket.o: $(top_srcdir)/internal/imemo.h ipsocket.o: $(top_srcdir)/internal/io.h +ipsocket.o: $(top_srcdir)/internal/sanitizers.h ipsocket.o: $(top_srcdir)/internal/serial.h ipsocket.o: $(top_srcdir)/internal/static_assert.h ipsocket.o: $(top_srcdir)/internal/string.h ipsocket.o: $(top_srcdir)/internal/thread.h ipsocket.o: $(top_srcdir)/internal/vm.h ipsocket.o: $(top_srcdir)/internal/warnings.h +ipsocket.o: $(top_srcdir)/method.h +ipsocket.o: $(top_srcdir)/node.h +ipsocket.o: $(top_srcdir)/ruby_assert.h +ipsocket.o: $(top_srcdir)/ruby_atomic.h +ipsocket.o: $(top_srcdir)/rubyparser.h +ipsocket.o: $(top_srcdir)/shape.h +ipsocket.o: $(top_srcdir)/thread_pthread.h +ipsocket.o: $(top_srcdir)/vm_core.h +ipsocket.o: $(top_srcdir)/vm_opts.h ipsocket.o: constdefs.h ipsocket.o: ipsocket.c ipsocket.o: rubysocket.h ipsocket.o: sockport.h +ipsocket.o: {$(VPATH)}id.h option.o: $(RUBY_EXTCONF_H) option.o: $(arch_hdrdir)/ruby/config.h -option.o: $(hdrdir)/ruby.h option.o: $(hdrdir)/ruby/assert.h +option.o: $(hdrdir)/ruby/atomic.h option.o: $(hdrdir)/ruby/backward.h option.o: $(hdrdir)/ruby/backward/2/assume.h option.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1175,6 +1295,7 @@ option.o: $(hdrdir)/ruby/defines.h option.o: $(hdrdir)/ruby/encoding.h option.o: $(hdrdir)/ruby/fiber/scheduler.h option.o: $(hdrdir)/ruby/intern.h +option.o: $(hdrdir)/ruby/internal/abi.h option.o: $(hdrdir)/ruby/internal/anyargs.h option.o: $(hdrdir)/ruby/internal/arithmetic.h option.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1212,6 +1333,7 @@ option.o: $(hdrdir)/ruby/internal/attr/noexcept.h option.o: $(hdrdir)/ruby/internal/attr/noinline.h option.o: $(hdrdir)/ruby/internal/attr/nonnull.h option.o: $(hdrdir)/ruby/internal/attr/noreturn.h +option.o: $(hdrdir)/ruby/internal/attr/packed_struct.h option.o: $(hdrdir)/ruby/internal/attr/pure.h option.o: $(hdrdir)/ruby/internal/attr/restrict.h option.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1280,7 +1402,6 @@ option.o: $(hdrdir)/ruby/internal/intern/enumerator.h option.o: $(hdrdir)/ruby/internal/intern/error.h option.o: $(hdrdir)/ruby/internal/intern/eval.h option.o: $(hdrdir)/ruby/internal/intern/file.h -option.o: $(hdrdir)/ruby/internal/intern/gc.h option.o: $(hdrdir)/ruby/internal/intern/hash.h option.o: $(hdrdir)/ruby/internal/intern/io.h option.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1311,12 +1432,12 @@ option.o: $(hdrdir)/ruby/internal/memory.h option.o: $(hdrdir)/ruby/internal/method.h option.o: $(hdrdir)/ruby/internal/module.h option.o: $(hdrdir)/ruby/internal/newobj.h -option.o: $(hdrdir)/ruby/internal/rgengc.h option.o: $(hdrdir)/ruby/internal/scan_args.h option.o: $(hdrdir)/ruby/internal/special_consts.h option.o: $(hdrdir)/ruby/internal/static_assert.h option.o: $(hdrdir)/ruby/internal/stdalign.h option.o: $(hdrdir)/ruby/internal/stdbool.h +option.o: $(hdrdir)/ruby/internal/stdckdint.h option.o: $(hdrdir)/ruby/internal/symbol.h option.o: $(hdrdir)/ruby/internal/value.h option.o: $(hdrdir)/ruby/internal/value_type.h @@ -1331,27 +1452,46 @@ option.o: $(hdrdir)/ruby/ruby.h option.o: $(hdrdir)/ruby/st.h option.o: $(hdrdir)/ruby/subst.h option.o: $(hdrdir)/ruby/thread.h +option.o: $(hdrdir)/ruby/thread_native.h option.o: $(hdrdir)/ruby/util.h +option.o: $(hdrdir)/ruby/version.h +option.o: $(top_srcdir)/ccan/check_type/check_type.h +option.o: $(top_srcdir)/ccan/container_of/container_of.h +option.o: $(top_srcdir)/ccan/list/list.h +option.o: $(top_srcdir)/ccan/str/str.h option.o: $(top_srcdir)/internal.h option.o: $(top_srcdir)/internal/array.h +option.o: $(top_srcdir)/internal/basic_operators.h option.o: $(top_srcdir)/internal/compilers.h option.o: $(top_srcdir)/internal/error.h option.o: $(top_srcdir)/internal/gc.h +option.o: $(top_srcdir)/internal/imemo.h option.o: $(top_srcdir)/internal/io.h +option.o: $(top_srcdir)/internal/sanitizers.h option.o: $(top_srcdir)/internal/serial.h option.o: $(top_srcdir)/internal/static_assert.h option.o: $(top_srcdir)/internal/string.h option.o: $(top_srcdir)/internal/thread.h option.o: $(top_srcdir)/internal/vm.h option.o: $(top_srcdir)/internal/warnings.h +option.o: $(top_srcdir)/method.h +option.o: $(top_srcdir)/node.h +option.o: $(top_srcdir)/ruby_assert.h +option.o: $(top_srcdir)/ruby_atomic.h +option.o: $(top_srcdir)/rubyparser.h +option.o: $(top_srcdir)/shape.h +option.o: $(top_srcdir)/thread_pthread.h +option.o: $(top_srcdir)/vm_core.h +option.o: $(top_srcdir)/vm_opts.h option.o: constdefs.h option.o: option.c option.o: rubysocket.h option.o: sockport.h +option.o: {$(VPATH)}id.h raddrinfo.o: $(RUBY_EXTCONF_H) raddrinfo.o: $(arch_hdrdir)/ruby/config.h -raddrinfo.o: $(hdrdir)/ruby.h raddrinfo.o: $(hdrdir)/ruby/assert.h +raddrinfo.o: $(hdrdir)/ruby/atomic.h raddrinfo.o: $(hdrdir)/ruby/backward.h raddrinfo.o: $(hdrdir)/ruby/backward/2/assume.h raddrinfo.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1366,6 +1506,7 @@ raddrinfo.o: $(hdrdir)/ruby/defines.h raddrinfo.o: $(hdrdir)/ruby/encoding.h raddrinfo.o: $(hdrdir)/ruby/fiber/scheduler.h raddrinfo.o: $(hdrdir)/ruby/intern.h +raddrinfo.o: $(hdrdir)/ruby/internal/abi.h raddrinfo.o: $(hdrdir)/ruby/internal/anyargs.h raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic.h raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1403,6 +1544,7 @@ raddrinfo.o: $(hdrdir)/ruby/internal/attr/noexcept.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/noinline.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/nonnull.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/noreturn.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/packed_struct.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/pure.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/restrict.h raddrinfo.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1471,7 +1613,6 @@ raddrinfo.o: $(hdrdir)/ruby/internal/intern/enumerator.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/error.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/eval.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/file.h -raddrinfo.o: $(hdrdir)/ruby/internal/intern/gc.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/hash.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/io.h raddrinfo.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1502,12 +1643,12 @@ raddrinfo.o: $(hdrdir)/ruby/internal/memory.h raddrinfo.o: $(hdrdir)/ruby/internal/method.h raddrinfo.o: $(hdrdir)/ruby/internal/module.h raddrinfo.o: $(hdrdir)/ruby/internal/newobj.h -raddrinfo.o: $(hdrdir)/ruby/internal/rgengc.h raddrinfo.o: $(hdrdir)/ruby/internal/scan_args.h raddrinfo.o: $(hdrdir)/ruby/internal/special_consts.h raddrinfo.o: $(hdrdir)/ruby/internal/static_assert.h raddrinfo.o: $(hdrdir)/ruby/internal/stdalign.h raddrinfo.o: $(hdrdir)/ruby/internal/stdbool.h +raddrinfo.o: $(hdrdir)/ruby/internal/stdckdint.h raddrinfo.o: $(hdrdir)/ruby/internal/symbol.h raddrinfo.o: $(hdrdir)/ruby/internal/value.h raddrinfo.o: $(hdrdir)/ruby/internal/value_type.h @@ -1522,27 +1663,46 @@ raddrinfo.o: $(hdrdir)/ruby/ruby.h raddrinfo.o: $(hdrdir)/ruby/st.h raddrinfo.o: $(hdrdir)/ruby/subst.h raddrinfo.o: $(hdrdir)/ruby/thread.h +raddrinfo.o: $(hdrdir)/ruby/thread_native.h raddrinfo.o: $(hdrdir)/ruby/util.h +raddrinfo.o: $(hdrdir)/ruby/version.h +raddrinfo.o: $(top_srcdir)/ccan/check_type/check_type.h +raddrinfo.o: $(top_srcdir)/ccan/container_of/container_of.h +raddrinfo.o: $(top_srcdir)/ccan/list/list.h +raddrinfo.o: $(top_srcdir)/ccan/str/str.h raddrinfo.o: $(top_srcdir)/internal.h raddrinfo.o: $(top_srcdir)/internal/array.h +raddrinfo.o: $(top_srcdir)/internal/basic_operators.h raddrinfo.o: $(top_srcdir)/internal/compilers.h raddrinfo.o: $(top_srcdir)/internal/error.h raddrinfo.o: $(top_srcdir)/internal/gc.h +raddrinfo.o: $(top_srcdir)/internal/imemo.h raddrinfo.o: $(top_srcdir)/internal/io.h +raddrinfo.o: $(top_srcdir)/internal/sanitizers.h raddrinfo.o: $(top_srcdir)/internal/serial.h raddrinfo.o: $(top_srcdir)/internal/static_assert.h raddrinfo.o: $(top_srcdir)/internal/string.h raddrinfo.o: $(top_srcdir)/internal/thread.h raddrinfo.o: $(top_srcdir)/internal/vm.h raddrinfo.o: $(top_srcdir)/internal/warnings.h +raddrinfo.o: $(top_srcdir)/method.h +raddrinfo.o: $(top_srcdir)/node.h +raddrinfo.o: $(top_srcdir)/ruby_assert.h +raddrinfo.o: $(top_srcdir)/ruby_atomic.h +raddrinfo.o: $(top_srcdir)/rubyparser.h +raddrinfo.o: $(top_srcdir)/shape.h +raddrinfo.o: $(top_srcdir)/thread_pthread.h +raddrinfo.o: $(top_srcdir)/vm_core.h +raddrinfo.o: $(top_srcdir)/vm_opts.h raddrinfo.o: constdefs.h raddrinfo.o: raddrinfo.c raddrinfo.o: rubysocket.h raddrinfo.o: sockport.h +raddrinfo.o: {$(VPATH)}id.h socket.o: $(RUBY_EXTCONF_H) socket.o: $(arch_hdrdir)/ruby/config.h -socket.o: $(hdrdir)/ruby.h socket.o: $(hdrdir)/ruby/assert.h +socket.o: $(hdrdir)/ruby/atomic.h socket.o: $(hdrdir)/ruby/backward.h socket.o: $(hdrdir)/ruby/backward/2/assume.h socket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1557,6 +1717,7 @@ socket.o: $(hdrdir)/ruby/defines.h socket.o: $(hdrdir)/ruby/encoding.h socket.o: $(hdrdir)/ruby/fiber/scheduler.h socket.o: $(hdrdir)/ruby/intern.h +socket.o: $(hdrdir)/ruby/internal/abi.h socket.o: $(hdrdir)/ruby/internal/anyargs.h socket.o: $(hdrdir)/ruby/internal/arithmetic.h socket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1594,6 +1755,7 @@ socket.o: $(hdrdir)/ruby/internal/attr/noexcept.h socket.o: $(hdrdir)/ruby/internal/attr/noinline.h socket.o: $(hdrdir)/ruby/internal/attr/nonnull.h socket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +socket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h socket.o: $(hdrdir)/ruby/internal/attr/pure.h socket.o: $(hdrdir)/ruby/internal/attr/restrict.h socket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1662,7 +1824,6 @@ socket.o: $(hdrdir)/ruby/internal/intern/enumerator.h socket.o: $(hdrdir)/ruby/internal/intern/error.h socket.o: $(hdrdir)/ruby/internal/intern/eval.h socket.o: $(hdrdir)/ruby/internal/intern/file.h -socket.o: $(hdrdir)/ruby/internal/intern/gc.h socket.o: $(hdrdir)/ruby/internal/intern/hash.h socket.o: $(hdrdir)/ruby/internal/intern/io.h socket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1693,12 +1854,12 @@ socket.o: $(hdrdir)/ruby/internal/memory.h socket.o: $(hdrdir)/ruby/internal/method.h socket.o: $(hdrdir)/ruby/internal/module.h socket.o: $(hdrdir)/ruby/internal/newobj.h -socket.o: $(hdrdir)/ruby/internal/rgengc.h socket.o: $(hdrdir)/ruby/internal/scan_args.h socket.o: $(hdrdir)/ruby/internal/special_consts.h socket.o: $(hdrdir)/ruby/internal/static_assert.h socket.o: $(hdrdir)/ruby/internal/stdalign.h socket.o: $(hdrdir)/ruby/internal/stdbool.h +socket.o: $(hdrdir)/ruby/internal/stdckdint.h socket.o: $(hdrdir)/ruby/internal/symbol.h socket.o: $(hdrdir)/ruby/internal/value.h socket.o: $(hdrdir)/ruby/internal/value_type.h @@ -1713,27 +1874,46 @@ socket.o: $(hdrdir)/ruby/ruby.h socket.o: $(hdrdir)/ruby/st.h socket.o: $(hdrdir)/ruby/subst.h socket.o: $(hdrdir)/ruby/thread.h +socket.o: $(hdrdir)/ruby/thread_native.h socket.o: $(hdrdir)/ruby/util.h +socket.o: $(hdrdir)/ruby/version.h +socket.o: $(top_srcdir)/ccan/check_type/check_type.h +socket.o: $(top_srcdir)/ccan/container_of/container_of.h +socket.o: $(top_srcdir)/ccan/list/list.h +socket.o: $(top_srcdir)/ccan/str/str.h socket.o: $(top_srcdir)/internal.h socket.o: $(top_srcdir)/internal/array.h +socket.o: $(top_srcdir)/internal/basic_operators.h socket.o: $(top_srcdir)/internal/compilers.h socket.o: $(top_srcdir)/internal/error.h socket.o: $(top_srcdir)/internal/gc.h +socket.o: $(top_srcdir)/internal/imemo.h socket.o: $(top_srcdir)/internal/io.h +socket.o: $(top_srcdir)/internal/sanitizers.h socket.o: $(top_srcdir)/internal/serial.h socket.o: $(top_srcdir)/internal/static_assert.h socket.o: $(top_srcdir)/internal/string.h socket.o: $(top_srcdir)/internal/thread.h socket.o: $(top_srcdir)/internal/vm.h socket.o: $(top_srcdir)/internal/warnings.h +socket.o: $(top_srcdir)/method.h +socket.o: $(top_srcdir)/node.h +socket.o: $(top_srcdir)/ruby_assert.h +socket.o: $(top_srcdir)/ruby_atomic.h +socket.o: $(top_srcdir)/rubyparser.h +socket.o: $(top_srcdir)/shape.h +socket.o: $(top_srcdir)/thread_pthread.h +socket.o: $(top_srcdir)/vm_core.h +socket.o: $(top_srcdir)/vm_opts.h socket.o: constdefs.h socket.o: rubysocket.h socket.o: socket.c socket.o: sockport.h +socket.o: {$(VPATH)}id.h sockssocket.o: $(RUBY_EXTCONF_H) sockssocket.o: $(arch_hdrdir)/ruby/config.h -sockssocket.o: $(hdrdir)/ruby.h sockssocket.o: $(hdrdir)/ruby/assert.h +sockssocket.o: $(hdrdir)/ruby/atomic.h sockssocket.o: $(hdrdir)/ruby/backward.h sockssocket.o: $(hdrdir)/ruby/backward/2/assume.h sockssocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1748,6 +1928,7 @@ sockssocket.o: $(hdrdir)/ruby/defines.h sockssocket.o: $(hdrdir)/ruby/encoding.h sockssocket.o: $(hdrdir)/ruby/fiber/scheduler.h sockssocket.o: $(hdrdir)/ruby/intern.h +sockssocket.o: $(hdrdir)/ruby/internal/abi.h sockssocket.o: $(hdrdir)/ruby/internal/anyargs.h sockssocket.o: $(hdrdir)/ruby/internal/arithmetic.h sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1785,6 +1966,7 @@ sockssocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h sockssocket.o: $(hdrdir)/ruby/internal/attr/noinline.h sockssocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h sockssocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h sockssocket.o: $(hdrdir)/ruby/internal/attr/pure.h sockssocket.o: $(hdrdir)/ruby/internal/attr/restrict.h sockssocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1853,7 +2035,6 @@ sockssocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h sockssocket.o: $(hdrdir)/ruby/internal/intern/error.h sockssocket.o: $(hdrdir)/ruby/internal/intern/eval.h sockssocket.o: $(hdrdir)/ruby/internal/intern/file.h -sockssocket.o: $(hdrdir)/ruby/internal/intern/gc.h sockssocket.o: $(hdrdir)/ruby/internal/intern/hash.h sockssocket.o: $(hdrdir)/ruby/internal/intern/io.h sockssocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1884,12 +2065,12 @@ sockssocket.o: $(hdrdir)/ruby/internal/memory.h sockssocket.o: $(hdrdir)/ruby/internal/method.h sockssocket.o: $(hdrdir)/ruby/internal/module.h sockssocket.o: $(hdrdir)/ruby/internal/newobj.h -sockssocket.o: $(hdrdir)/ruby/internal/rgengc.h sockssocket.o: $(hdrdir)/ruby/internal/scan_args.h sockssocket.o: $(hdrdir)/ruby/internal/special_consts.h sockssocket.o: $(hdrdir)/ruby/internal/static_assert.h sockssocket.o: $(hdrdir)/ruby/internal/stdalign.h sockssocket.o: $(hdrdir)/ruby/internal/stdbool.h +sockssocket.o: $(hdrdir)/ruby/internal/stdckdint.h sockssocket.o: $(hdrdir)/ruby/internal/symbol.h sockssocket.o: $(hdrdir)/ruby/internal/value.h sockssocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -1904,27 +2085,46 @@ sockssocket.o: $(hdrdir)/ruby/ruby.h sockssocket.o: $(hdrdir)/ruby/st.h sockssocket.o: $(hdrdir)/ruby/subst.h sockssocket.o: $(hdrdir)/ruby/thread.h +sockssocket.o: $(hdrdir)/ruby/thread_native.h sockssocket.o: $(hdrdir)/ruby/util.h +sockssocket.o: $(hdrdir)/ruby/version.h +sockssocket.o: $(top_srcdir)/ccan/check_type/check_type.h +sockssocket.o: $(top_srcdir)/ccan/container_of/container_of.h +sockssocket.o: $(top_srcdir)/ccan/list/list.h +sockssocket.o: $(top_srcdir)/ccan/str/str.h sockssocket.o: $(top_srcdir)/internal.h sockssocket.o: $(top_srcdir)/internal/array.h +sockssocket.o: $(top_srcdir)/internal/basic_operators.h sockssocket.o: $(top_srcdir)/internal/compilers.h sockssocket.o: $(top_srcdir)/internal/error.h sockssocket.o: $(top_srcdir)/internal/gc.h +sockssocket.o: $(top_srcdir)/internal/imemo.h sockssocket.o: $(top_srcdir)/internal/io.h +sockssocket.o: $(top_srcdir)/internal/sanitizers.h sockssocket.o: $(top_srcdir)/internal/serial.h sockssocket.o: $(top_srcdir)/internal/static_assert.h sockssocket.o: $(top_srcdir)/internal/string.h sockssocket.o: $(top_srcdir)/internal/thread.h sockssocket.o: $(top_srcdir)/internal/vm.h sockssocket.o: $(top_srcdir)/internal/warnings.h +sockssocket.o: $(top_srcdir)/method.h +sockssocket.o: $(top_srcdir)/node.h +sockssocket.o: $(top_srcdir)/ruby_assert.h +sockssocket.o: $(top_srcdir)/ruby_atomic.h +sockssocket.o: $(top_srcdir)/rubyparser.h +sockssocket.o: $(top_srcdir)/shape.h +sockssocket.o: $(top_srcdir)/thread_pthread.h +sockssocket.o: $(top_srcdir)/vm_core.h +sockssocket.o: $(top_srcdir)/vm_opts.h sockssocket.o: constdefs.h sockssocket.o: rubysocket.h sockssocket.o: sockport.h sockssocket.o: sockssocket.c +sockssocket.o: {$(VPATH)}id.h tcpserver.o: $(RUBY_EXTCONF_H) tcpserver.o: $(arch_hdrdir)/ruby/config.h -tcpserver.o: $(hdrdir)/ruby.h tcpserver.o: $(hdrdir)/ruby/assert.h +tcpserver.o: $(hdrdir)/ruby/atomic.h tcpserver.o: $(hdrdir)/ruby/backward.h tcpserver.o: $(hdrdir)/ruby/backward/2/assume.h tcpserver.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -1939,6 +2139,7 @@ tcpserver.o: $(hdrdir)/ruby/defines.h tcpserver.o: $(hdrdir)/ruby/encoding.h tcpserver.o: $(hdrdir)/ruby/fiber/scheduler.h tcpserver.o: $(hdrdir)/ruby/intern.h +tcpserver.o: $(hdrdir)/ruby/internal/abi.h tcpserver.o: $(hdrdir)/ruby/internal/anyargs.h tcpserver.o: $(hdrdir)/ruby/internal/arithmetic.h tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -1976,6 +2177,7 @@ tcpserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h tcpserver.o: $(hdrdir)/ruby/internal/attr/noinline.h tcpserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h tcpserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h tcpserver.o: $(hdrdir)/ruby/internal/attr/pure.h tcpserver.o: $(hdrdir)/ruby/internal/attr/restrict.h tcpserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2044,7 +2246,6 @@ tcpserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h tcpserver.o: $(hdrdir)/ruby/internal/intern/error.h tcpserver.o: $(hdrdir)/ruby/internal/intern/eval.h tcpserver.o: $(hdrdir)/ruby/internal/intern/file.h -tcpserver.o: $(hdrdir)/ruby/internal/intern/gc.h tcpserver.o: $(hdrdir)/ruby/internal/intern/hash.h tcpserver.o: $(hdrdir)/ruby/internal/intern/io.h tcpserver.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2075,12 +2276,12 @@ tcpserver.o: $(hdrdir)/ruby/internal/memory.h tcpserver.o: $(hdrdir)/ruby/internal/method.h tcpserver.o: $(hdrdir)/ruby/internal/module.h tcpserver.o: $(hdrdir)/ruby/internal/newobj.h -tcpserver.o: $(hdrdir)/ruby/internal/rgengc.h tcpserver.o: $(hdrdir)/ruby/internal/scan_args.h tcpserver.o: $(hdrdir)/ruby/internal/special_consts.h tcpserver.o: $(hdrdir)/ruby/internal/static_assert.h tcpserver.o: $(hdrdir)/ruby/internal/stdalign.h tcpserver.o: $(hdrdir)/ruby/internal/stdbool.h +tcpserver.o: $(hdrdir)/ruby/internal/stdckdint.h tcpserver.o: $(hdrdir)/ruby/internal/symbol.h tcpserver.o: $(hdrdir)/ruby/internal/value.h tcpserver.o: $(hdrdir)/ruby/internal/value_type.h @@ -2095,27 +2296,46 @@ tcpserver.o: $(hdrdir)/ruby/ruby.h tcpserver.o: $(hdrdir)/ruby/st.h tcpserver.o: $(hdrdir)/ruby/subst.h tcpserver.o: $(hdrdir)/ruby/thread.h +tcpserver.o: $(hdrdir)/ruby/thread_native.h tcpserver.o: $(hdrdir)/ruby/util.h +tcpserver.o: $(hdrdir)/ruby/version.h +tcpserver.o: $(top_srcdir)/ccan/check_type/check_type.h +tcpserver.o: $(top_srcdir)/ccan/container_of/container_of.h +tcpserver.o: $(top_srcdir)/ccan/list/list.h +tcpserver.o: $(top_srcdir)/ccan/str/str.h tcpserver.o: $(top_srcdir)/internal.h tcpserver.o: $(top_srcdir)/internal/array.h +tcpserver.o: $(top_srcdir)/internal/basic_operators.h tcpserver.o: $(top_srcdir)/internal/compilers.h tcpserver.o: $(top_srcdir)/internal/error.h tcpserver.o: $(top_srcdir)/internal/gc.h +tcpserver.o: $(top_srcdir)/internal/imemo.h tcpserver.o: $(top_srcdir)/internal/io.h +tcpserver.o: $(top_srcdir)/internal/sanitizers.h tcpserver.o: $(top_srcdir)/internal/serial.h tcpserver.o: $(top_srcdir)/internal/static_assert.h tcpserver.o: $(top_srcdir)/internal/string.h tcpserver.o: $(top_srcdir)/internal/thread.h tcpserver.o: $(top_srcdir)/internal/vm.h tcpserver.o: $(top_srcdir)/internal/warnings.h +tcpserver.o: $(top_srcdir)/method.h +tcpserver.o: $(top_srcdir)/node.h +tcpserver.o: $(top_srcdir)/ruby_assert.h +tcpserver.o: $(top_srcdir)/ruby_atomic.h +tcpserver.o: $(top_srcdir)/rubyparser.h +tcpserver.o: $(top_srcdir)/shape.h +tcpserver.o: $(top_srcdir)/thread_pthread.h +tcpserver.o: $(top_srcdir)/vm_core.h +tcpserver.o: $(top_srcdir)/vm_opts.h tcpserver.o: constdefs.h tcpserver.o: rubysocket.h tcpserver.o: sockport.h tcpserver.o: tcpserver.c +tcpserver.o: {$(VPATH)}id.h tcpsocket.o: $(RUBY_EXTCONF_H) tcpsocket.o: $(arch_hdrdir)/ruby/config.h -tcpsocket.o: $(hdrdir)/ruby.h tcpsocket.o: $(hdrdir)/ruby/assert.h +tcpsocket.o: $(hdrdir)/ruby/atomic.h tcpsocket.o: $(hdrdir)/ruby/backward.h tcpsocket.o: $(hdrdir)/ruby/backward/2/assume.h tcpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2130,6 +2350,7 @@ tcpsocket.o: $(hdrdir)/ruby/defines.h tcpsocket.o: $(hdrdir)/ruby/encoding.h tcpsocket.o: $(hdrdir)/ruby/fiber/scheduler.h tcpsocket.o: $(hdrdir)/ruby/intern.h +tcpsocket.o: $(hdrdir)/ruby/internal/abi.h tcpsocket.o: $(hdrdir)/ruby/internal/anyargs.h tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2167,6 +2388,7 @@ tcpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h tcpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2235,7 +2457,6 @@ tcpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/error.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/file.h -tcpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/io.h tcpsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2266,12 +2487,12 @@ tcpsocket.o: $(hdrdir)/ruby/internal/memory.h tcpsocket.o: $(hdrdir)/ruby/internal/method.h tcpsocket.o: $(hdrdir)/ruby/internal/module.h tcpsocket.o: $(hdrdir)/ruby/internal/newobj.h -tcpsocket.o: $(hdrdir)/ruby/internal/rgengc.h tcpsocket.o: $(hdrdir)/ruby/internal/scan_args.h tcpsocket.o: $(hdrdir)/ruby/internal/special_consts.h tcpsocket.o: $(hdrdir)/ruby/internal/static_assert.h tcpsocket.o: $(hdrdir)/ruby/internal/stdalign.h tcpsocket.o: $(hdrdir)/ruby/internal/stdbool.h +tcpsocket.o: $(hdrdir)/ruby/internal/stdckdint.h tcpsocket.o: $(hdrdir)/ruby/internal/symbol.h tcpsocket.o: $(hdrdir)/ruby/internal/value.h tcpsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -2286,27 +2507,46 @@ tcpsocket.o: $(hdrdir)/ruby/ruby.h tcpsocket.o: $(hdrdir)/ruby/st.h tcpsocket.o: $(hdrdir)/ruby/subst.h tcpsocket.o: $(hdrdir)/ruby/thread.h +tcpsocket.o: $(hdrdir)/ruby/thread_native.h tcpsocket.o: $(hdrdir)/ruby/util.h +tcpsocket.o: $(hdrdir)/ruby/version.h +tcpsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +tcpsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +tcpsocket.o: $(top_srcdir)/ccan/list/list.h +tcpsocket.o: $(top_srcdir)/ccan/str/str.h tcpsocket.o: $(top_srcdir)/internal.h tcpsocket.o: $(top_srcdir)/internal/array.h +tcpsocket.o: $(top_srcdir)/internal/basic_operators.h tcpsocket.o: $(top_srcdir)/internal/compilers.h tcpsocket.o: $(top_srcdir)/internal/error.h tcpsocket.o: $(top_srcdir)/internal/gc.h +tcpsocket.o: $(top_srcdir)/internal/imemo.h tcpsocket.o: $(top_srcdir)/internal/io.h +tcpsocket.o: $(top_srcdir)/internal/sanitizers.h tcpsocket.o: $(top_srcdir)/internal/serial.h tcpsocket.o: $(top_srcdir)/internal/static_assert.h tcpsocket.o: $(top_srcdir)/internal/string.h tcpsocket.o: $(top_srcdir)/internal/thread.h tcpsocket.o: $(top_srcdir)/internal/vm.h tcpsocket.o: $(top_srcdir)/internal/warnings.h +tcpsocket.o: $(top_srcdir)/method.h +tcpsocket.o: $(top_srcdir)/node.h +tcpsocket.o: $(top_srcdir)/ruby_assert.h +tcpsocket.o: $(top_srcdir)/ruby_atomic.h +tcpsocket.o: $(top_srcdir)/rubyparser.h +tcpsocket.o: $(top_srcdir)/shape.h +tcpsocket.o: $(top_srcdir)/thread_pthread.h +tcpsocket.o: $(top_srcdir)/vm_core.h +tcpsocket.o: $(top_srcdir)/vm_opts.h tcpsocket.o: constdefs.h tcpsocket.o: rubysocket.h tcpsocket.o: sockport.h tcpsocket.o: tcpsocket.c +tcpsocket.o: {$(VPATH)}id.h udpsocket.o: $(RUBY_EXTCONF_H) udpsocket.o: $(arch_hdrdir)/ruby/config.h -udpsocket.o: $(hdrdir)/ruby.h udpsocket.o: $(hdrdir)/ruby/assert.h +udpsocket.o: $(hdrdir)/ruby/atomic.h udpsocket.o: $(hdrdir)/ruby/backward.h udpsocket.o: $(hdrdir)/ruby/backward/2/assume.h udpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2321,6 +2561,7 @@ udpsocket.o: $(hdrdir)/ruby/defines.h udpsocket.o: $(hdrdir)/ruby/encoding.h udpsocket.o: $(hdrdir)/ruby/fiber/scheduler.h udpsocket.o: $(hdrdir)/ruby/intern.h +udpsocket.o: $(hdrdir)/ruby/internal/abi.h udpsocket.o: $(hdrdir)/ruby/internal/anyargs.h udpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2358,6 +2599,7 @@ udpsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h udpsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h udpsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h udpsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h udpsocket.o: $(hdrdir)/ruby/internal/attr/pure.h udpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h udpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2426,7 +2668,6 @@ udpsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h udpsocket.o: $(hdrdir)/ruby/internal/intern/error.h udpsocket.o: $(hdrdir)/ruby/internal/intern/eval.h udpsocket.o: $(hdrdir)/ruby/internal/intern/file.h -udpsocket.o: $(hdrdir)/ruby/internal/intern/gc.h udpsocket.o: $(hdrdir)/ruby/internal/intern/hash.h udpsocket.o: $(hdrdir)/ruby/internal/intern/io.h udpsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2457,12 +2698,12 @@ udpsocket.o: $(hdrdir)/ruby/internal/memory.h udpsocket.o: $(hdrdir)/ruby/internal/method.h udpsocket.o: $(hdrdir)/ruby/internal/module.h udpsocket.o: $(hdrdir)/ruby/internal/newobj.h -udpsocket.o: $(hdrdir)/ruby/internal/rgengc.h udpsocket.o: $(hdrdir)/ruby/internal/scan_args.h udpsocket.o: $(hdrdir)/ruby/internal/special_consts.h udpsocket.o: $(hdrdir)/ruby/internal/static_assert.h udpsocket.o: $(hdrdir)/ruby/internal/stdalign.h udpsocket.o: $(hdrdir)/ruby/internal/stdbool.h +udpsocket.o: $(hdrdir)/ruby/internal/stdckdint.h udpsocket.o: $(hdrdir)/ruby/internal/symbol.h udpsocket.o: $(hdrdir)/ruby/internal/value.h udpsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -2477,27 +2718,46 @@ udpsocket.o: $(hdrdir)/ruby/ruby.h udpsocket.o: $(hdrdir)/ruby/st.h udpsocket.o: $(hdrdir)/ruby/subst.h udpsocket.o: $(hdrdir)/ruby/thread.h +udpsocket.o: $(hdrdir)/ruby/thread_native.h udpsocket.o: $(hdrdir)/ruby/util.h +udpsocket.o: $(hdrdir)/ruby/version.h +udpsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +udpsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +udpsocket.o: $(top_srcdir)/ccan/list/list.h +udpsocket.o: $(top_srcdir)/ccan/str/str.h udpsocket.o: $(top_srcdir)/internal.h udpsocket.o: $(top_srcdir)/internal/array.h +udpsocket.o: $(top_srcdir)/internal/basic_operators.h udpsocket.o: $(top_srcdir)/internal/compilers.h udpsocket.o: $(top_srcdir)/internal/error.h udpsocket.o: $(top_srcdir)/internal/gc.h +udpsocket.o: $(top_srcdir)/internal/imemo.h udpsocket.o: $(top_srcdir)/internal/io.h +udpsocket.o: $(top_srcdir)/internal/sanitizers.h udpsocket.o: $(top_srcdir)/internal/serial.h udpsocket.o: $(top_srcdir)/internal/static_assert.h udpsocket.o: $(top_srcdir)/internal/string.h udpsocket.o: $(top_srcdir)/internal/thread.h udpsocket.o: $(top_srcdir)/internal/vm.h udpsocket.o: $(top_srcdir)/internal/warnings.h +udpsocket.o: $(top_srcdir)/method.h +udpsocket.o: $(top_srcdir)/node.h +udpsocket.o: $(top_srcdir)/ruby_assert.h +udpsocket.o: $(top_srcdir)/ruby_atomic.h +udpsocket.o: $(top_srcdir)/rubyparser.h +udpsocket.o: $(top_srcdir)/shape.h +udpsocket.o: $(top_srcdir)/thread_pthread.h +udpsocket.o: $(top_srcdir)/vm_core.h +udpsocket.o: $(top_srcdir)/vm_opts.h udpsocket.o: constdefs.h udpsocket.o: rubysocket.h udpsocket.o: sockport.h udpsocket.o: udpsocket.c +udpsocket.o: {$(VPATH)}id.h unixserver.o: $(RUBY_EXTCONF_H) unixserver.o: $(arch_hdrdir)/ruby/config.h -unixserver.o: $(hdrdir)/ruby.h unixserver.o: $(hdrdir)/ruby/assert.h +unixserver.o: $(hdrdir)/ruby/atomic.h unixserver.o: $(hdrdir)/ruby/backward.h unixserver.o: $(hdrdir)/ruby/backward/2/assume.h unixserver.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2512,6 +2772,7 @@ unixserver.o: $(hdrdir)/ruby/defines.h unixserver.o: $(hdrdir)/ruby/encoding.h unixserver.o: $(hdrdir)/ruby/fiber/scheduler.h unixserver.o: $(hdrdir)/ruby/intern.h +unixserver.o: $(hdrdir)/ruby/internal/abi.h unixserver.o: $(hdrdir)/ruby/internal/anyargs.h unixserver.o: $(hdrdir)/ruby/internal/arithmetic.h unixserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2549,6 +2810,7 @@ unixserver.o: $(hdrdir)/ruby/internal/attr/noexcept.h unixserver.o: $(hdrdir)/ruby/internal/attr/noinline.h unixserver.o: $(hdrdir)/ruby/internal/attr/nonnull.h unixserver.o: $(hdrdir)/ruby/internal/attr/noreturn.h +unixserver.o: $(hdrdir)/ruby/internal/attr/packed_struct.h unixserver.o: $(hdrdir)/ruby/internal/attr/pure.h unixserver.o: $(hdrdir)/ruby/internal/attr/restrict.h unixserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2617,7 +2879,6 @@ unixserver.o: $(hdrdir)/ruby/internal/intern/enumerator.h unixserver.o: $(hdrdir)/ruby/internal/intern/error.h unixserver.o: $(hdrdir)/ruby/internal/intern/eval.h unixserver.o: $(hdrdir)/ruby/internal/intern/file.h -unixserver.o: $(hdrdir)/ruby/internal/intern/gc.h unixserver.o: $(hdrdir)/ruby/internal/intern/hash.h unixserver.o: $(hdrdir)/ruby/internal/intern/io.h unixserver.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2648,12 +2909,12 @@ unixserver.o: $(hdrdir)/ruby/internal/memory.h unixserver.o: $(hdrdir)/ruby/internal/method.h unixserver.o: $(hdrdir)/ruby/internal/module.h unixserver.o: $(hdrdir)/ruby/internal/newobj.h -unixserver.o: $(hdrdir)/ruby/internal/rgengc.h unixserver.o: $(hdrdir)/ruby/internal/scan_args.h unixserver.o: $(hdrdir)/ruby/internal/special_consts.h unixserver.o: $(hdrdir)/ruby/internal/static_assert.h unixserver.o: $(hdrdir)/ruby/internal/stdalign.h unixserver.o: $(hdrdir)/ruby/internal/stdbool.h +unixserver.o: $(hdrdir)/ruby/internal/stdckdint.h unixserver.o: $(hdrdir)/ruby/internal/symbol.h unixserver.o: $(hdrdir)/ruby/internal/value.h unixserver.o: $(hdrdir)/ruby/internal/value_type.h @@ -2668,27 +2929,46 @@ unixserver.o: $(hdrdir)/ruby/ruby.h unixserver.o: $(hdrdir)/ruby/st.h unixserver.o: $(hdrdir)/ruby/subst.h unixserver.o: $(hdrdir)/ruby/thread.h +unixserver.o: $(hdrdir)/ruby/thread_native.h unixserver.o: $(hdrdir)/ruby/util.h +unixserver.o: $(hdrdir)/ruby/version.h +unixserver.o: $(top_srcdir)/ccan/check_type/check_type.h +unixserver.o: $(top_srcdir)/ccan/container_of/container_of.h +unixserver.o: $(top_srcdir)/ccan/list/list.h +unixserver.o: $(top_srcdir)/ccan/str/str.h unixserver.o: $(top_srcdir)/internal.h unixserver.o: $(top_srcdir)/internal/array.h +unixserver.o: $(top_srcdir)/internal/basic_operators.h unixserver.o: $(top_srcdir)/internal/compilers.h unixserver.o: $(top_srcdir)/internal/error.h unixserver.o: $(top_srcdir)/internal/gc.h +unixserver.o: $(top_srcdir)/internal/imemo.h unixserver.o: $(top_srcdir)/internal/io.h +unixserver.o: $(top_srcdir)/internal/sanitizers.h unixserver.o: $(top_srcdir)/internal/serial.h unixserver.o: $(top_srcdir)/internal/static_assert.h unixserver.o: $(top_srcdir)/internal/string.h unixserver.o: $(top_srcdir)/internal/thread.h unixserver.o: $(top_srcdir)/internal/vm.h unixserver.o: $(top_srcdir)/internal/warnings.h +unixserver.o: $(top_srcdir)/method.h +unixserver.o: $(top_srcdir)/node.h +unixserver.o: $(top_srcdir)/ruby_assert.h +unixserver.o: $(top_srcdir)/ruby_atomic.h +unixserver.o: $(top_srcdir)/rubyparser.h +unixserver.o: $(top_srcdir)/shape.h +unixserver.o: $(top_srcdir)/thread_pthread.h +unixserver.o: $(top_srcdir)/vm_core.h +unixserver.o: $(top_srcdir)/vm_opts.h unixserver.o: constdefs.h unixserver.o: rubysocket.h unixserver.o: sockport.h unixserver.o: unixserver.c +unixserver.o: {$(VPATH)}id.h unixsocket.o: $(RUBY_EXTCONF_H) unixsocket.o: $(arch_hdrdir)/ruby/config.h -unixsocket.o: $(hdrdir)/ruby.h unixsocket.o: $(hdrdir)/ruby/assert.h +unixsocket.o: $(hdrdir)/ruby/atomic.h unixsocket.o: $(hdrdir)/ruby/backward.h unixsocket.o: $(hdrdir)/ruby/backward/2/assume.h unixsocket.o: $(hdrdir)/ruby/backward/2/attributes.h @@ -2703,6 +2983,7 @@ unixsocket.o: $(hdrdir)/ruby/defines.h unixsocket.o: $(hdrdir)/ruby/encoding.h unixsocket.o: $(hdrdir)/ruby/fiber/scheduler.h unixsocket.o: $(hdrdir)/ruby/intern.h +unixsocket.o: $(hdrdir)/ruby/internal/abi.h unixsocket.o: $(hdrdir)/ruby/internal/anyargs.h unixsocket.o: $(hdrdir)/ruby/internal/arithmetic.h unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -2740,6 +3021,7 @@ unixsocket.o: $(hdrdir)/ruby/internal/attr/noexcept.h unixsocket.o: $(hdrdir)/ruby/internal/attr/noinline.h unixsocket.o: $(hdrdir)/ruby/internal/attr/nonnull.h unixsocket.o: $(hdrdir)/ruby/internal/attr/noreturn.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/packed_struct.h unixsocket.o: $(hdrdir)/ruby/internal/attr/pure.h unixsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h unixsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -2808,7 +3090,6 @@ unixsocket.o: $(hdrdir)/ruby/internal/intern/enumerator.h unixsocket.o: $(hdrdir)/ruby/internal/intern/error.h unixsocket.o: $(hdrdir)/ruby/internal/intern/eval.h unixsocket.o: $(hdrdir)/ruby/internal/intern/file.h -unixsocket.o: $(hdrdir)/ruby/internal/intern/gc.h unixsocket.o: $(hdrdir)/ruby/internal/intern/hash.h unixsocket.o: $(hdrdir)/ruby/internal/intern/io.h unixsocket.o: $(hdrdir)/ruby/internal/intern/load.h @@ -2839,12 +3120,12 @@ unixsocket.o: $(hdrdir)/ruby/internal/memory.h unixsocket.o: $(hdrdir)/ruby/internal/method.h unixsocket.o: $(hdrdir)/ruby/internal/module.h unixsocket.o: $(hdrdir)/ruby/internal/newobj.h -unixsocket.o: $(hdrdir)/ruby/internal/rgengc.h unixsocket.o: $(hdrdir)/ruby/internal/scan_args.h unixsocket.o: $(hdrdir)/ruby/internal/special_consts.h unixsocket.o: $(hdrdir)/ruby/internal/static_assert.h unixsocket.o: $(hdrdir)/ruby/internal/stdalign.h unixsocket.o: $(hdrdir)/ruby/internal/stdbool.h +unixsocket.o: $(hdrdir)/ruby/internal/stdckdint.h unixsocket.o: $(hdrdir)/ruby/internal/symbol.h unixsocket.o: $(hdrdir)/ruby/internal/value.h unixsocket.o: $(hdrdir)/ruby/internal/value_type.h @@ -2859,21 +3140,40 @@ unixsocket.o: $(hdrdir)/ruby/ruby.h unixsocket.o: $(hdrdir)/ruby/st.h unixsocket.o: $(hdrdir)/ruby/subst.h unixsocket.o: $(hdrdir)/ruby/thread.h +unixsocket.o: $(hdrdir)/ruby/thread_native.h unixsocket.o: $(hdrdir)/ruby/util.h +unixsocket.o: $(hdrdir)/ruby/version.h +unixsocket.o: $(top_srcdir)/ccan/check_type/check_type.h +unixsocket.o: $(top_srcdir)/ccan/container_of/container_of.h +unixsocket.o: $(top_srcdir)/ccan/list/list.h +unixsocket.o: $(top_srcdir)/ccan/str/str.h unixsocket.o: $(top_srcdir)/internal.h unixsocket.o: $(top_srcdir)/internal/array.h +unixsocket.o: $(top_srcdir)/internal/basic_operators.h unixsocket.o: $(top_srcdir)/internal/compilers.h unixsocket.o: $(top_srcdir)/internal/error.h unixsocket.o: $(top_srcdir)/internal/gc.h +unixsocket.o: $(top_srcdir)/internal/imemo.h unixsocket.o: $(top_srcdir)/internal/io.h +unixsocket.o: $(top_srcdir)/internal/sanitizers.h unixsocket.o: $(top_srcdir)/internal/serial.h unixsocket.o: $(top_srcdir)/internal/static_assert.h unixsocket.o: $(top_srcdir)/internal/string.h unixsocket.o: $(top_srcdir)/internal/thread.h unixsocket.o: $(top_srcdir)/internal/vm.h unixsocket.o: $(top_srcdir)/internal/warnings.h +unixsocket.o: $(top_srcdir)/method.h +unixsocket.o: $(top_srcdir)/node.h +unixsocket.o: $(top_srcdir)/ruby_assert.h +unixsocket.o: $(top_srcdir)/ruby_atomic.h +unixsocket.o: $(top_srcdir)/rubyparser.h +unixsocket.o: $(top_srcdir)/shape.h +unixsocket.o: $(top_srcdir)/thread_pthread.h +unixsocket.o: $(top_srcdir)/vm_core.h +unixsocket.o: $(top_srcdir)/vm_opts.h unixsocket.o: constdefs.h unixsocket.o: rubysocket.h unixsocket.o: sockport.h unixsocket.o: unixsocket.c +unixsocket.o: {$(VPATH)}id.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index c86cc8f8c0..d44ce31b0a 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -316,6 +316,7 @@ end netpacket/packet.h net/ethernet.h sys/un.h + afunix.h ifaddrs.h sys/ioctl.h sys/sockio.h @@ -326,6 +327,8 @@ end net/if_dl.h arpa/nameser.h resolv.h + pthread.h + sched.h ].each {|h| if have_header(h, headers) headers << h @@ -346,10 +349,22 @@ have_type("struct sockaddr_storage", headers) have_type("struct addrinfo", headers) -if have_type("socklen_t", headers) - if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers) - $defs << "-DRSTRING_SOCKLEN=(socklen_t)RSTRING_LEN" +def check_socklen(headers) + def (fmt = "none").%(x) + x || self + end + s = checking_for("RSTRING_SOCKLEN", fmt) do + if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers) + "RSTRING_LEN" + else + "RSTRING_LENINT" + end end + $defs << "-DRSTRING_SOCKLEN=(socklen_t)"+s +end + +if have_type("socklen_t", headers) + check_socklen(headers) end have_type("struct in_pktinfo", headers) {|src| @@ -484,6 +499,9 @@ EOF have_func("getpeerucred(0, (ucred_t **)NULL)", headers) # SunOS have_func_decl = proc do |name, headers| + # check if there is a declaration of <name> by trying to declare + # both "int <name>(void)" and "void <name>(void)" + # (at least one attempt should fail if there is a declaration) if !checking_for("declaration of #{name}()") {!%w[int void].all? {|ret| try_compile(<<EOF)}} #{cpp_include(headers)} #{ret} #{name}(void); @@ -492,10 +510,10 @@ EOF end end if have_func('if_indextoname(0, "")', headers) - have_func_decl["if_indextoname"] + have_func_decl["if_indextoname", headers] end if have_func('if_nametoindex("")', headers) - have_func_decl["if_nametoindex"] + have_func_decl["if_nametoindex", headers] end have_func("hsterror", headers) @@ -548,7 +566,7 @@ EOS end if !have_macro("IPPROTO_IPV6", headers) && have_const("IPPROTO_IPV6", headers) - IO.read(File.join(File.dirname(__FILE__), "mkconstants.rb")).sub(/\A.*^__END__$/m, '').split(/\r?\n/).grep(/\AIPPROTO_\w*/){$&}.each {|name| + File.read(File.join(File.dirname(__FILE__), "mkconstants.rb")).sub(/\A.*^__END__$/m, '').split(/\r?\n/).grep(/\AIPPROTO_\w*/){$&}.each {|name| have_const(name, headers) unless $defs.include?("-DHAVE_CONST_#{name.upcase}") } end @@ -652,12 +670,20 @@ EOS end hdr = "netinet6/in6.h" - if /darwin/ =~ RUBY_PLATFORM and !try_compile(<<"SRC", nil, :werror=>true) + /darwin/ =~ RUBY_PLATFORM and + checking_for("if apple's #{hdr} needs s6_addr patch") {!try_compile(<<"SRC", nil, :werror=>true)} and #include <netinet/in.h> int t(struct in6_addr *addr) {return IN6_IS_ADDR_UNSPECIFIED(addr);} SRC - print "fixing apple's netinet6/in6.h ..."; $stdout.flush - in6 = File.read("/usr/include/#{hdr}") + checking_for("fixing apple's #{hdr}", "%s") do + file = xpopen(%w"clang -include netinet/in.h -E -xc -", in: IO::NULL) do |f| + re = %r[^# *\d+ *"(.*/netinet/in\.h)"] + Logging.message " grep(#{re})\n" + f.read[re, 1] + end + Logging.message "Substitute from #{file}\n" + + in6 = File.read(file) if in6.gsub!(/\*\(const\s+__uint32_t\s+\*\)\(const\s+void\s+\*\)\(&(\(\w+\))->s6_addr\[(\d+)\]\)/) do i, r = $2.to_i.divmod(4) if r.zero? @@ -667,13 +693,18 @@ SRC end end FileUtils.mkdir_p(File.dirname(hdr)) - open(hdr, "w") {|f| f.write(in6)} + File.write(hdr, in6) $distcleanfiles << hdr $distcleandirs << File.dirname(hdr) - puts "done" + "done" else - puts "not needed" + "not needed" end end + + have_func("pthread_create") + have_func("pthread_detach") + + $VPATH << '$(topdir)' << '$(top_srcdir)' create_makefile("socket") end diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c index ce6dc40478..bf0d90129f 100644 --- a/ext/socket/getaddrinfo.c +++ b/ext/socket/getaddrinfo.c @@ -98,42 +98,42 @@ static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT; static const char in_addrany[] = { 0, 0, 0, 0 }; static const char in6_addrany[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char in_loopback[] = { 127, 0, 0, 1 }; static const char in6_loopback[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; + u_char si_len; + u_char si_family; + u_short si_port; }; static const struct afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; - const char *a_addrany; - const char *a_loopback; + int a_af; + int a_addrlen; + int a_socklen; + int a_off; + const char *a_addrany; + const char *a_loopback; } afdl [] = { #ifdef INET6 #define N_INET6 0 - {PF_INET6, sizeof(struct in6_addr), - sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr), - in6_addrany, in6_loopback}, + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr), + in6_addrany, in6_loopback}, #define N_INET 1 #else #define N_INET 0 #endif - {PF_INET, sizeof(struct in_addr), - sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr), - in_addrany, in_loopback}, - {0, 0, 0, 0, NULL, NULL}, + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr), + in_addrany, in_loopback}, + {0, 0, 0, 0, NULL, NULL}, }; #ifdef INET6 @@ -143,58 +143,58 @@ static const struct afd { #endif static int get_name __P((const char *, const struct afd *, - struct addrinfo **, char *, struct addrinfo *, - int)); + struct addrinfo **, char *, struct addrinfo *, + int)); static int get_addr __P((const char *, int, struct addrinfo **, - struct addrinfo *, int)); + struct addrinfo *, int)); static int str_isnumber __P((const char *)); #ifndef HAVE_GAI_STRERROR static const char *const ai_errlist[] = { - "success.", - "address family for hostname not supported.", /* EAI_ADDRFAMILY */ - "temporary failure in name resolution.", /* EAI_AGAIN */ - "invalid value for ai_flags.", /* EAI_BADFLAGS */ - "non-recoverable failure in name resolution.", /* EAI_FAIL */ - "ai_family not supported.", /* EAI_FAMILY */ - "memory allocation failure.", /* EAI_MEMORY */ - "no address associated with hostname.", /* EAI_NODATA */ - "hostname nor servname provided, or not known.",/* EAI_NONAME */ - "servname not supported for ai_socktype.", /* EAI_SERVICE */ - "ai_socktype not supported.", /* EAI_SOCKTYPE */ - "system error returned in errno.", /* EAI_SYSTEM */ - "invalid value for hints.", /* EAI_BADHINTS */ - "resolved protocol is unknown.", /* EAI_PROTOCOL */ - "unknown error.", /* EAI_MAX */ + "success.", + "address family for hostname not supported.", /* EAI_ADDRFAMILY */ + "temporary failure in name resolution.", /* EAI_AGAIN */ + "invalid value for ai_flags.", /* EAI_BADFLAGS */ + "non-recoverable failure in name resolution.", /* EAI_FAIL */ + "ai_family not supported.", /* EAI_FAMILY */ + "memory allocation failure.", /* EAI_MEMORY */ + "no address associated with hostname.", /* EAI_NODATA */ + "hostname nor servname provided, or not known.",/* EAI_NONAME */ + "servname not supported for ai_socktype.", /* EAI_SERVICE */ + "ai_socktype not supported.", /* EAI_SOCKTYPE */ + "system error returned in errno.", /* EAI_SYSTEM */ + "invalid value for hints.", /* EAI_BADHINTS */ + "resolved protocol is unknown.", /* EAI_PROTOCOL */ + "unknown error.", /* EAI_MAX */ }; #endif #define GET_CANONNAME(ai, str) \ if (pai->ai_flags & AI_CANONNAME) {\ - if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ - strcpy((ai)->ai_canonname, (str));\ - } else {\ - error = EAI_MEMORY;\ - goto free;\ - }\ + if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ + strcpy((ai)->ai_canonname, (str));\ + } else {\ + error = EAI_MEMORY;\ + goto free;\ + }\ } #define GET_AI(ai, afd, addr, port) {\ - char *p;\ - if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ - ((afd)->a_socklen)))\ - == NULL) {\ - error = EAI_MEMORY;\ - goto free;\ - }\ - memcpy((ai), pai, sizeof(struct addrinfo));\ - (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ - (ai)->ai_family = (afd)->a_af;\ - (ai)->ai_addrlen = (afd)->a_socklen;\ - INIT_SOCKADDR((ai)->ai_addr, (afd)->a_af, (afd)->a_socklen);\ - ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\ - p = (char *)((ai)->ai_addr);\ - memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\ + char *p;\ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ + ((afd)->a_socklen)))\ + == NULL) {\ + error = EAI_MEMORY;\ + goto free;\ + }\ + memcpy((ai), pai, sizeof(struct addrinfo));\ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ + (ai)->ai_family = (afd)->a_af;\ + (ai)->ai_addrlen = (afd)->a_socklen;\ + INIT_SOCKADDR((ai)->ai_addr, (afd)->a_af, (afd)->a_socklen);\ + ((struct sockinet *)(ai)->ai_addr)->si_port = (port);\ + p = (char *)((ai)->ai_addr);\ + memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\ } #define ERR(err) { error = (err); goto bad; } @@ -206,36 +206,35 @@ const char * gai_strerror(int ecode) { - if (ecode < 0 || ecode > EAI_MAX) - ecode = EAI_MAX; - return (char *)ai_errlist[ecode]; + if (ecode < 0 || ecode > EAI_MAX) + ecode = EAI_MAX; + return (char *)ai_errlist[ecode]; } #endif void freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *next; - - do { - next = ai->ai_next; - if (ai->ai_canonname) - free(ai->ai_canonname); - /* no need to free(ai->ai_addr) */ - free(ai); - } while ((ai = next) != NULL); + struct addrinfo *next; + + do { + next = ai->ai_next; + free(ai->ai_canonname); + /* no need to free(ai->ai_addr) */ + free(ai); + } while ((ai = next) != NULL); } static int str_isnumber(const char *p) { - char *q = (char *)p; - while (*q) { - if (! isdigit(*q)) - return NO; - q++; - } - return YES; + char *q = (char *)p; + while (*q) { + if (! isdigit(*q)) + return NO; + q++; + } + return YES; } #ifndef HAVE_INET_PTON @@ -243,435 +242,435 @@ str_isnumber(const char *p) static int inet_pton(int af, const char *hostname, void *pton) { - struct in_addr in; + struct in_addr in; #ifdef HAVE_INET_ATON - if (!inet_aton(hostname, &in)) - return 0; + if (!inet_aton(hostname, &in)) + return 0; #else - int d1, d2, d3, d4; - char ch; - - if (sscanf(hostname, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 && - 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 && - 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) { - in.s_addr = htonl( - ((long) d1 << 24) | ((long) d2 << 16) | - ((long) d3 << 8) | ((long) d4 << 0)); - } - else { - return 0; - } -#endif - memcpy(pton, &in, sizeof(in)); - return 1; + int d1, d2, d3, d4; + char ch; + + if (sscanf(hostname, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 && + 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 && + 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) { + in.s_addr = htonl( + ((long) d1 << 24) | ((long) d2 << 16) | + ((long) d3 << 8) | ((long) d4 << 0)); + } + else { + return 0; + } +#endif + memcpy(pton, &in, sizeof(in)); + return 1; } #endif int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { - struct addrinfo sentinel; - struct addrinfo *top = NULL; - struct addrinfo *cur; - int i, error = 0; - char pton[PTON_MAX]; - struct addrinfo ai; - struct addrinfo *pai; - u_short port; + struct addrinfo sentinel; + struct addrinfo *top = NULL; + struct addrinfo *cur; + int i, error = 0; + char pton[PTON_MAX]; + struct addrinfo ai; + struct addrinfo *pai; + u_short port; #ifdef FAITH - static int firsttime = 1; - - if (firsttime) { - /* translator hack */ - { - char *q = getenv("GAI"); - if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) - translate = YES; - } - firsttime = 0; - } -#endif - - /* initialize file static vars */ - sentinel.ai_next = NULL; - cur = &sentinel; - pai = &ai; - pai->ai_flags = 0; - pai->ai_family = PF_UNSPEC; - pai->ai_socktype = ANY; - pai->ai_protocol = ANY; - pai->ai_addrlen = 0; - pai->ai_canonname = NULL; - pai->ai_addr = NULL; - pai->ai_next = NULL; - port = ANY; - - if (hostname == NULL && servname == NULL) - return EAI_NONAME; - if (hints) { - /* error check for hints */ - if (hints->ai_addrlen || hints->ai_canonname || - hints->ai_addr || hints->ai_next) - ERR(EAI_BADHINTS); /* xxx */ - if (hints->ai_flags & ~AI_MASK) - ERR(EAI_BADFLAGS); - switch (hints->ai_family) { - case PF_UNSPEC: - case PF_INET: + static int firsttime = 1; + + if (firsttime) { + /* translator hack */ + { + char *q = getenv("GAI"); + if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) + translate = YES; + } + firsttime = 0; + } +#endif + + /* initialize file static vars */ + sentinel.ai_next = NULL; + cur = &sentinel; + pai = &ai; + pai->ai_flags = 0; + pai->ai_family = PF_UNSPEC; + pai->ai_socktype = ANY; + pai->ai_protocol = ANY; + pai->ai_addrlen = 0; + pai->ai_canonname = NULL; + pai->ai_addr = NULL; + pai->ai_next = NULL; + port = ANY; + + if (hostname == NULL && servname == NULL) + return EAI_NONAME; + if (hints) { + /* error check for hints */ + if (hints->ai_addrlen || hints->ai_canonname || + hints->ai_addr || hints->ai_next) + ERR(EAI_BADHINTS); /* xxx */ + if (hints->ai_flags & ~AI_MASK) + ERR(EAI_BADFLAGS); + switch (hints->ai_family) { + case PF_UNSPEC: + case PF_INET: #ifdef INET6 - case PF_INET6: -#endif - break; - default: - ERR(EAI_FAMILY); - } - memcpy(pai, hints, sizeof(*pai)); - switch (pai->ai_socktype) { - case ANY: - switch (pai->ai_protocol) { - case ANY: - break; - case IPPROTO_UDP: - pai->ai_socktype = SOCK_DGRAM; - break; - case IPPROTO_TCP: - pai->ai_socktype = SOCK_STREAM; - break; - default: + case PF_INET6: +#endif + break; + default: + ERR(EAI_FAMILY); + } + memcpy(pai, hints, sizeof(*pai)); + switch (pai->ai_socktype) { + case ANY: + switch (pai->ai_protocol) { + case ANY: + break; + case IPPROTO_UDP: + pai->ai_socktype = SOCK_DGRAM; + break; + case IPPROTO_TCP: + pai->ai_socktype = SOCK_STREAM; + break; + default: #if defined(SOCK_RAW) - pai->ai_socktype = SOCK_RAW; + pai->ai_socktype = SOCK_RAW; #endif - break; - } - break; + break; + } + break; #if defined(SOCK_RAW) - case SOCK_RAW: - break; -#endif - case SOCK_DGRAM: - if (pai->ai_protocol != IPPROTO_UDP && - pai->ai_protocol != ANY) - ERR(EAI_BADHINTS); /*xxx*/ - pai->ai_protocol = IPPROTO_UDP; - break; - case SOCK_STREAM: - if (pai->ai_protocol != IPPROTO_TCP && - pai->ai_protocol != ANY) - ERR(EAI_BADHINTS); /*xxx*/ - pai->ai_protocol = IPPROTO_TCP; - break; - default: - ERR(EAI_SOCKTYPE); - break; - } - } - - /* - * service port - */ - if (servname) { - if (str_isnumber(servname)) { - if (pai->ai_socktype == ANY) { - /* caller accept *ANY* socktype */ - pai->ai_socktype = SOCK_DGRAM; - pai->ai_protocol = IPPROTO_UDP; - } - port = htons((unsigned short)atoi(servname)); + case SOCK_RAW: + break; +#endif + case SOCK_DGRAM: + if (pai->ai_protocol != IPPROTO_UDP && + pai->ai_protocol != ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_UDP; + break; + case SOCK_STREAM: + if (pai->ai_protocol != IPPROTO_TCP && + pai->ai_protocol != ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_TCP; + break; + default: + ERR(EAI_SOCKTYPE); + break; + } + } + + /* + * service port + */ + if (servname) { + if (str_isnumber(servname)) { + if (pai->ai_socktype == ANY) { + /* caller accept *ANY* socktype */ + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } + port = htons((unsigned short)atoi(servname)); } else if (pai->ai_flags & AI_NUMERICSERV) { ERR(EAI_NONAME); - } else { - struct servent *sp; - const char *proto; - - proto = NULL; - switch (pai->ai_socktype) { - case ANY: - proto = NULL; - break; - case SOCK_DGRAM: - proto = "udp"; - break; - case SOCK_STREAM: - proto = "tcp"; - break; - default: - fprintf(stderr, "panic!\n"); - break; - } - if ((sp = getservbyname((char*)servname, proto)) == NULL) - ERR(EAI_SERVICE); - port = sp->s_port; - if (pai->ai_socktype == ANY) - if (strcmp(sp->s_proto, "udp") == 0) { - pai->ai_socktype = SOCK_DGRAM; - pai->ai_protocol = IPPROTO_UDP; - } else if (strcmp(sp->s_proto, "tcp") == 0) { - pai->ai_socktype = SOCK_STREAM; - pai->ai_protocol = IPPROTO_TCP; - } else - ERR(EAI_PROTOCOL); /*xxx*/ - } - } - - /* - * hostname == NULL. - * passive socket -> anyaddr (0.0.0.0 or ::) - * non-passive socket -> localhost (127.0.0.1 or ::1) - */ - if (hostname == NULL) { - const struct afd *afd; - int s; - - for (afd = &afdl[0]; afd->a_af; afd++) { - if (!(pai->ai_family == PF_UNSPEC - || pai->ai_family == afd->a_af)) { - continue; - } - - /* - * filter out AFs that are not supported by the kernel - * XXX errno? - */ - s = socket(afd->a_af, SOCK_DGRAM, 0); - if (s < 0) - continue; - - close(s); - - if (pai->ai_flags & AI_PASSIVE) { - GET_AI(cur->ai_next, afd, afd->a_addrany, port); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "anyaddr"); - */ - } else { - GET_AI(cur->ai_next, afd, afd->a_loopback, - port); - /* xxx meaningless? - * GET_CANONNAME(cur->ai_next, "localhost"); - */ - } - cur = cur->ai_next; - } - top = sentinel.ai_next; - if (top) - goto good; - else - ERR(EAI_FAMILY); - } - - /* hostname as numeric name */ - for (i = 0; afdl[i].a_af; i++) { - if (inet_pton(afdl[i].a_af, hostname, pton)) { - u_long v4a; + } else { + struct servent *sp; + const char *proto; + + proto = NULL; + switch (pai->ai_socktype) { + case ANY: + proto = NULL; + break; + case SOCK_DGRAM: + proto = "udp"; + break; + case SOCK_STREAM: + proto = "tcp"; + break; + default: + fprintf(stderr, "panic!\n"); + break; + } + if ((sp = getservbyname((char*)servname, proto)) == NULL) + ERR(EAI_SERVICE); + port = sp->s_port; + if (pai->ai_socktype == ANY) + if (strcmp(sp->s_proto, "udp") == 0) { + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } else if (strcmp(sp->s_proto, "tcp") == 0) { + pai->ai_socktype = SOCK_STREAM; + pai->ai_protocol = IPPROTO_TCP; + } else + ERR(EAI_PROTOCOL); /*xxx*/ + } + } + + /* + * hostname == NULL. + * passive socket -> anyaddr (0.0.0.0 or ::) + * non-passive socket -> localhost (127.0.0.1 or ::1) + */ + if (hostname == NULL) { + const struct afd *afd; + int s; + + for (afd = &afdl[0]; afd->a_af; afd++) { + if (!(pai->ai_family == PF_UNSPEC + || pai->ai_family == afd->a_af)) { + continue; + } + + /* + * filter out AFs that are not supported by the kernel + * XXX errno? + */ + s = socket(afd->a_af, SOCK_DGRAM, 0); + if (s < 0) + continue; + + close(s); + + if (pai->ai_flags & AI_PASSIVE) { + GET_AI(cur->ai_next, afd, afd->a_addrany, port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "anyaddr"); + */ + } else { + GET_AI(cur->ai_next, afd, afd->a_loopback, + port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "localhost"); + */ + } + cur = cur->ai_next; + } + top = sentinel.ai_next; + if (top) + goto good; + else + ERR(EAI_FAMILY); + } + + /* hostname as numeric name */ + for (i = 0; afdl[i].a_af; i++) { + if (inet_pton(afdl[i].a_af, hostname, pton)) { + u_long v4a; #ifdef INET6 - u_char pfx; -#endif - - switch (afdl[i].a_af) { - case AF_INET: - v4a = ((struct in_addr *)pton)->s_addr; - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - pai->ai_flags &= ~AI_CANONNAME; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0 || v4a == IN_LOOPBACKNET) - pai->ai_flags &= ~AI_CANONNAME; - break; + u_char pfx; +#endif + + switch (afdl[i].a_af) { + case AF_INET: + v4a = ((struct in_addr *)pton)->s_addr; + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + pai->ai_flags &= ~AI_CANONNAME; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + pai->ai_flags &= ~AI_CANONNAME; + break; #ifdef INET6 - case AF_INET6: - pfx = ((struct in6_addr *)pton)->s6_addr[0]; - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - pai->ai_flags &= ~AI_CANONNAME; - break; -#endif - } - - if (pai->ai_family == afdl[i].a_af || - pai->ai_family == PF_UNSPEC) { - if (! (pai->ai_flags & AI_CANONNAME)) { - GET_AI(top, &afdl[i], pton, port); - goto good; - } - /* - * if AI_CANONNAME and if reverse lookup - * fail, return ai anyway to pacify - * calling application. - * - * XXX getaddrinfo() is a name->address - * translation function, and it looks strange - * that we do addr->name translation here. - */ - get_name(pton, &afdl[i], &top, pton, pai, port); - goto good; - } else - ERR(EAI_FAMILY); /*xxx*/ - } - } - - if (pai->ai_flags & AI_NUMERICHOST) - ERR(EAI_NONAME); - - /* hostname as alphabetical name */ - error = get_addr(hostname, pai->ai_family, &top, pai, port); - if (error == 0) { - if (top) { + case AF_INET6: + pfx = ((struct in6_addr *)pton)->s6_addr[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + pai->ai_flags &= ~AI_CANONNAME; + break; +#endif + } + + if (pai->ai_family == afdl[i].a_af || + pai->ai_family == PF_UNSPEC) { + if (! (pai->ai_flags & AI_CANONNAME)) { + GET_AI(top, &afdl[i], pton, port); + goto good; + } + /* + * if AI_CANONNAME and if reverse lookup + * fail, return ai anyway to pacify + * calling application. + * + * XXX getaddrinfo() is a name->address + * translation function, and it looks strange + * that we do addr->name translation here. + */ + get_name(pton, &afdl[i], &top, pton, pai, port); + goto good; + } else + ERR(EAI_FAMILY); /*xxx*/ + } + } + + if (pai->ai_flags & AI_NUMERICHOST) + ERR(EAI_NONAME); + + /* hostname as alphabetical name */ + error = get_addr(hostname, pai->ai_family, &top, pai, port); + if (error == 0) { + if (top) { good: - *res = top; - return SUCCESS; - } else - error = EAI_FAIL; - } + *res = top; + return SUCCESS; + } else + error = EAI_FAIL; + } free: - if (top) - freeaddrinfo(top); + if (top) + freeaddrinfo(top); bad: - *res = NULL; - return error; + *res = NULL; + return error; } static int get_name(const char *addr, const struct afd *afd, struct addrinfo **res, char *numaddr, struct addrinfo *pai, int port0) { - u_short port = port0 & 0xffff; - struct hostent *hp; - struct addrinfo *cur; - int error = 0; + u_short port = port0 & 0xffff; + struct hostent *hp; + struct addrinfo *cur; + int error = 0; #ifdef INET6 - int h_error; + int h_error; #endif #ifdef INET6 - hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); #else - hp = gethostbyaddr((char*)addr, afd->a_addrlen, AF_INET); + hp = gethostbyaddr((char*)addr, afd->a_addrlen, AF_INET); #endif - if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { - GET_AI(cur, afd, hp->h_addr_list[0], port); - GET_CANONNAME(cur, hp->h_name); - } else - GET_AI(cur, afd, numaddr, port); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + GET_AI(cur, afd, hp->h_addr_list[0], port); + GET_CANONNAME(cur, hp->h_name); + } else + GET_AI(cur, afd, numaddr, port); #ifdef INET6 - if (hp) - freehostent(hp); + if (hp) + freehostent(hp); #endif - *res = cur; - return SUCCESS; + *res = cur; + return SUCCESS; free: - if (cur) - freeaddrinfo(cur); + if (cur) + freeaddrinfo(cur); #ifdef INET6 - if (hp) - freehostent(hp); + if (hp) + freehostent(hp); #endif /* bad: */ - *res = NULL; - return error; + *res = NULL; + return error; } static int get_addr(const char *hostname, int af, struct addrinfo **res, struct addrinfo *pai, int port0) { - u_short port = port0 & 0xffff; - struct addrinfo sentinel; - struct hostent *hp; - struct addrinfo *top, *cur; - const struct afd *afd; - int i, error = 0, h_error; - char *ap; - - top = NULL; - sentinel.ai_next = NULL; - cur = &sentinel; + u_short port = port0 & 0xffff; + struct addrinfo sentinel; + struct hostent *hp; + struct addrinfo *top, *cur; + const struct afd *afd; + int i, error = 0, h_error; + char *ap; + + top = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; #ifdef INET6 - if (af == AF_UNSPEC) { - hp = getipnodebyname(hostname, AF_INET6, - AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); - } else - hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); + if (af == AF_UNSPEC) { + hp = getipnodebyname(hostname, AF_INET6, + AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); + } else + hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); #else - if (strlen(hostname) >= NI_MAXHOST) ERR(EAI_NODATA); - hp = gethostbyname((char*)hostname); - h_error = h_errno; -#endif - if (hp == NULL) { - switch (h_error) { - case HOST_NOT_FOUND: - case NO_DATA: - error = EAI_NODATA; - break; - case TRY_AGAIN: - error = EAI_AGAIN; - break; - case NO_RECOVERY: - default: - error = EAI_FAIL; - break; - } - goto bad; - } - - if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || - (hp->h_addr_list[0] == NULL)) - ERR(EAI_FAIL); - - for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { - switch (af) { + if (strlen(hostname) >= NI_MAXHOST) ERR(EAI_NODATA); + hp = gethostbyname((char*)hostname); + h_error = h_errno; +#endif + if (hp == NULL) { + switch (h_error) { + case HOST_NOT_FOUND: + case NO_DATA: + error = EAI_NODATA; + break; + case TRY_AGAIN: + error = EAI_AGAIN; + break; + case NO_RECOVERY: + default: + error = EAI_FAIL; + break; + } + goto bad; + } + + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || + (hp->h_addr_list[0] == NULL)) + ERR(EAI_FAIL); + + for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { + switch (af) { #ifdef INET6 - case AF_INET6: - afd = &afdl[N_INET6]; - break; + case AF_INET6: + afd = &afdl[N_INET6]; + break; #endif #ifndef INET6 - default: /* AF_UNSPEC */ + default: /* AF_UNSPEC */ #endif - case AF_INET: - afd = &afdl[N_INET]; - break; + case AF_INET: + afd = &afdl[N_INET]; + break; #ifdef INET6 - default: /* AF_UNSPEC */ - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { - ap += sizeof(struct in6_addr) - - sizeof(struct in_addr); - afd = &afdl[N_INET]; - } else - afd = &afdl[N_INET6]; - break; -#endif - } + default: /* AF_UNSPEC */ + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { + ap += sizeof(struct in6_addr) - + sizeof(struct in_addr); + afd = &afdl[N_INET]; + } else + afd = &afdl[N_INET6]; + break; +#endif + } #ifdef FAITH - if (translate && afd->a_af == AF_INET) { - struct in6_addr *in6; - - GET_AI(cur->ai_next, &afdl[N_INET6], ap, port); - in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; - memcpy(&in6->s6_addr, &faith_prefix, - sizeof(struct in6_addr) - sizeof(struct in_addr)); - memcpy(&in6->s6_addr + sizeof(struct in_addr), ap, - sizeof(struct in_addr)); - } else + if (translate && afd->a_af == AF_INET) { + struct in6_addr *in6; + + GET_AI(cur->ai_next, &afdl[N_INET6], ap, port); + in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; + memcpy(&in6->s6_addr, &faith_prefix, + sizeof(struct in6_addr) - sizeof(struct in_addr)); + memcpy(&in6->s6_addr + sizeof(struct in_addr), ap, + sizeof(struct in_addr)); + } else #endif /* FAITH */ - GET_AI(cur->ai_next, afd, ap, port); - if (cur == &sentinel) { - top = cur->ai_next; - GET_CANONNAME(top, hp->h_name); - } - cur = cur->ai_next; - } + GET_AI(cur->ai_next, afd, ap, port); + if (cur == &sentinel) { + top = cur->ai_next; + GET_CANONNAME(top, hp->h_name); + } + cur = cur->ai_next; + } #ifdef INET6 - freehostent(hp); + freehostent(hp); #endif - *res = top; - return SUCCESS; + *res = top; + return SUCCESS; free: - if (top) - freeaddrinfo(top); + if (top) + freeaddrinfo(top); #ifdef INET6 - if (hp) - freehostent(hp); + if (hp) + freehostent(hp); #endif bad: - *res = NULL; - return error; + *res = NULL; + return error; } diff --git a/ext/socket/getnameinfo.c b/ext/socket/getnameinfo.c index 94a5eb9439..ae5284fab6 100644 --- a/ext/socket/getnameinfo.c +++ b/ext/socket/getnameinfo.c @@ -84,30 +84,30 @@ typedef int socklen_t; #define NO 0 struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; + u_char si_len; + u_char si_family; + u_short si_port; }; static struct afd { - int a_af; - int a_addrlen; - int a_socklen; - int a_off; + int a_af; + int a_addrlen; + int a_socklen; + int a_off; } afdl [] = { #ifdef INET6 #define N_INET6 0 - {PF_INET6, sizeof(struct in6_addr), - sizeof(struct sockaddr_in6), - offsetof(struct sockaddr_in6, sin6_addr)}, + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr)}, #define N_INET 1 #else #define N_INET 0 #endif - {PF_INET, sizeof(struct in_addr), - sizeof(struct sockaddr_in), - offsetof(struct sockaddr_in, sin_addr)}, - {0, 0, 0, 0}, + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr)}, + {0, 0, 0, 0}, }; #define ENI_NOSOCKET 0 @@ -121,123 +121,123 @@ static struct afd { int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags) { - struct afd *afd; - struct hostent *hp; - u_short port; - int family, len, i; - char *addr, *p; - u_long v4a; + struct afd *afd; + struct hostent *hp; + u_short port; + int family, len, i; + char *addr, *p; + u_long v4a; #ifdef INET6 - u_char pfx; + u_char pfx; #endif - int h_error; - char numserv[512]; - char numaddr[512]; + int h_error; + char numserv[512]; + char numaddr[512]; - if (sa == NULL) - return ENI_NOSOCKET; + if (sa == NULL) + return ENI_NOSOCKET; - if (!VALIDATE_SOCKLEN(sa, salen)) return ENI_SALEN; + if (!VALIDATE_SOCKLEN(sa, salen)) return ENI_SALEN; len = salen; - family = sa->sa_family; - for (i = 0; afdl[i].a_af; i++) - if (afdl[i].a_af == family) { - afd = &afdl[i]; - goto found; - } - return ENI_FAMILY; + family = sa->sa_family; + for (i = 0; afdl[i].a_af; i++) + if (afdl[i].a_af == family) { + afd = &afdl[i]; + goto found; + } + return ENI_FAMILY; found: - if (len != afd->a_socklen) return ENI_SALEN; - - port = ((struct sockinet *)sa)->si_port; /* network byte order */ - addr = (char *)sa + afd->a_off; - - if (serv == NULL || servlen == 0) { - /* what we should do? */ - } else if (flags & NI_NUMERICSERV) { - snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); - if (strlen(numserv) + 1 > servlen) - return ENI_MEMORY; - strcpy(serv, numserv); - } else { + if (len != afd->a_socklen) return ENI_SALEN; + + port = ((struct sockinet *)sa)->si_port; /* network byte order */ + addr = (char *)sa + afd->a_off; + + if (serv == NULL || servlen == 0) { + /* what we should do? */ + } else if (flags & NI_NUMERICSERV) { + snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); + if (strlen(numserv) + 1 > servlen) + return ENI_MEMORY; + strcpy(serv, numserv); + } else { #if defined(HAVE_GETSERVBYPORT) - struct servent *sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); - if (sp) { - if (strlen(sp->s_name) + 1 > servlen) - return ENI_MEMORY; - strcpy(serv, sp->s_name); - } else - return ENI_NOSERVNAME; + struct servent *sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); + if (sp) { + if (strlen(sp->s_name) + 1 > servlen) + return ENI_MEMORY; + strcpy(serv, sp->s_name); + } else + return ENI_NOSERVNAME; #else - return ENI_NOSERVNAME; -#endif - } - - switch (sa->sa_family) { - case AF_INET: - v4a = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - flags |= NI_NUMERICHOST; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0) - flags |= NI_NUMERICHOST; - break; + return ENI_NOSERVNAME; +#endif + } + + switch (sa->sa_family) { + case AF_INET: + v4a = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + flags |= NI_NUMERICHOST; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0) + flags |= NI_NUMERICHOST; + break; #ifdef INET6 - case AF_INET6: + case AF_INET6: #ifdef HAVE_ADDR8 - pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0]; + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0]; #else - pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; -#endif - if (pfx == 0 || pfx == 0xfe || pfx == 0xff) - flags |= NI_NUMERICHOST; - break; -#endif - } - if (host == NULL || hostlen == 0) { - /* what should we do? */ - } else if (flags & NI_NUMERICHOST) { - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_SYSTEM; - if (strlen(numaddr) > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } else { + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; +#endif + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + flags |= NI_NUMERICHOST; + break; +#endif + } + if (host == NULL || hostlen == 0) { + /* what should we do? */ + } else if (flags & NI_NUMERICHOST) { + if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_SYSTEM; + if (strlen(numaddr) > hostlen) + return ENI_MEMORY; + strcpy(host, numaddr); + } else { #ifdef INET6 - hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); + hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); #else - hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); - h_error = h_errno; + hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); + h_error = h_errno; #endif - if (hp) { - if (flags & NI_NOFQDN) { - p = strchr(hp->h_name, '.'); - if (p) *p = '\0'; - } - if (strlen(hp->h_name) + 1 > hostlen) { + if (hp) { + if (flags & NI_NOFQDN) { + p = strchr(hp->h_name, '.'); + if (p) *p = '\0'; + } + if (strlen(hp->h_name) + 1 > hostlen) { #ifdef INET6 - freehostent(hp); + freehostent(hp); #endif - return ENI_MEMORY; - } - strcpy(host, hp->h_name); + return ENI_MEMORY; + } + strcpy(host, hp->h_name); #ifdef INET6 - freehostent(hp); -#endif - } else { - if (flags & NI_NAMEREQD) - return ENI_NOHOSTNAME; - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_NOHOSTNAME; - if (strlen(numaddr) > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); - } - } - return SUCCESS; + freehostent(hp); +#endif + } else { + if (flags & NI_NAMEREQD) + return ENI_NOHOSTNAME; + if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_NOHOSTNAME; + if (strlen(numaddr) > hostlen) + return ENI_MEMORY; + strcpy(host, numaddr); + } + } + return SUCCESS; } diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c index 1da259bd6f..ab163dcc8f 100644 --- a/ext/socket/ifaddr.c +++ b/ext/socket/ifaddr.c @@ -104,7 +104,7 @@ rsock_getifaddrs(void) rb_sys_fail("getifaddrs"); if (!ifaddrs) { - return rb_ary_new(); + return rb_ary_new(); } numifaddrs = 0; @@ -128,9 +128,9 @@ rsock_getifaddrs(void) result = rb_ary_new2(numifaddrs); rb_ary_push(result, addr); for (i = 1; i < numifaddrs; i++) { - addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]); - root->refcount++; - rb_ary_push(result, addr); + addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]); + root->refcount++; + rb_ary_push(result, addr); } return result; diff --git a/ext/socket/init.c b/ext/socket/init.c index 359696e626..0e312b540e 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -27,6 +27,7 @@ VALUE rb_cSocket; VALUE rb_cAddrinfo; VALUE rb_eSocket; +VALUE rb_eResolution; #ifdef SOCKS VALUE rb_cSOCKSSocket; @@ -34,24 +35,29 @@ VALUE rb_cSOCKSSocket; int rsock_do_not_reverse_lookup = 1; static VALUE sym_wait_readable; +static ID id_error_code; void -rsock_raise_socket_error(const char *reason, int error) +rsock_raise_resolution_error(const char *reason, int error) { #ifdef EAI_SYSTEM int e; if (error == EAI_SYSTEM && (e = errno) != 0) - rb_syserr_fail(e, reason); + rb_syserr_fail(e, reason); #endif #ifdef _WIN32 rb_encoding *enc = rb_default_internal_encoding(); VALUE msg = rb_sprintf("%s: ", reason); if (!enc) enc = rb_default_internal_encoding(); rb_str_concat(msg, rb_w32_conv_from_wchar(gai_strerrorW(error), enc)); - rb_exc_raise(rb_exc_new_str(rb_eSocket, msg)); #else - rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error)); + VALUE msg = rb_sprintf("%s: %s", reason, gai_strerror(error)); #endif + + StringValue(msg); + VALUE self = rb_class_new_instance(1, &msg, rb_eResolution); + rb_ivar_set(self, id_error_code, INT2NUM(error)); + rb_exc_raise(self); } #if defined __APPLE__ @@ -71,7 +77,7 @@ rsock_init_sock(VALUE sock, int fd) fp->mode = FMODE_READWRITE|FMODE_DUPLEX; rb_io_ascii8bit_binmode(sock); if (rsock_do_not_reverse_lookup) { - fp->mode |= FMODE_NOREVLOOKUP; + fp->mode |= FMODE_NOREVLOOKUP; } rb_io_synchronized(fp); @@ -85,7 +91,7 @@ rsock_sendto_blocking(void *data) VALUE mesg = arg->mesg; ssize_t ret; do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags, arg->to, arg->tolen)); + arg->flags, arg->to, arg->tolen)); return (VALUE)ret; } @@ -96,7 +102,7 @@ rsock_send_blocking(void *data) VALUE mesg = arg->mesg; ssize_t ret; do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags)); + arg->flags)); return (VALUE)ret; } @@ -116,6 +122,7 @@ recvfrom_blocking(void *data) ssize_t ret; ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), arg->length, arg->flags, &arg->buf.addr, &arg->alen); + if (ret != -1 && len0 < arg->alen) arg->alen = len0; @@ -132,9 +139,9 @@ rsock_strbuf(VALUE str, long buflen) StringValue(str); len = RSTRING_LEN(str); if (len >= buflen) { - rb_str_modify(str); + rb_str_modify(str); } else { - rb_str_modify_expand(str, buflen - len); + rb_str_modify_expand(str, buflen - len); } return str; } @@ -147,6 +154,18 @@ recvfrom_locktmp(VALUE v) return rb_thread_io_blocking_region(recvfrom_blocking, arg, arg->fd); } +int +rsock_is_dgram(rb_io_t *fptr) +{ + int socktype; + socklen_t optlen = (socklen_t)sizeof(socktype); + int ret = getsockopt(fptr->fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen); + if (ret == -1) { + rb_sys_fail("getsockopt(SO_TYPE)"); + } + return socktype == SOCK_DGRAM; +} + VALUE rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) { @@ -185,11 +204,15 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); #endif - slen = (long)rb_str_locktmp_ensure(str, recvfrom_locktmp, (VALUE)&arg); + rb_str_locktmp(str); + slen = (long)rb_ensure(recvfrom_locktmp, (VALUE)&arg, rb_str_unlocktmp, str); + if (slen == 0 && !rsock_is_dgram(fptr)) { + return Qnil; + } if (slen >= 0) break; - if (!rb_io_maybe_wait_readable(errno, socket, Qnil)) + if (!rb_io_maybe_wait_readable(errno, socket, RUBY_IO_TIMEOUT_DEFAULT)) rb_sys_fail("recvfrom(2)"); } @@ -197,32 +220,32 @@ rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) rb_str_set_len(str, slen); switch (from) { case RECV_RECV: - return str; + return str; case RECV_IP: #if 0 - if (arg.alen != sizeof(struct sockaddr_in)) { - rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); - } + if (arg.alen != sizeof(struct sockaddr_in)) { + rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); + } #endif - if (arg.alen && arg.alen != sizeof(arg.buf)) /* OSX doesn't return a from result for connection-oriented sockets */ - return rb_assoc_new(str, rsock_ipaddr(&arg.buf.addr, arg.alen, fptr->mode & FMODE_NOREVLOOKUP)); - else - return rb_assoc_new(str, Qnil); + if (arg.alen && arg.alen != sizeof(arg.buf)) /* OSX doesn't return a from result for connection-oriented sockets */ + return rb_assoc_new(str, rsock_ipaddr(&arg.buf.addr, arg.alen, fptr->mode & FMODE_NOREVLOOKUP)); + else + return rb_assoc_new(str, Qnil); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case RECV_UNIX: return rb_assoc_new(str, rsock_unixaddr(&arg.buf.un, arg.alen)); #endif case RECV_SOCKET: - return rb_assoc_new(str, rsock_io_socket_addrinfo(socket, &arg.buf.addr, arg.alen)); + return rb_assoc_new(str, rsock_io_socket_addrinfo(socket, &arg.buf.addr, arg.alen)); default: - rb_bug("rsock_s_recvfrom called with bad value"); + rb_bug("rsock_s_recvfrom called with bad value"); } } VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, - VALUE ex, enum sock_recv_type from) + VALUE ex, enum sock_recv_type from) { rb_io_t *fptr; union_sockaddr buf; @@ -245,35 +268,39 @@ rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, GetOpenFile(sock, fptr); if (rb_io_read_pending(fptr)) { - rb_raise(rb_eIOError, "recvfrom for buffered IO"); + rb_raise(rb_eIOError, "recvfrom for buffered IO"); } fd = fptr->fd; rb_io_check_closed(fptr); if (!MSG_DONTWAIT_RELIABLE) - rb_io_set_nonblock(fptr); + rb_io_set_nonblock(fptr); len0 = alen; slen = recvfrom(fd, RSTRING_PTR(str), buflen, flags, &buf.addr, &alen); if (slen != -1 && len0 < alen) alen = len0; + if (slen == 0 && !rsock_is_dgram(fptr)) { + return Qnil; + } + if (slen < 0) { - int e = errno; - switch (e) { - case EAGAIN: + int e = errno; + switch (e) { + case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: + case EWOULDBLOCK: #endif if (ex == Qfalse) - return sym_wait_readable; + return sym_wait_readable; rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvfrom(2) would block"); - } - rb_syserr_fail(e, "recvfrom(2)"); + } + rb_syserr_fail(e, "recvfrom(2)"); } if (slen != RSTRING_LEN(str)) { - rb_str_set_len(str, slen); + rb_str_set_len(str, slen); } switch (from) { case RECV_RECV: @@ -324,31 +351,31 @@ rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex) GetOpenFile(sock, fptr); if (len == 0) { - rb_str_set_len(str, 0); - return str; + rb_str_set_len(str, 0); + return str; } ptr = RSTRING_PTR(str); n = read_buffered_data(ptr, len, fptr); if (n <= 0) { - n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT); - if (n < 0) { - int e = errno; - if ((e == EWOULDBLOCK || e == EAGAIN)) { - if (ex == Qfalse) return sym_wait_readable; - rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, - e, "read would block"); - } - rb_syserr_fail_path(e, fptr->pathv); - } + n = (long)recv(fptr->fd, ptr, len, MSG_DONTWAIT); + if (n < 0) { + int e = errno; + if ((e == EWOULDBLOCK || e == EAGAIN)) { + if (ex == Qfalse) return sym_wait_readable; + rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, + e, "read would block"); + } + rb_syserr_fail_path(e, fptr->pathv); + } } if (n != RSTRING_LEN(str)) { - rb_str_modify(str); - rb_str_set_len(str, n); + rb_str_modify(str); + rb_str_set_len(str, n); } if (n == 0) { - if (ex == Qfalse) return Qnil; - rb_eof_error(); + if (ex == Qfalse) return Qnil; + rb_eof_error(); } return str; @@ -362,7 +389,7 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) long n; if (!RB_TYPE_P(str, T_STRING)) - str = rb_obj_as_string(str); + str = rb_obj_as_string(str); sock = rb_io_get_write_io(sock); GetOpenFile(sock, fptr); @@ -374,7 +401,7 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) * are not userspace-buffered in Ruby by default. */ if (fptr->wbuf.len > 0) { - rb_io_flush(sock); + rb_io_flush(sock); } #ifdef __APPLE__ @@ -382,19 +409,19 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) #endif n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT); if (n < 0) { - int e = errno; + int e = errno; #ifdef __APPLE__ - if (e == EPROTOTYPE) { - goto again; - } -#endif - if (e == EWOULDBLOCK || e == EAGAIN) { - if (ex == Qfalse) return sym_wait_writable; - rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, - "write would block"); - } - rb_syserr_fail_path(e, fptr->pathv); + if (e == EPROTOTYPE) { + goto again; + } +#endif + if (e == EWOULDBLOCK || e == EAGAIN) { + if (ex == Qfalse) return sym_wait_writable; + rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, + "write would block"); + } + rb_syserr_fail_path(e, fptr->pathv); } return LONG2FIX(n); @@ -433,9 +460,9 @@ rsock_socket(int domain, int type, int proto) fd = rsock_socket0(domain, type, proto); if (fd < 0) { - if (rb_gc_for_fd(errno)) { - fd = rsock_socket0(domain, type, proto); - } + if (rb_gc_for_fd(errno)) { + fd = rsock_socket0(domain, type, proto); + } } if (0 <= fd) rb_update_max_fd(fd); @@ -492,16 +519,16 @@ wait_connectable(int fd, struct timeval *timeout) switch (sockerr) { case 0: - /* - * be defensive in case some platforms set SO_ERROR on the original, - * interrupted connect() - */ - - /* when the connection timed out, no errno is set and revents is 0. */ - if (timeout && revents == 0) { - errno = ETIMEDOUT; - return -1; - } + /* + * be defensive in case some platforms set SO_ERROR on the original, + * interrupted connect() + */ + + /* when the connection timed out, no errno is set and revents is 0. */ + if (timeout && revents == 0) { + errno = ETIMEDOUT; + return -1; + } case EINTR: #ifdef ERESTART case ERESTART: @@ -516,7 +543,7 @@ wait_connectable(int fd, struct timeval *timeout) #ifdef EISCONN case EISCONN: #endif - return 0; /* success */ + return 0; /* success */ default: /* likely (but not limited to): ECONNREFUSED, ETIMEDOUT, EHOSTUNREACH */ errno = sockerr; @@ -634,27 +661,27 @@ cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, - struct sockaddr *sockaddr, socklen_t *len) + struct sockaddr *sockaddr, socklen_t *len) { int fd2; rb_io_set_nonblock(fptr); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len); if (fd2 < 0) { - int e = errno; - switch (e) { - case EAGAIN: + int e = errno; + switch (e) { + case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: + case EWOULDBLOCK: #endif - case ECONNABORTED: + case ECONNABORTED: #if defined EPROTO - case EPROTO: + case EPROTO: #endif if (ex == Qfalse) - return sym_wait_readable; + return sym_wait_readable; rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "accept(2) would block"); - } + } rb_syserr_fail(e, "accept(2)"); } rb_update_max_fd(fd2); @@ -681,9 +708,9 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) RB_IO_POINTER(io, fptr); struct accept_arg accept_arg = { - .fd = fptr->fd, - .sockaddr = sockaddr, - .len = len + .fd = fptr->fd, + .sockaddr = sockaddr, + .len = len }; int retry = 0, peer; @@ -705,7 +732,7 @@ rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) retry = 1; goto retry; default: - if (!rb_io_maybe_wait_readable(error, io, Qnil)) break; + if (!rb_io_maybe_wait_readable(error, io, RUBY_IO_TIMEOUT_DEFAULT)) break; retry = 0; goto retry; } @@ -730,11 +757,11 @@ rsock_getfamily(rb_io_t *fptr) if (cached) { switch (cached) { #ifdef AF_UNIX - case FMODE_UNIX: return AF_UNIX; + case FMODE_UNIX: return AF_UNIX; #endif - case FMODE_INET: return AF_INET; - case FMODE_INET6: return AF_INET6; - } + case FMODE_INET: return AF_INET; + case FMODE_INET6: return AF_INET6; + } } ss.addr.sa_family = AF_UNSPEC; @@ -752,6 +779,18 @@ rsock_getfamily(rb_io_t *fptr) return ss.addr.sa_family; } +/* + * call-seq: + * error_code -> integer + * + * Returns the raw error code occurred at name resolution. + */ +static VALUE +sock_resolv_error_code(VALUE self) +{ + return rb_attr_get(self, id_error_code); +} + void rsock_init_socket_init(void) { @@ -759,6 +798,11 @@ rsock_init_socket_init(void) * SocketError is the error class for socket. */ rb_eSocket = rb_define_class("SocketError", rb_eStandardError); + /* + * ResolutionError is the error class for socket name resolution. + */ + rb_eResolution = rb_define_class_under(rb_cSocket, "ResolutionError", rb_eSocket); + rb_define_method(rb_eResolution, "error_code", sock_resolv_error_code, 0); rsock_init_ipsocket(); rsock_init_tcpsocket(); rsock_init_tcpserver(); @@ -772,6 +816,8 @@ rsock_init_socket_init(void) rsock_init_sockifaddr(); rsock_init_socket_constants(); + id_error_code = rb_intern_const("error_code"); + #undef rb_intern sym_wait_readable = ID2SYM(rb_intern("wait_readable")); diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index b5cdc60080..0c13620258 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -14,8 +14,8 @@ struct inetsock_arg { VALUE sock; struct { - VALUE host, serv; - struct rb_addrinfo *res; + VALUE host, serv; + struct rb_addrinfo *res; } remote, local; int type; int fd; @@ -28,15 +28,15 @@ inetsock_cleanup(VALUE v) { struct inetsock_arg *arg = (void *)v; if (arg->remote.res) { - rb_freeaddrinfo(arg->remote.res); - arg->remote.res = 0; + rb_freeaddrinfo(arg->remote.res); + arg->remote.res = 0; } if (arg->local.res) { - rb_freeaddrinfo(arg->local.res); - arg->local.res = 0; + rb_freeaddrinfo(arg->local.res); + arg->local.res = 0; } if (arg->fd >= 0) { - close(arg->fd); + close(arg->fd); } return Qnil; } @@ -61,8 +61,8 @@ init_inetsock_internal(VALUE v) } arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, - family, SOCK_STREAM, - (type == INET_SERVER) ? AI_PASSIVE : 0); + family, SOCK_STREAM, + (type == INET_SERVER) ? AI_PASSIVE : 0); /* @@ -70,15 +70,15 @@ init_inetsock_internal(VALUE v) */ if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) { - arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, - family, SOCK_STREAM, 0); + arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, + family, SOCK_STREAM, 0); } arg->fd = fd = -1; for (res = arg->remote.res->ai; res; res = res->ai_next) { #if !defined(INET6) && defined(AF_INET6) - if (res->ai_family == AF_INET6) - continue; + if (res->ai_family == AF_INET6) + continue; #endif lres = NULL; if (arg->local.res) { @@ -94,73 +94,73 @@ init_inetsock_internal(VALUE v) lres = arg->local.res->ai; } } - status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); - syscall = "socket(2)"; - fd = status; - if (fd < 0) { - error = errno; - continue; - } - arg->fd = fd; - if (type == INET_SERVER) { + status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); + syscall = "socket(2)"; + fd = status; + if (fd < 0) { + error = errno; + continue; + } + arg->fd = fd; + if (type == INET_SERVER) { #if !defined(_WIN32) && !defined(__CYGWIN__) - status = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - (char*)&status, (socklen_t)sizeof(status)); + status = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + (char*)&status, (socklen_t)sizeof(status)); #endif - status = bind(fd, res->ai_addr, res->ai_addrlen); - syscall = "bind(2)"; - } - else { - if (lres) { + status = bind(fd, res->ai_addr, res->ai_addrlen); + syscall = "bind(2)"; + } + else { + if (lres) { #if !defined(_WIN32) && !defined(__CYGWIN__) status = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&status, (socklen_t)sizeof(status)); #endif - status = bind(fd, lres->ai_addr, lres->ai_addrlen); - local = status; - syscall = "bind(2)"; - } - - if (status >= 0) { - status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, - (type == INET_SOCKS), tv); - syscall = "connect(2)"; - } - } - - if (status < 0) { - error = errno; - close(fd); - arg->fd = fd = -1; - continue; - } else - break; + status = bind(fd, lres->ai_addr, lres->ai_addrlen); + local = status; + syscall = "bind(2)"; + } + + if (status >= 0) { + status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, + (type == INET_SOCKS), tv); + syscall = "connect(2)"; + } + } + + if (status < 0) { + error = errno; + close(fd); + arg->fd = fd = -1; + continue; + } else + break; } if (status < 0) { - VALUE host, port; - - if (local < 0) { - host = arg->local.host; - port = arg->local.serv; - } else { - host = arg->remote.host; - port = arg->remote.serv; - } + VALUE host, port; + + if (local < 0) { + host = arg->local.host; + port = arg->local.serv; + } else { + host = arg->remote.host; + port = arg->remote.serv; + } - rsock_syserr_fail_host_port(error, syscall, host, port); + rsock_syserr_fail_host_port(error, syscall, host, port); } arg->fd = -1; if (type == INET_SERVER) { - status = listen(fd, SOMAXCONN); - if (status < 0) { - error = errno; - close(fd); - rb_syserr_fail(error, "listen(2)"); - } + status = listen(fd, SOMAXCONN); + if (status < 0) { + error = errno; + close(fd); + rb_syserr_fail(error, "listen(2)"); + } } /* create new instance */ @@ -169,8 +169,8 @@ init_inetsock_internal(VALUE v) VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, - VALUE local_host, VALUE local_serv, int type, - VALUE resolv_timeout, VALUE connect_timeout) + VALUE local_host, VALUE local_serv, int type, + VALUE resolv_timeout, VALUE connect_timeout) { struct inetsock_arg arg; arg.sock = sock; @@ -185,7 +185,7 @@ rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, arg.resolv_timeout = resolv_timeout; arg.connect_timeout = connect_timeout; return rb_ensure(init_inetsock_internal, (VALUE)&arg, - inetsock_cleanup, (VALUE)&arg); + inetsock_cleanup, (VALUE)&arg); } static ID id_numeric, id_hostname; @@ -201,11 +201,11 @@ rsock_revlookup_flag(VALUE revlookup, int *norevlookup) case Qfalse: return_norevlookup(1); case Qnil: break; default: - Check_Type(revlookup, T_SYMBOL); - id = SYM2ID(revlookup); - if (id == id_numeric) return_norevlookup(1); - if (id == id_hostname) return_norevlookup(0); - rb_raise(rb_eArgError, "invalid reverse_lookup flag: :%s", rb_id2name(id)); + Check_Type(revlookup, T_SYMBOL); + id = SYM2ID(revlookup); + if (id == id_numeric) return_norevlookup(1); + if (id == id_hostname) return_norevlookup(0); + rb_raise(rb_eArgError, "invalid reverse_lookup flag: :%s", rb_id2name(id)); } return 0; #undef return_norevlookup @@ -226,24 +226,24 @@ ip_inspect(VALUE sock) socklen_t len = (socklen_t)sizeof addr; ID id; if (fptr && fptr->fd >= 0 && - getsockname(fptr->fd, &addr.addr, &len) >= 0 && - (id = rsock_intern_family(addr.addr.sa_family)) != 0) { - VALUE family = rb_id2str(id); - char hbuf[1024], pbuf[1024]; - long slen = RSTRING_LEN(str); - const char last = (slen > 1 && RSTRING_PTR(str)[slen - 1] == '>') ? - (--slen, '>') : 0; - str = rb_str_subseq(str, 0, slen); - rb_str_cat_cstr(str, ", "); - rb_str_append(str, family); - if (!rb_getnameinfo(&addr.addr, len, hbuf, sizeof(hbuf), - pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { - rb_str_cat_cstr(str, ", "); - rb_str_cat_cstr(str, hbuf); - rb_str_cat_cstr(str, ", "); - rb_str_cat_cstr(str, pbuf); - } - if (last) rb_str_cat(str, &last, 1); + getsockname(fptr->fd, &addr.addr, &len) >= 0 && + (id = rsock_intern_family(addr.addr.sa_family)) != 0) { + VALUE family = rb_id2str(id); + char hbuf[1024], pbuf[1024]; + long slen = RSTRING_LEN(str); + const char last = (slen > 1 && RSTRING_PTR(str)[slen - 1] == '>') ? + (--slen, '>') : 0; + str = rb_str_subseq(str, 0, slen); + rb_str_cat_cstr(str, ", "); + rb_str_append(str, family); + if (!rb_getnameinfo(&addr.addr, len, hbuf, sizeof(hbuf), + pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { + rb_str_cat_cstr(str, ", "); + rb_str_cat_cstr(str, hbuf); + rb_str_cat_cstr(str, ", "); + rb_str_cat_cstr(str, pbuf); + } + if (last) rb_str_cat(str, &last, 1); } return str; } @@ -282,9 +282,9 @@ ip_addr(int argc, VALUE *argv, VALUE sock) GetOpenFile(sock, fptr); if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup)) - norevlookup = fptr->mode & FMODE_NOREVLOOKUP; + norevlookup = fptr->mode & FMODE_NOREVLOOKUP; if (getsockname(fptr->fd, &addr.addr, &len) < 0) - rb_sys_fail("getsockname(2)"); + rb_sys_fail("getsockname(2)"); return rsock_ipaddr(&addr.addr, len, norevlookup); } @@ -323,9 +323,9 @@ ip_peeraddr(int argc, VALUE *argv, VALUE sock) GetOpenFile(sock, fptr); if (argc < 1 || !rsock_revlookup_flag(argv[0], &norevlookup)) - norevlookup = fptr->mode & FMODE_NOREVLOOKUP; + norevlookup = fptr->mode & FMODE_NOREVLOOKUP; if (getpeername(fptr->fd, &addr.addr, &len) < 0) - rb_sys_fail("getpeername(2)"); + rb_sys_fail("getpeername(2)"); return rsock_ipaddr(&addr.addr, len, norevlookup); } diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index d756a32a5a..e953077fe6 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -1,7 +1,11 @@ # frozen_string_literal: true require 'socket.so' -require 'io/wait' + +unless IO.method_defined?(:wait_writable, false) + # It's only required on older Rubies < v3.2: + require 'io/wait' +end class Addrinfo # creates an Addrinfo object from the arguments. @@ -197,7 +201,7 @@ class Addrinfo sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? - sock.setsockopt(:SOCKET, :REUSEADDR, 1) + sock.setsockopt(:SOCKET, :REUSEADDR, 1) unless self.pfamily == Socket::PF_UNIX sock.bind(self) sock.listen(backlog) rescue Exception @@ -329,9 +333,10 @@ class BasicSocket < IO # _flags_ is zero or more of the +MSG_+ options. # The result, _mesg_, is the data received. # - # When recvfrom(2) returns 0, Socket#recv_nonblock returns - # an empty string as data. - # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc. + # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil. + # In most cases it means the connection was closed, but for UDP connections + # it may mean an empty packet was received, as the underlying API makes + # it impossible to distinguish these two cases. # # === Parameters # * +maxlen+ - the number of bytes to receive from the socket @@ -476,9 +481,10 @@ class Socket < BasicSocket # The second element, _sender_addrinfo_, contains protocol-specific address # information of the sender. # - # When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns - # an empty string as data. - # The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc. + # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil. + # In most cases it means the connection was closed, but for UDP connections + # it may mean an empty packet was received, as the underlying API makes + # it impossible to distinguish these two cases. # # === Parameters # * +maxlen+ - the maximum number of bytes to receive from the socket @@ -593,6 +599,30 @@ class Socket < BasicSocket __accept_nonblock(exception) end + RESOLUTION_DELAY = 0.05 + private_constant :RESOLUTION_DELAY + + CONNECTION_ATTEMPT_DELAY = 0.25 + private_constant :CONNECTION_ATTEMPT_DELAY + + ADDRESS_FAMILIES = { + ipv6: Socket::AF_INET6, + ipv4: Socket::AF_INET + }.freeze + private_constant :ADDRESS_FAMILIES + + HOSTNAME_RESOLUTION_QUEUE_UPDATED = 0 + private_constant :HOSTNAME_RESOLUTION_QUEUE_UPDATED + + IPV6_ADRESS_FORMAT = /(?i)(?:(?:[0-9A-F]{1,4}:){7}(?:[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){6}(?:[0-9A-F]{1,4}::[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:){1,5}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){5}(?::[0-9A-F]{1,4}::[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:){1,4}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){4}(?::[0-9A-F]{1,4}::[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:){1,3}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){3}(?::[0-9A-F]{1,4}::[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:){1,2}[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){2}(?::[0-9A-F]{1,4}::[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:)[0-9A-F]{1,4}|:)|(?:[0-9A-F]{1,4}:){1}(?::[0-9A-F]{1,4}::[0-9A-F]{1,4}|::(?:[0-9A-F]{1,4}:){1,5}[0-9A-F]{1,4}|:)|::(?:[0-9A-F]{1,4}::[0-9A-F]{1,4}|:(?:[0-9A-F]{1,4}:){1,6}[0-9A-F]{1,4}|:))(?:%.+)?/ + private_constant :IPV6_ADRESS_FORMAT + + @tcp_fast_fallback = true + + class << self + attr_accessor :tcp_fast_fallback + end + # :call-seq: # Socket.tcp(host, port, local_host=nil, local_port=nil, [opts]) {|socket| ... } # Socket.tcp(host, port, local_host=nil, local_port=nil, [opts]) @@ -606,7 +636,6 @@ class Socket < BasicSocket # _opts_ may have following options: # # [:connect_timeout] specify the timeout in seconds. - # [:resolv_timeout] specify the name resolution timeout in seconds. # # If a block is given, the block is called with the socket. # The value of the block is returned. @@ -619,8 +648,491 @@ class Socket < BasicSocket # sock.close_write # puts sock.read # } - # - def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil) # :yield: socket + def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil, fast_fallback: tcp_fast_fallback, &block) # :yield: socket + unless fast_fallback + return tcp_without_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, &block) + end + + # Happy Eyeballs' states + # - :start + # - :v6c + # - :v4w + # - :v4c + # - :v46c + # - :v46w + # - :success + # - :failure + # - :timeout + + specified_family_name = nil + hostname_resolution_threads = [] + hostname_resolution_queue = nil + hostname_resolution_waiting = nil + hostname_resolution_expires_at = nil + selectable_addrinfos = SelectableAddrinfos.new + connecting_sockets = ConnectingSockets.new + local_addrinfos = [] + connection_attempt_delay_expires_at = nil + connection_attempt_started_at = nil + state = :start + connected_socket = nil + last_error = nil + is_windows_environment ||= (RUBY_PLATFORM =~ /mswin|mingw|cygwin/) + + ret = loop do + case state + when :start + specified_family_name, next_state = host && specified_family_name_and_next_state(host) + + if local_host && local_port + specified_family_name, next_state = specified_family_name_and_next_state(local_host) unless specified_family_name + local_addrinfos = Addrinfo.getaddrinfo(local_host, local_port, ADDRESS_FAMILIES[specified_family_name], :STREAM, timeout: resolv_timeout) + end + + if specified_family_name + addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[specified_family_name], :STREAM, timeout: resolv_timeout) + selectable_addrinfos.add(specified_family_name, addrinfos) + hostname_resolution_queue = NoHostnameResolutionQueue.new + state = next_state + next + end + + resolving_family_names = ADDRESS_FAMILIES.keys + hostname_resolution_queue = HostnameResolutionQueue.new(resolving_family_names.size) + hostname_resolution_waiting = hostname_resolution_queue.waiting_pipe + hostname_resolution_started_at = current_clocktime if resolv_timeout + hostname_resolution_args = [host, port, hostname_resolution_queue] + + hostname_resolution_threads.concat( + resolving_family_names.map { |family| + thread_args = [family, *hostname_resolution_args] + thread = Thread.new(*thread_args) { |*thread_args| hostname_resolution(*thread_args) } + Thread.pass + thread + } + ) + + hostname_resolution_retry_count = resolving_family_names.size - 1 + hostname_resolution_expires_at = hostname_resolution_started_at + resolv_timeout if resolv_timeout + + while hostname_resolution_retry_count >= 0 + remaining = resolv_timeout ? second_to_timeout(hostname_resolution_started_at + resolv_timeout) : nil + hostname_resolved, _, = IO.select(hostname_resolution_waiting, nil, nil, remaining) + + unless hostname_resolved + state = :timeout + break + end + + family_name, res = hostname_resolution_queue.get + + if res.is_a? Exception + unless (Socket.const_defined?(:EAI_ADDRFAMILY)) && + (res.is_a?(Socket::ResolutionError)) && + (res.error_code == Socket::EAI_ADDRFAMILY) + last_error = res + end + + if hostname_resolution_retry_count.zero? + state = :failure + break + end + hostname_resolution_retry_count -= 1 + else + state = case family_name + when :ipv6 then :v6c + when :ipv4 then hostname_resolution_queue.closed? ? :v4c : :v4w + end + selectable_addrinfos.add(family_name, res) + last_error = nil + break + end + end + + next + when :v4w + ipv6_resolved, _, = IO.select(hostname_resolution_waiting, nil, nil, RESOLUTION_DELAY) + + if ipv6_resolved + family_name, res = hostname_resolution_queue.get + selectable_addrinfos.add(family_name, res) unless res.is_a? Exception + state = :v46c + else + state = :v4c + end + + next + when :v4c, :v6c, :v46c + connection_attempt_started_at = current_clocktime unless connection_attempt_started_at + addrinfo = selectable_addrinfos.get + + if local_addrinfos.any? + local_addrinfo = local_addrinfos.find { |lai| lai.afamily == addrinfo.afamily } + + if local_addrinfo.nil? + if selectable_addrinfos.empty? && connecting_sockets.empty? && hostname_resolution_queue.closed? + last_error = SocketError.new 'no appropriate local address' + state = :failure + elsif selectable_addrinfos.any? + # Try other Addrinfo in next loop + else + if resolv_timeout && hostname_resolution_queue.opened? && + (current_clocktime >= hostname_resolution_expires_at) + state = :timeout + else + # Wait for connection to be established or hostname resolution in next loop + connection_attempt_delay_expires_at = nil + state = :v46w + end + end + next + end + end + + connection_attempt_delay_expires_at = current_clocktime + CONNECTION_ATTEMPT_DELAY + + begin + result = if specified_family_name && selectable_addrinfos.empty? && + connecting_sockets.empty? && hostname_resolution_queue.closed? + local_addrinfo ? + addrinfo.connect_from(local_addrinfo, timeout: connect_timeout) : + addrinfo.connect(timeout: connect_timeout) + else + socket = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) + socket.bind(local_addrinfo) if local_addrinfo + socket.connect_nonblock(addrinfo, exception: false) + end + + case result + when 0 + connected_socket = socket + state = :success + when Socket + connected_socket = result + state = :success + when :wait_writable + connecting_sockets.add(socket, addrinfo) + state = :v46w + end + rescue SystemCallError => e + last_error = e + socket.close if socket && !socket.closed? + + if selectable_addrinfos.empty? && connecting_sockets.empty? && hostname_resolution_queue.closed? + state = :failure + elsif selectable_addrinfos.any? + # Try other Addrinfo in next loop + else + if resolv_timeout && hostname_resolution_queue.opened? && + (current_clocktime >= hostname_resolution_expires_at) + state = :timeout + else + # Wait for connection to be established or hostname resolution in next loop + connection_attempt_delay_expires_at = nil + state = :v46w + end + end + end + + next + when :v46w + if connect_timeout && second_to_timeout(connection_attempt_started_at + connect_timeout).zero? + state = :timeout + next + end + + remaining = second_to_timeout(connection_attempt_delay_expires_at) + hostname_resolution_waiting = hostname_resolution_waiting && hostname_resolution_queue.closed? ? nil : hostname_resolution_waiting + hostname_resolved, connectable_sockets, = IO.select(hostname_resolution_waiting, connecting_sockets.all, nil, remaining) + + if connectable_sockets&.any? + while (connectable_socket = connectable_sockets.pop) + is_connected = + if is_windows_environment + sockopt = connectable_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_CONNECT_TIME) + sockopt.unpack('i').first >= 0 + else + sockopt = connectable_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR) + sockopt.int.zero? + end + + if is_connected + connected_socket = connectable_socket + connecting_sockets.delete connectable_socket + connectable_sockets.each do |other_connectable_socket| + other_connectable_socket.close unless other_connectable_socket.closed? + end + state = :success + break + else + failed_ai = connecting_sockets.delete connectable_socket + inspected_ip_address = failed_ai.ipv6? ? "[#{failed_ai.ip_address}]" : failed_ai.ip_address + last_error = SystemCallError.new("connect(2) for #{inspected_ip_address}:#{failed_ai.ip_port}", sockopt.int) + connectable_socket.close unless connectable_socket.closed? + + next if connectable_sockets.any? + + if selectable_addrinfos.empty? && connecting_sockets.empty? && hostname_resolution_queue.closed? + state = :failure + elsif selectable_addrinfos.any? + # Wait for connection attempt delay timeout in next loop + else + if resolv_timeout && hostname_resolution_queue.opened? && + (current_clocktime >= hostname_resolution_expires_at) + state = :timeout + else + # Wait for connection to be established or hostname resolution in next loop + connection_attempt_delay_expires_at = nil + end + end + end + end + elsif hostname_resolved&.any? + family_name, res = hostname_resolution_queue.get + selectable_addrinfos.add(family_name, res) unless res.is_a? Exception + else + if selectable_addrinfos.empty? && connecting_sockets.empty? && hostname_resolution_queue.closed? + state = :failure + elsif selectable_addrinfos.any? + # Try other Addrinfo in next loop + state = :v46c + else + if resolv_timeout && hostname_resolution_queue.opened? && + (current_clocktime >= hostname_resolution_expires_at) + state = :timeout + else + # Wait for connection to be established or hostname resolution in next loop + connection_attempt_delay_expires_at = nil + end + end + end + + next + when :success + break connected_socket + when :failure + raise last_error + when :timeout + raise Errno::ETIMEDOUT, 'user specified timeout' + end + end + + if block_given? + begin + yield ret + ensure + ret.close + end + else + ret + end + ensure + if fast_fallback + hostname_resolution_threads.each do |thread| + thread&.exit + end + + hostname_resolution_queue&.close_all + + connecting_sockets.each do |connecting_socket| + connecting_socket.close unless connecting_socket.closed? + end + end + end + + def self.specified_family_name_and_next_state(hostname) + if hostname.match?(IPV6_ADRESS_FORMAT) then [:ipv6, :v6c] + elsif hostname.match?(/^([0-9]{1,3}\.){3}[0-9]{1,3}$/) then [:ipv4, :v4c] + end + end + private_class_method :specified_family_name_and_next_state + + def self.hostname_resolution(family, host, port, hostname_resolution_queue) + begin + resolved_addrinfos = Addrinfo.getaddrinfo(host, port, ADDRESS_FAMILIES[family], :STREAM) + hostname_resolution_queue.add_resolved(family, resolved_addrinfos) + rescue => e + hostname_resolution_queue.add_error(family, e) + end + end + private_class_method :hostname_resolution + + def self.second_to_timeout(ends_at) + return 0 unless ends_at + + remaining = (ends_at - current_clocktime) + remaining.negative? ? 0 : remaining + end + private_class_method :second_to_timeout + + def self.current_clocktime + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + private_class_method :current_clocktime + + class SelectableAddrinfos + PRIORITY_ON_V6 = [:ipv6, :ipv4] + PRIORITY_ON_V4 = [:ipv4, :ipv6] + + def initialize + @addrinfo_dict = {} + @last_family = nil + end + + def add(family_name, addrinfos) + @addrinfo_dict[family_name] = addrinfos + end + + def get + return nil if empty? + + if @addrinfo_dict.size == 1 + @addrinfo_dict.each { |_, addrinfos| return addrinfos.shift } + end + + precedences = case @last_family + when :ipv4, nil then PRIORITY_ON_V6 + when :ipv6 then PRIORITY_ON_V4 + end + + precedences.each do |family_name| + addrinfo = @addrinfo_dict[family_name]&.shift + next unless addrinfo + + @last_family = family_name + return addrinfo + end + end + + def empty? + @addrinfo_dict.all? { |_, addrinfos| addrinfos.empty? } + end + + def any? + !empty? + end + end + private_constant :SelectableAddrinfos + + class NoHostnameResolutionQueue + def waiting_pipe + nil + end + + def add_resolved(_, _) + raise StandardError, "This #{self.class} cannot respond to:" + end + + def add_error(_, _) + raise StandardError, "This #{self.class} cannot respond to:" + end + + def get + nil + end + + def opened? + false + end + + def closed? + true + end + + def close_all + # Do nothing + end + end + private_constant :NoHostnameResolutionQueue + + class HostnameResolutionQueue + def initialize(size) + @size = size + @taken_count = 0 + @rpipe, @wpipe = IO.pipe + @queue = Queue.new + @mutex = Mutex.new + end + + def waiting_pipe + [@rpipe] + end + + def add_resolved(family, resolved_addrinfos) + @mutex.synchronize do + @queue.push [family, resolved_addrinfos] + @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED + end + end + + def add_error(family, error) + @mutex.synchronize do + @queue.push [family, error] + @wpipe.putc HOSTNAME_RESOLUTION_QUEUE_UPDATED + end + end + + def get + return nil if @queue.empty? + + res = nil + + @mutex.synchronize do + @rpipe.getbyte + res = @queue.pop + end + + @taken_count += 1 + close_all if @taken_count == @size + res + end + + def closed? + @rpipe.closed? + end + + def opened? + !closed? + end + + def close_all + @queue.close unless @queue.closed? + @rpipe.close unless @rpipe.closed? + @wpipe.close unless @wpipe.closed? + end + end + private_constant :HostnameResolutionQueue + + class ConnectingSockets + def initialize + @socket_dict = {} + end + + def all + @socket_dict.keys + end + + def add(socket, addrinfo) + @socket_dict[socket] = addrinfo + end + + def delete(socket) + @socket_dict.delete socket + end + + def empty? + @socket_dict.empty? + end + + def each + @socket_dict.keys.each do |socket| + yield socket + end + end + end + private_constant :ConnectingSockets + + def self.tcp_without_fast_fallback(host, port, local_host, local_port, connect_timeout:, resolv_timeout:, &block) last_error = nil ret = nil @@ -664,6 +1176,7 @@ class Socket < BasicSocket ret end end + private_class_method :tcp_without_fast_fallback # :stopdoc: def self.ip_sockets_port0(ai_list, reuseaddr) @@ -1226,9 +1739,10 @@ class UDPSocket < IPSocket # The first element of the results, _mesg_, is the data received. # The second element, _sender_inet_addr_, is an array to represent the sender address. # - # When recvfrom(2) returns 0, - # Socket#recvfrom_nonblock returns an empty string as data. - # It means an empty packet. + # When recvfrom(2) returns 0, Socket#recv_nonblock returns nil. + # In most cases it means the connection was closed, but it may also mean + # an empty packet was received, as the underlying API makes + # it impossible to distinguish these two cases. # # === Parameters # * +maxlen+ - the number of bytes to receive from the socket diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb index 577958a358..4271e40cd8 100644 --- a/ext/socket/mkconstants.rb +++ b/ext/socket/mkconstants.rb @@ -51,7 +51,10 @@ DATA.each_line {|s| next end h[name] = default_value - COMMENTS[name] = comment + if comment + # Stop unintentional references + COMMENTS[name] = comment.gsub(/\b(Data|Kernel|Process|Set|Socket|Time)\b/, '\\\\\\&') + end } DEFS = h.to_a @@ -73,15 +76,11 @@ def each_name(pat) } end -erb_new = lambda do |src, safe, trim| - if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ - ERB.new(src, trim_mode: trim) - else - ERB.new(src, safe, trim) - end +erb_new = lambda do |src, trim| + ERB.new(src, trim_mode: trim) end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_decls") % each_const {|guard, name, default_value| #if !defined(<%=name%>) # if defined(HAVE_CONST_<%=name.upcase%>) @@ -95,7 +94,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") % } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)") #if defined(<%=name%>) /* <%= COMMENTS[name] %> */ rb_define_const(rb_cSocket, <%=c_str name%>, INTEGER2NUM(<%=name%>)); @@ -104,7 +103,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name #endif EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_defs") % each_const {|guard, name, default_value| % if guard #if <%=guard%> @@ -154,7 +153,7 @@ def each_names_with_len(pat, prefix_optional=nil) } end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)") %if guard #ifdef <%=guard%> int <%=funcname%>(const char *str, long len, int *valp); @@ -164,7 +163,7 @@ int <%=funcname%>(const char *str, long len, int *valp); %end EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)") int <%=funcname%>(const char *str, long len, int *valp) { @@ -186,7 +185,7 @@ int } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)") %if guard #ifdef <%=guard%> <%=gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard)%> @@ -215,7 +214,7 @@ def reverse_each_name_with_prefix_optional(pat, prefix_pat) end end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)") <%=hash_var%> = st_init_numtable(); % reverse_each_name_with_prefix_optional(pat, prefix_pat) {|n,s| #ifdef <%=n%> @@ -224,7 +223,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_va % } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)") ID <%=func_name%>(int val) { @@ -235,7 +234,7 @@ ID } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)") ID <%=func_name%>(int val); EOS @@ -284,7 +283,7 @@ def_intern('rsock_intern_udp_optname', /\AUDP_/, "UDP_") def_intern('rsock_intern_scm_optname', /\ASCM_/, "SCM_") def_intern('rsock_intern_local_optname', /\ALOCAL_/, "LOCAL_") -result = erb_new.call(<<'EOS', nil, '%').result(binding) +result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ <%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| vardef }.join("\n") %> @@ -327,7 +326,7 @@ init_constants(void) EOS -header_result = erb_new.call(<<'EOS', nil, '%').result(binding) +header_result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ <%= gen_const_decls %> <%= NAME_TO_INT_DEFS.map {|decl, func| decl }.join("\n") %> @@ -423,8 +422,8 @@ AF_ISDN nil Integrated Services Digital Network PF_ISDN nil Integrated Services Digital Network AF_NATM nil Native ATM access PF_NATM nil Native ATM access -AF_SYSTEM -PF_SYSTEM +AF_SYSTEM nil Kernel event messages +PF_SYSTEM nil Kernel event messages AF_NETBIOS nil NetBIOS PF_NETBIOS nil NetBIOS AF_PPP nil Point-to-Point Protocol @@ -440,8 +439,8 @@ PF_PACKET nil Direct link-layer access AF_E164 nil CCITT (ITU-T) E.164 recommendation PF_XTP nil eXpress Transfer Protocol -PF_RTIP -PF_PIP +PF_RTIP nil Help Identify RTIP packets +PF_PIP nil Help Identify PIP packets AF_KEY nil Key management protocol, originally developed for usage with IPsec PF_KEY nil Key management protocol, originally developed for usage with IPsec AF_NETLINK nil Kernel user interface device @@ -626,6 +625,7 @@ SO_SNDTIMEO nil Send timeout SO_ACCEPTCONN nil Socket has had listen() called on it SO_USELOOPBACK nil Bypass hardware when possible SO_ACCEPTFILTER nil There is an accept filter +SO_USER_COOKIE nil Setting an identifier for ipfw purpose mainly SO_DONTTRUNC nil Retain unread data SO_WANTMORE nil Give a hint when more data is ready SO_WANTOOBFLAG nil OOB data is wanted in MSG_FLAG on receive @@ -661,6 +661,11 @@ SO_SELECT_ERR_QUEUE nil Make select() detect socket error queue with err SO_BUSY_POLL nil Set the threshold in microseconds for low latency polling (Linux 3.11) SO_MAX_PACING_RATE nil Cap the rate computed by transport layer. [bytes per second] (Linux 3.13) SO_BPF_EXTENSIONS nil Query supported BPF extensions (Linux 3.14) +SO_SETFIB nil Set the associated routing table for the socket (FreeBSD) +SO_RTABLE nil Set the routing table for this socket (OpenBSD) +SO_INCOMING_CPU nil Receive the cpu attached to the socket (Linux 3.19) +SO_INCOMING_NAPI_ID nil Receive the napi ID attached to a RX queue (Linux 4.12) +SO_CONNECT_TIME nil Returns the number of seconds a socket has been connected. This option is only valid for connection-oriented protocols (Windows) SOPRI_INTERACTIVE nil Interactive socket priority SOPRI_NORMAL nil Normal socket priority @@ -670,9 +675,11 @@ IPX_TYPE TCP_NODELAY nil Don't delay sending to coalesce packets TCP_MAXSEG nil Set maximum segment size +TCP_CONNECTION_INFO nil Retrieve information about this socket (macOS) TCP_CORK nil Don't send partial frames (Linux 2.2, glibc 2.2) TCP_DEFER_ACCEPT nil Don't notify a listening socket until data is ready (Linux 2.4, glibc 2.2) TCP_INFO nil Retrieve information about this socket (Linux 2.4, glibc 2.2) +TCP_KEEPALIVE nil Idle time before keepalive probes are sent (macOS) TCP_KEEPCNT nil Maximum number of keepalive probes allowed before dropping a connection (Linux 2.4, glibc 2.2) TCP_KEEPIDLE nil Idle time before keepalive probes are sent (Linux 2.4, glibc 2.2) TCP_KEEPINTVL nil Time between keepalive probes (Linux 2.4, glibc 2.2) @@ -738,6 +745,7 @@ SHUT_RDWR 2 Shut down the both sides of the socket IPV6_JOIN_GROUP nil Join a group membership IPV6_LEAVE_GROUP nil Leave a group membership +IPV6_MTU_DISCOVER nil Path MTU discovery IPV6_MULTICAST_HOPS nil IP6 multicast hops IPV6_MULTICAST_IF nil IP6 multicast interface IPV6_MULTICAST_LOOP nil IP6 multicast loopback @@ -752,6 +760,7 @@ IPV6_NEXTHOP nil Next hop address IPV6_PATHMTU nil Retrieve current path MTU IPV6_PKTINFO nil Receive packet information with datagram IPV6_RECVDSTOPTS nil Receive all IP6 options for response +IPV6_RECVERR nil Enable extended reliable error message passing IPV6_RECVHOPLIMIT nil Receive hop limit with datagram IPV6_RECVHOPOPTS nil Receive hop-by-hop options IPV6_RECVPKTINFO nil Receive destination IP address and incoming interface diff --git a/ext/socket/option.c b/ext/socket/option.c index 4b33b3f1d3..0d818d0c70 100644 --- a/ext/socket/option.c +++ b/ext/socket/option.c @@ -31,7 +31,7 @@ VALUE rb_cSockOpt; ((len) == (size) ? \ (void)0 : \ rb_raise(rb_eTypeError, "size differ. expected as "#size"=%d but %ld", \ - (int)size, (long)(len))) + (int)size, (long)(len))) static VALUE sockopt_pack_byte(VALUE value) @@ -309,7 +309,7 @@ sockopt_bool(VALUE self) StringValue(data); len = RSTRING_LEN(data); if (len == 1) { - return *RSTRING_PTR(data) == 0 ? Qfalse : Qtrue; + return *RSTRING_PTR(data) == 0 ? Qfalse : Qtrue; } check_size(len, sizeof(int)); memcpy((char*)&i, RSTRING_PTR(data), len); @@ -420,7 +420,7 @@ sockopt_ipv4_multicast_loop(VALUE self) #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP) if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_LOOP) { - return XCAT(sockopt_,TYPE_IP_MULTICAST_LOOP)(self); + return XCAT(sockopt_,TYPE_IP_MULTICAST_LOOP)(self); } #endif rb_raise(rb_eTypeError, "ipv4_multicast_loop socket option expected"); @@ -471,7 +471,7 @@ sockopt_ipv4_multicast_ttl(VALUE self) #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL) if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_TTL) { - return XCAT(sockopt_,TYPE_IP_MULTICAST_TTL)(self); + return XCAT(sockopt_,TYPE_IP_MULTICAST_TTL)(self); } #endif rb_raise(rb_eTypeError, "ipv4_multicast_ttl socket option expected"); @@ -657,8 +657,8 @@ inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len) #else unsigned long x = ntohl(*(unsigned long*)addr); snprintf(numaddr, numaddr_len, "%d.%d.%d.%d", - (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, - (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff); + (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, + (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff); #endif return numaddr; } @@ -670,10 +670,10 @@ rb_if_indextoname(const char *succ_prefix, const char *fail_prefix, unsigned int { #if defined(HAVE_IF_INDEXTONAME) char ifbuf[IFNAMSIZ]; - if (if_indextoname(ifindex, ifbuf) == NULL) - return snprintf(buf, len, "%s%u", fail_prefix, ifindex); - else + if (if_indextoname(ifindex, ifbuf)) return snprintf(buf, len, "%s%s", succ_prefix, ifbuf); + else + return snprintf(buf, len, "%s%u", fail_prefix, ifindex); #else # ifndef IFNAMSIZ # define IFNAMSIZ (sizeof(unsigned int)*3+1) @@ -1059,16 +1059,16 @@ inspect_tcp_info(int level, int optname, VALUE data, VALUE ret) rb_str_catf(ret, " fackets=%u", s.tcpi_fackets); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_DATA_SENT - inspect_tcpi_last_data_sent(ret, s.tcpi_last_data_sent); + inspect_tcpi_last_data_sent(ret, s.tcpi_last_data_sent); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_ACK_SENT - inspect_tcpi_last_ack_sent(ret, s.tcpi_last_ack_sent); + inspect_tcpi_last_ack_sent(ret, s.tcpi_last_ack_sent); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_DATA_RECV - inspect_tcpi_last_data_recv(ret, s.tcpi_last_data_recv); + inspect_tcpi_last_data_recv(ret, s.tcpi_last_data_recv); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_LAST_ACK_RECV - inspect_tcpi_last_ack_recv(ret, s.tcpi_last_ack_recv); + inspect_tcpi_last_ack_recv(ret, s.tcpi_last_ack_recv); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_PMTU rb_str_catf(ret, " pmtu=%u", s.tcpi_pmtu); @@ -1077,10 +1077,10 @@ inspect_tcp_info(int level, int optname, VALUE data, VALUE ret) rb_str_catf(ret, " rcv_ssthresh=%u", s.tcpi_rcv_ssthresh); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_RTT - inspect_tcpi_rtt(ret, s.tcpi_rtt); + inspect_tcpi_rtt(ret, s.tcpi_rtt); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_RTTVAR - inspect_tcpi_rttvar(ret, s.tcpi_rttvar); + inspect_tcpi_rttvar(ret, s.tcpi_rttvar); #endif #ifdef HAVE_STRUCT_TCP_INFO_TCPI_SND_SSTHRESH rb_str_catf(ret, " snd_ssthresh=%u", s.tcpi_snd_ssthresh); @@ -1150,7 +1150,7 @@ inspect_peercred(int level, int optname, VALUE data, VALUE ret) RUBY_SOCK_PEERCRED cred; memcpy(&cred, RSTRING_PTR(data), sizeof(RUBY_SOCK_PEERCRED)); rb_str_catf(ret, " pid=%u euid=%u egid=%u", - (unsigned)cred.pid, (unsigned)cred.uid, (unsigned)cred.gid); + (unsigned)cred.pid, (unsigned)cred.uid, (unsigned)cred.gid); rb_str_cat2(ret, " (ucred)"); return 1; } @@ -1171,14 +1171,14 @@ inspect_local_peercred(int level, int optname, VALUE data, VALUE ret) return 0; rb_str_catf(ret, " version=%u", cred.cr_version); rb_str_catf(ret, " euid=%u", cred.cr_uid); - if (cred.cr_ngroups) { - int i; - const char *sep = " groups="; - for (i = 0; i < cred.cr_ngroups; i++) { - rb_str_catf(ret, "%s%u", sep, cred.cr_groups[i]); - sep = ","; - } - } + if (cred.cr_ngroups) { + int i; + const char *sep = " groups="; + for (i = 0; i < cred.cr_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred.cr_groups[i]); + sep = ","; + } + } rb_str_cat2(ret, " (xucred)"); return 1; } @@ -1216,42 +1216,42 @@ sockopt_inspect(VALUE self) family_id = rsock_intern_family_noprefix(family); if (family_id) - rb_str_catf(ret, " %s", rb_id2name(family_id)); + rb_str_catf(ret, " %s", rb_id2name(family_id)); else rb_str_catf(ret, " family:%d", family); if (level == SOL_SOCKET) { rb_str_cat2(ret, " SOCKET"); - optname_id = rsock_intern_so_optname(optname); - if (optname_id) - rb_str_catf(ret, " %s", rb_id2name(optname_id)); - else - rb_str_catf(ret, " optname:%d", optname); + optname_id = rsock_intern_so_optname(optname); + if (optname_id) + rb_str_catf(ret, " %s", rb_id2name(optname_id)); + else + rb_str_catf(ret, " optname:%d", optname); } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN else if (family == AF_UNIX) { - rb_str_catf(ret, " level:%d", level); + rb_str_catf(ret, " level:%d", level); - optname_id = rsock_intern_local_optname(optname); - if (optname_id) - rb_str_catf(ret, " %s", rb_id2name(optname_id)); - else - rb_str_catf(ret, " optname:%d", optname); + optname_id = rsock_intern_local_optname(optname); + if (optname_id) + rb_str_catf(ret, " %s", rb_id2name(optname_id)); + else + rb_str_catf(ret, " optname:%d", optname); } #endif else if (IS_IP_FAMILY(family)) { - level_id = rsock_intern_iplevel(level); - if (level_id) - rb_str_catf(ret, " %s", rb_id2name(level_id)); - else - rb_str_catf(ret, " level:%d", level); - - v = optname_to_sym(level, optname); - if (SYMBOL_P(v)) - rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(v)); - else - rb_str_catf(ret, " optname:%d", optname); + level_id = rsock_intern_iplevel(level); + if (level_id) + rb_str_catf(ret, " %s", rb_id2name(level_id)); + else + rb_str_catf(ret, " level:%d", level); + + v = optname_to_sym(level, optname); + if (SYMBOL_P(v)) + rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(v)); + else + rb_str_catf(ret, " optname:%d", optname); } else { rb_str_catf(ret, " level:%d", level); @@ -1393,7 +1393,7 @@ sockopt_inspect(VALUE self) } break; -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: switch (level) { case 0: diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index d94e96a2bc..e79bcfa332 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -10,6 +10,22 @@ #include "rubysocket.h" +// GETADDRINFO_IMPL == 0 : call getaddrinfo/getnameinfo directly +// GETADDRINFO_IMPL == 1 : call getaddrinfo/getnameinfo without gvl (but uncancellable) +// GETADDRINFO_IMPL == 2 : call getaddrinfo/getnameinfo in a dedicated pthread +// (and if the call is interrupted, the pthread is detached) + +#ifndef GETADDRINFO_IMPL +# ifdef GETADDRINFO_EMU +# define GETADDRINFO_IMPL 0 +# elif !defined(HAVE_PTHREAD_CREATE) || !defined(HAVE_PTHREAD_DETACH) || defined(__MINGW32__) || defined(__MINGW64__) +# define GETADDRINFO_IMPL 1 +# else +# define GETADDRINFO_IMPL 2 +# include "ruby/thread_native.h" +# endif +#endif + #if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6)) #define LOOKUP_ORDERS (sizeof(lookup_order_table) / sizeof(lookup_order_table[0])) static const int lookup_order_table[] = { @@ -24,28 +40,28 @@ static const int lookup_order_table[] = { static int ruby_getaddrinfo(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo tmp_hints; int i, af, error; if (hints->ai_family != PF_UNSPEC) { - return getaddrinfo(nodename, servname, hints, res); + return getaddrinfo(nodename, servname, hints, res); } for (i = 0; i < LOOKUP_ORDERS; i++) { - af = lookup_order_table[i]; - MEMCPY(&tmp_hints, hints, struct addrinfo, 1); - tmp_hints.ai_family = af; - error = getaddrinfo(nodename, servname, &tmp_hints, res); - if (error) { - if (tmp_hints.ai_family == PF_UNSPEC) { - break; - } - } - else { - break; - } + af = lookup_order_table[i]; + MEMCPY(&tmp_hints, hints, struct addrinfo, 1); + tmp_hints.ai_family = af; + error = getaddrinfo(nodename, servname, &tmp_hints, res); + if (error) { + if (tmp_hints.ai_family == PF_UNSPEC) { + break; + } + } + else { + break; + } } return error; @@ -56,17 +72,17 @@ ruby_getaddrinfo(const char *nodename, const char *servname, #if defined(_AIX) static int ruby_getaddrinfo__aix(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { int error = getaddrinfo(nodename, servname, hints, res); struct addrinfo *r; if (error) - return error; + return error; for (r = *res; r != NULL; r = r->ai_next) { - if (r->ai_addr->sa_family == 0) - r->ai_addr->sa_family = r->ai_family; - if (r->ai_addr->sa_len == 0) - r->ai_addr->sa_len = r->ai_addrlen; + if (r->ai_addr->sa_family == 0) + r->ai_addr->sa_family = r->ai_family; + if (r->ai_addr->sa_len == 0) + r->ai_addr->sa_len = r->ai_addrlen; } return 0; } @@ -74,21 +90,21 @@ ruby_getaddrinfo__aix(const char *nodename, const char *servname, #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res)) static int ruby_getnameinfo__aix(const struct sockaddr *sa, size_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags) + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) { struct sockaddr_in6 *sa6; u_int32_t *a6; if (sa->sa_family == AF_INET6) { - sa6 = (struct sockaddr_in6 *)sa; - a6 = sa6->sin6_addr.u6_addr.u6_addr32; + sa6 = (struct sockaddr_in6 *)sa; + a6 = sa6->sin6_addr.u6_addr.u6_addr32; - if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { - strncpy(host, "::", hostlen); - snprintf(serv, servlen, "%d", sa6->sin6_port); - return 0; - } + if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { + strncpy(host, "::", hostlen); + snprintf(serv, servlen, "%d", sa6->sin6_port); + return 0; + } } return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); } @@ -102,7 +118,7 @@ static int str_is_number(const char *); #if defined(__APPLE__) static int ruby_getaddrinfo__darwin(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { /* fix [ruby-core:29427] */ const char *tmp_servname; @@ -112,12 +128,12 @@ ruby_getaddrinfo__darwin(const char *nodename, const char *servname, tmp_servname = servname; MEMCPY(&tmp_hints, hints, struct addrinfo, 1); if (nodename && servname) { - if (str_is_number(tmp_servname) && atoi(servname) == 0) { - tmp_servname = NULL; + if (str_is_number(tmp_servname) && atoi(servname) == 0) { + tmp_servname = NULL; #ifdef AI_NUMERICSERV - if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV; + if (tmp_hints.ai_flags) tmp_hints.ai_flags &= ~AI_NUMERICSERV; #endif - } + } } error = getaddrinfo(nodename, tmp_servname, &tmp_hints, res); @@ -173,32 +189,6 @@ parse_numeric_port(const char *service, int *portp) } #endif -#ifndef GETADDRINFO_EMU -struct getaddrinfo_arg -{ - const char *node; - const char *service; - const struct addrinfo *hints; - struct addrinfo **res; -}; - -static void * -nogvl_getaddrinfo(void *arg) -{ - int ret; - struct getaddrinfo_arg *ptr = arg; - ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res); -#ifdef __linux__ - /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and - * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] - */ - if (ret == EAI_SYSTEM && errno == ENOENT) - ret = EAI_NONAME; -#endif - return (void *)(VALUE)ret; -} -#endif - static int numeric_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, @@ -212,15 +202,15 @@ numeric_getaddrinfo(const char *node, const char *service, int port; if (node && parse_numeric_port(service, &port)) { - static const struct { - int socktype; - int protocol; - } list[] = { - { SOCK_STREAM, IPPROTO_TCP }, - { SOCK_DGRAM, IPPROTO_UDP }, - { SOCK_RAW, 0 } - }; - struct addrinfo *ai = NULL; + static const struct { + int socktype; + int protocol; + } list[] = { + { SOCK_STREAM, IPPROTO_TCP }, + { SOCK_DGRAM, IPPROTO_UDP }, + { SOCK_RAW, 0 } + }; + struct addrinfo *ai = NULL; int hint_family = hints ? hints->ai_family : PF_UNSPEC; int hint_socktype = hints ? hints->ai_socktype : 0; int hint_protocol = hints ? hints->ai_protocol : 0; @@ -302,7 +292,263 @@ rb_freeaddrinfo(struct rb_addrinfo *ai) xfree(ai); } -#ifndef GETADDRINFO_EMU +#if GETADDRINFO_IMPL == 0 + +static int +rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai) +{ + return getaddrinfo(hostp, portp, hints, ai); +} + +#elif GETADDRINFO_IMPL == 1 + +struct getaddrinfo_arg +{ + const char *node; + const char *service; + const struct addrinfo *hints; + struct addrinfo **res; +}; + +static void * +nogvl_getaddrinfo(void *arg) +{ + int ret; + struct getaddrinfo_arg *ptr = arg; + ret = getaddrinfo(ptr->node, ptr->service, ptr->hints, ptr->res); +#ifdef __linux__ + /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and + * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] + */ + if (ret == EAI_SYSTEM && errno == ENOENT) + ret = EAI_NONAME; +#endif + return (void *)(VALUE)ret; +} + +static int +rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai) +{ + struct getaddrinfo_arg arg; + MEMZERO(&arg, struct getaddrinfo_arg, 1); + arg.node = hostp; + arg.service = portp; + arg.hints = hints; + arg.res = ai; + return (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0); +} + +#elif GETADDRINFO_IMPL == 2 + +struct getaddrinfo_arg +{ + char *node, *service; + struct addrinfo hints; + struct addrinfo *ai; + int err, gai_errno, refcount, done, cancelled; + rb_nativethread_lock_t lock; + rb_nativethread_cond_t cond; +}; + +static struct getaddrinfo_arg * +allocate_getaddrinfo_arg(const char *hostp, const char *portp, const struct addrinfo *hints) +{ + size_t hostp_offset = sizeof(struct getaddrinfo_arg); + size_t portp_offset = hostp_offset + (hostp ? strlen(hostp) + 1 : 0); + size_t bufsize = portp_offset + (portp ? strlen(portp) + 1 : 0); + + char *buf = malloc(bufsize); + if (!buf) { + rb_gc(); + buf = malloc(bufsize); + if (!buf) return NULL; + } + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)buf; + + if (hostp) { + arg->node = buf + hostp_offset; + strcpy(arg->node, hostp); + } + else { + arg->node = NULL; + } + + if (portp) { + arg->service = buf + portp_offset; + strcpy(arg->service, portp); + } + else { + arg->service = NULL; + } + + arg->hints = *hints; + arg->ai = NULL; + + arg->refcount = 2; + arg->done = arg->cancelled = 0; + + rb_nativethread_lock_initialize(&arg->lock); + rb_native_cond_initialize(&arg->cond); + + return arg; +} + +static void +free_getaddrinfo_arg(struct getaddrinfo_arg *arg) +{ + rb_native_cond_destroy(&arg->cond); + rb_nativethread_lock_destroy(&arg->lock); + free(arg); +} + +static void * +do_getaddrinfo(void *ptr) +{ + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr; + + int err, gai_errno; + err = getaddrinfo(arg->node, arg->service, &arg->hints, &arg->ai); + gai_errno = errno; +#ifdef __linux__ + /* On Linux (mainly Ubuntu 13.04) /etc/nsswitch.conf has mdns4 and + * it cause getaddrinfo to return EAI_SYSTEM/ENOENT. [ruby-list:49420] + */ + if (err == EAI_SYSTEM && errno == ENOENT) + err = EAI_NONAME; +#endif + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + { + arg->err = err; + arg->gai_errno = gai_errno; + if (arg->cancelled) { + freeaddrinfo(arg->ai); + } + else { + arg->done = 1; + rb_native_cond_signal(&arg->cond); + } + if (--arg->refcount == 0) need_free = 1; + } + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getaddrinfo_arg(arg); + + return 0; +} + +static void * +wait_getaddrinfo(void *ptr) +{ + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + while (!arg->done && !arg->cancelled) { + rb_native_cond_wait(&arg->cond, &arg->lock); + } + rb_nativethread_lock_unlock(&arg->lock); + return 0; +} + +static void +cancel_getaddrinfo(void *ptr) +{ + struct getaddrinfo_arg *arg = (struct getaddrinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + { + arg->cancelled = 1; + rb_native_cond_signal(&arg->cond); + } + rb_nativethread_lock_unlock(&arg->lock); +} + +static int +do_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg) +{ + int limit = 3, ret; + do { + // It is said that pthread_create may fail spuriously, so we follow the JDK and retry several times. + // + // https://bugs.openjdk.org/browse/JDK-8268605 + // https://github.com/openjdk/jdk/commit/e35005d5ce383ddd108096a3079b17cb0bcf76f1 + ret = pthread_create(th, 0, start_routine, arg); + } while (ret == EAGAIN && limit-- > 0); + return ret; +} + +static int +rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai) +{ + int retry; + struct getaddrinfo_arg *arg; + int err, gai_errno = 0; + +start: + retry = 0; + + arg = allocate_getaddrinfo_arg(hostp, portp, hints); + if (!arg) { + return EAI_MEMORY; + } + + pthread_t th; + if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { + free_getaddrinfo_arg(arg); + return EAI_AGAIN; + } + pthread_detach(th); + + rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg); + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + { + if (arg->done) { + err = arg->err; + gai_errno = arg->gai_errno; + if (err == 0) *ai = arg->ai; + } + else if (arg->cancelled) { + err = EAI_AGAIN; + } + else { + // If already interrupted, rb_thread_call_without_gvl2 may return without calling wait_getaddrinfo. + // In this case, it could be !arg->done && !arg->cancelled. + arg->cancelled = 1; // to make do_getaddrinfo call freeaddrinfo + retry = 1; + } + if (--arg->refcount == 0) need_free = 1; + } + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getaddrinfo_arg(arg); + + // If the current thread is interrupted by asynchronous exception, the following raises the exception. + // But if the current thread is interrupted by timer thread, the following returns; we need to manually retry. + rb_thread_check_ints(); + if (retry) goto start; + + /* Because errno is threadlocal, the errno value we got from the call to getaddrinfo() in the thread + * (in case of EAI_SYSTEM return value) is not propagated to the caller of _this_ function. Set errno + * explicitly, as round-tripped through struct getaddrinfo_arg, to deal with that */ + if (gai_errno) errno = gai_errno; + return err; +} + +#endif + +#if GETADDRINFO_IMPL == 0 + +int +rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) +{ + return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); +} + +#elif GETADDRINFO_IMPL == 1 + struct getnameinfo_arg { const struct sockaddr *sa; @@ -319,20 +565,15 @@ nogvl_getnameinfo(void *arg) { struct getnameinfo_arg *ptr = arg; return (void *)(VALUE)getnameinfo(ptr->sa, ptr->salen, - ptr->host, (socklen_t)ptr->hostlen, - ptr->serv, (socklen_t)ptr->servlen, - ptr->flags); + ptr->host, (socklen_t)ptr->hostlen, + ptr->serv, (socklen_t)ptr->servlen, + ptr->flags); } -#endif - int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *host, size_t hostlen, - char *serv, size_t servlen, int flags) + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) { -#ifdef GETADDRINFO_EMU - return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); -#else struct getnameinfo_arg arg; int ret; arg.sa = sa; @@ -344,17 +585,185 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, arg.flags = flags; ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getnameinfo, &arg, RUBY_UBF_IO, 0); return ret; -#endif +} + +#elif GETADDRINFO_IMPL == 2 + +struct getnameinfo_arg +{ + struct sockaddr *sa; + socklen_t salen; + int flags; + char *host; + size_t hostlen; + char *serv; + size_t servlen; + int err, gni_errno, refcount, done, cancelled; + rb_nativethread_lock_t lock; + rb_nativethread_cond_t cond; +}; + +static struct getnameinfo_arg * +allocate_getnameinfo_arg(const struct sockaddr *sa, socklen_t salen, size_t hostlen, size_t servlen, int flags) +{ + size_t sa_offset = sizeof(struct getnameinfo_arg); + size_t host_offset = sa_offset + salen; + size_t serv_offset = host_offset + hostlen; + size_t bufsize = serv_offset + servlen; + + char *buf = malloc(bufsize); + if (!buf) { + rb_gc(); + buf = malloc(bufsize); + if (!buf) return NULL; + } + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)buf; + + arg->sa = (struct sockaddr *)(buf + sa_offset); + memcpy(arg->sa, sa, salen); + arg->salen = salen; + arg->host = buf + host_offset; + arg->hostlen = hostlen; + arg->serv = buf + serv_offset; + arg->servlen = servlen; + arg->flags = flags; + + arg->refcount = 2; + arg->done = arg->cancelled = 0; + + rb_nativethread_lock_initialize(&arg->lock); + rb_native_cond_initialize(&arg->cond); + + return arg; } static void +free_getnameinfo_arg(struct getnameinfo_arg *arg) +{ + rb_native_cond_destroy(&arg->cond); + rb_nativethread_lock_destroy(&arg->lock); + + free(arg); +} + +static void * +do_getnameinfo(void *ptr) +{ + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr; + + int err, gni_errno; + err = getnameinfo(arg->sa, arg->salen, arg->host, (socklen_t)arg->hostlen, arg->serv, (socklen_t)arg->servlen, arg->flags); + gni_errno = errno; + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + arg->err = err; + arg->gni_errno = gni_errno; + if (!arg->cancelled) { + arg->done = 1; + rb_native_cond_signal(&arg->cond); + } + if (--arg->refcount == 0) need_free = 1; + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getnameinfo_arg(arg); + + return 0; +} + +static void * +wait_getnameinfo(void *ptr) +{ + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + while (!arg->done && !arg->cancelled) { + rb_native_cond_wait(&arg->cond, &arg->lock); + } + rb_nativethread_lock_unlock(&arg->lock); + return 0; +} + +static void +cancel_getnameinfo(void *ptr) +{ + struct getnameinfo_arg *arg = (struct getnameinfo_arg *)ptr; + rb_nativethread_lock_lock(&arg->lock); + arg->cancelled = 1; + rb_native_cond_signal(&arg->cond); + rb_nativethread_lock_unlock(&arg->lock); +} + +int +rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, int flags) +{ + int retry; + struct getnameinfo_arg *arg; + int err, gni_errno = 0; + +start: + retry = 0; + + arg = allocate_getnameinfo_arg(sa, salen, hostlen, servlen, flags); + if (!arg) { + return EAI_MEMORY; + } + + pthread_t th; + if (do_pthread_create(&th, do_getnameinfo, arg) != 0) { + free_getnameinfo_arg(arg); + return EAI_AGAIN; + } + pthread_detach(th); + + rb_thread_call_without_gvl2(wait_getnameinfo, arg, cancel_getnameinfo, arg); + + int need_free = 0; + rb_nativethread_lock_lock(&arg->lock); + if (arg->done) { + err = arg->err; + gni_errno = arg->gni_errno; + if (err == 0) { + if (host) memcpy(host, arg->host, hostlen); + if (serv) memcpy(serv, arg->serv, servlen); + } + } + else if (arg->cancelled) { + err = EAI_AGAIN; + } + else { + // If already interrupted, rb_thread_call_without_gvl2 may return without calling wait_getnameinfo. + // In this case, it could be !arg->done && !arg->cancelled. + arg->cancelled = 1; + retry = 1; + } + if (--arg->refcount == 0) need_free = 1; + rb_nativethread_lock_unlock(&arg->lock); + + if (need_free) free_getnameinfo_arg(arg); + + // If the current thread is interrupted by asynchronous exception, the following raises the exception. + // But if the current thread is interrupted by timer thread, the following returns; we need to manually retry. + rb_thread_check_ints(); + if (retry) goto start; + + /* Make sure we copy the thread-local errno value from the getnameinfo thread back to this thread, so + * calling code sees the correct errno */ + if (gni_errno) errno = gni_errno; + return err; +} + +#endif + +static void make_ipaddr0(struct sockaddr *addr, socklen_t addrlen, char *buf, size_t buflen) { int error; error = rb_getnameinfo(addr, addrlen, buf, buflen, NULL, 0, NI_NUMERICHOST); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } } @@ -550,17 +959,7 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h } if (!resolved) { -#ifdef GETADDRINFO_EMU - error = getaddrinfo(hostp, portp, hints, &ai); -#else - struct getaddrinfo_arg arg; - MEMZERO(&arg, struct getaddrinfo_arg, 1); - arg.node = hostp; - arg.service = portp; - arg.hints = hints; - arg.res = &ai; - error = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0); -#endif + error = rb_getaddrinfo(hostp, portp, hints, &ai); if (error == 0) { res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); res->allocated_by_malloc = 0; @@ -573,7 +972,7 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); } - rsock_raise_socket_error("getaddrinfo", error); + rsock_raise_resolution_error("getaddrinfo", error); } return res; @@ -587,7 +986,7 @@ rsock_fd_family(int fd) if (fd < 0 || getsockname(fd, &sa, &sa_len) != 0 || (size_t)sa_len < offsetof(struct sockaddr, sa_family) + sizeof(sa.sa_family)) { - return AF_UNSPEC; + return AF_UNSPEC; } return sa.sa_family; } @@ -618,8 +1017,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) family = rb_str_dup(rb_id2str(id)); } else { - sprintf(pbuf, "unknown:%d", sockaddr->sa_family); - family = rb_str_new2(pbuf); + family = rb_sprintf("unknown:%d", sockaddr->sa_family); } addr1 = Qnil; @@ -633,7 +1031,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) error = rb_getnameinfo(sockaddr, sockaddrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } addr2 = rb_str_new2(hbuf); if (addr1 == Qnil) { @@ -645,7 +1043,7 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) return ary; } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN static long unixsocket_len(const struct sockaddr_un *su, socklen_t socklen) { @@ -677,19 +1075,19 @@ rsock_unix_sockaddr_len(VALUE path) { #ifdef __linux__ if (RSTRING_LEN(path) == 0) { - /* autobind; see unix(7) for details. */ - return (socklen_t) sizeof(sa_family_t); + /* autobind; see unix(7) for details. */ + return (socklen_t) sizeof(sa_family_t); } else if (RSTRING_PTR(path)[0] == '\0') { - /* abstract namespace; see unix(7) for details. */ + /* abstract namespace; see unix(7) for details. */ if (SOCKLEN_MAX - offsetof(struct sockaddr_un, sun_path) < (size_t)RSTRING_LEN(path)) rb_raise(rb_eArgError, "Linux abstract socket too long"); - return (socklen_t) offsetof(struct sockaddr_un, sun_path) + - RSTRING_SOCKLEN(path); + return (socklen_t) offsetof(struct sockaddr_un, sun_path) + + RSTRING_SOCKLEN(path); } else { #endif - return (socklen_t) sizeof(struct sockaddr_un); + return (socklen_t) sizeof(struct sockaddr_un); #ifdef __linux__ } #endif @@ -727,7 +1125,7 @@ make_hostent_internal(VALUE v) rb_ary_push(ary, rb_str_new2(hostp)); if (addr->ai_canonname && strlen(addr->ai_canonname) < NI_MAXHOST && - (h = gethostbyname(addr->ai_canonname))) { + (h = gethostbyname(addr->ai_canonname))) { names = rb_ary_new(); if (h->h_aliases != NULL) { for (pch = h->h_aliases; *pch; pch++) { @@ -875,19 +1273,19 @@ call_getaddrinfo(VALUE node, VALUE service, hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family); if (!NIL_P(socktype)) { - hints.ai_socktype = rsock_socktype_arg(socktype); + hints.ai_socktype = rsock_socktype_arg(socktype); } if (!NIL_P(protocol)) { - hints.ai_protocol = NUM2INT(protocol); + hints.ai_protocol = NUM2INT(protocol); } if (!NIL_P(flags)) { - hints.ai_flags = NUM2INT(flags); + hints.ai_flags = NUM2INT(flags); } res = rsock_getaddrinfo(node, service, &hints, socktype_hack); if (res == NULL) - rb_raise(rb_eSocket, "host not found"); + rb_raise(rb_eSocket, "host not found"); return res; } @@ -1018,7 +1416,7 @@ addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN static void init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype) { @@ -1037,7 +1435,7 @@ init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype) len = rsock_unix_sockaddr_len(path); init_addrinfo(rai, (struct sockaddr *)&un, len, - PF_UNIX, socktype, 0, Qnil, Qnil); + PF_UNIX, socktype, 0, Qnil, Qnil); } static long @@ -1065,13 +1463,13 @@ rai_unixsocket_len(const rb_addrinfo_t *rai) * Socket.sockaddr_in or Socket.unpack_sockaddr_un. * * sockaddr examples: - * - ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] - * - ["AF_INET6", 42304, "ip6-localhost", "::1"] - * - ["AF_UNIX", "/tmp/sock"] - * - Socket.sockaddr_in("smtp", "2001:DB8::1") - * - Socket.sockaddr_in(80, "172.18.22.42") - * - Socket.sockaddr_in(80, "www.ruby-lang.org") - * - Socket.sockaddr_un("/tmp/sock") + * - <code>["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"]</code> + * - <code>["AF_INET6", 42304, "ip6-localhost", "::1"]</code> + * - <code>["AF_UNIX", "/tmp/sock"]</code> + * - <code>Socket.sockaddr_in("smtp", "2001:DB8::1")</code> + * - <code>Socket.sockaddr_in(80, "172.18.22.42")</code> + * - <code>Socket.sockaddr_in(80, "www.ruby-lang.org")</code> + * - <code>Socket.sockaddr_un("/tmp/sock")</code> * * In an AF_INET/AF_INET6 sockaddr array, the 4th element, * numeric IP address, is used to construct socket address in the Addrinfo instance. @@ -1119,7 +1517,7 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self) int af; StringValue(afamily); if (rsock_family_to_int(RSTRING_PTR(afamily), RSTRING_LEN(afamily), &af) == -1) - rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily)); + rb_raise(rb_eSocket, "unknown address family: %s", StringValueCStr(afamily)); switch (af) { case AF_INET: /* ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"] */ #ifdef INET6 @@ -1147,7 +1545,7 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self) break; } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: /* ["AF_UNIX", "/tmp/sock"] */ { VALUE path = rb_ary_entry(sockaddr_ary, 1); @@ -1209,45 +1607,45 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r else { switch (sockaddr->addr.sa_family) { case AF_UNSPEC: - { - rb_str_cat2(ret, "UNSPEC"); + { + rb_str_cat2(ret, "UNSPEC"); break; - } + } case AF_INET: { struct sockaddr_in *addr; int port; - addr = &sockaddr->in; - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+0+1) <= socklen) - rb_str_catf(ret, "%d", ((unsigned char*)&addr->sin_addr)[0]); - else - rb_str_cat2(ret, "?"); - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+1+1) <= socklen) - rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[1]); - else - rb_str_cat2(ret, ".?"); - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+2+1) <= socklen) - rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[2]); - else - rb_str_cat2(ret, ".?"); - if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+3+1) <= socklen) - rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[3]); - else - rb_str_cat2(ret, ".?"); - - if ((socklen_t)(((char*)&addr->sin_port)-(char*)addr+(int)sizeof(addr->sin_port)) < socklen) { - port = ntohs(addr->sin_port); - if (port) - rb_str_catf(ret, ":%d", port); - } - else { - rb_str_cat2(ret, ":?"); - } - if ((socklen_t)sizeof(struct sockaddr_in) != socklen) - rb_str_catf(ret, " (%d bytes for %d bytes sockaddr_in)", - (int)socklen, - (int)sizeof(struct sockaddr_in)); + addr = &sockaddr->in; + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+0+1) <= socklen) + rb_str_catf(ret, "%d", ((unsigned char*)&addr->sin_addr)[0]); + else + rb_str_cat2(ret, "?"); + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+1+1) <= socklen) + rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[1]); + else + rb_str_cat2(ret, ".?"); + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+2+1) <= socklen) + rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[2]); + else + rb_str_cat2(ret, ".?"); + if ((socklen_t)(((char*)&addr->sin_addr)-(char*)addr+3+1) <= socklen) + rb_str_catf(ret, ".%d", ((unsigned char*)&addr->sin_addr)[3]); + else + rb_str_cat2(ret, ".?"); + + if ((socklen_t)(((char*)&addr->sin_port)-(char*)addr+(int)sizeof(addr->sin_port)) < socklen) { + port = ntohs(addr->sin_port); + if (port) + rb_str_catf(ret, ":%d", port); + } + else { + rb_str_cat2(ret, ":?"); + } + if ((socklen_t)sizeof(struct sockaddr_in) != socklen) + rb_str_catf(ret, " (%d bytes for %d bytes sockaddr_in)", + (int)socklen, + (int)sizeof(struct sockaddr_in)); break; } @@ -1267,11 +1665,11 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r * RFC 4007: IPv6 Scoped Address Architecture * draft-ietf-ipv6-scope-api-00.txt: Scoped Address Extensions to the IPv6 Basic Socket API */ - error = getnameinfo(&sockaddr->addr, socklen, - hbuf, (socklen_t)sizeof(hbuf), NULL, 0, - NI_NUMERICHOST|NI_NUMERICSERV); + error = rb_getnameinfo(&sockaddr->addr, socklen, + hbuf, (socklen_t)sizeof(hbuf), NULL, 0, + NI_NUMERICHOST|NI_NUMERICSERV); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } if (addr->sin6_port == 0) { rb_str_cat2(ret, hbuf); @@ -1287,7 +1685,7 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r } #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: { struct sockaddr_un *addr = &sockaddr->un; @@ -1398,20 +1796,20 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r #endif #if defined(AF_LINK) && defined(HAVE_TYPE_STRUCT_SOCKADDR_DL) - /* AF_LINK is defined in 4.4BSD derivations since Net2. - link_ntoa is also defined at Net2. + /* AF_LINK is defined in 4.4BSD derivations since Net2. + link_ntoa is also defined at Net2. However Debian GNU/kFreeBSD defines AF_LINK but don't have link_ntoa. */ case AF_LINK: - { - /* - * Simple implementation using link_ntoa(): - * This doesn't work on Debian GNU/kFreeBSD 6.0.7 (squeeze). + { + /* + * Simple implementation using link_ntoa(): + * This doesn't work on Debian GNU/kFreeBSD 6.0.7 (squeeze). * Also, the format is bit different. - * - * rb_str_catf(ret, "LINK %s", link_ntoa(&sockaddr->dl)); - * break; - */ + * + * rb_str_catf(ret, "LINK %s", link_ntoa(&sockaddr->dl)); + * break; + */ struct sockaddr_dl *addr = &sockaddr->dl; char *np = NULL, *ap = NULL, *endp; int nlen = 0, alen = 0; @@ -1438,14 +1836,14 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r alen = (int)(endp - ap); } - CATSEP; + CATSEP; if (np) rb_str_catf(ret, "%.*s", nlen, np); else rb_str_cat2(ret, "?"); if (ap && 0 < alen) { - CATSEP; + CATSEP; for (i = 0; i < alen; i++) rb_str_catf(ret, "%s%02x", i == 0 ? "" : ":", (unsigned char)ap[i]); } @@ -1456,10 +1854,10 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r /* longer length is possible behavior because struct sockaddr_dl has "minimum work area, can be larger" as the last field. * cf. Net2:/usr/src/sys/net/if_dl.h. */ socklen < (socklen_t)(offsetof(struct sockaddr_dl, sdl_data) + addr->sdl_nlen + addr->sdl_alen + addr->sdl_slen)) { - CATSEP; + CATSEP; rb_str_catf(ret, "(%d bytes for %d bytes sockaddr_dl)", (int)socklen, (int)sizeof(struct sockaddr_dl)); - } + } rb_str_cat2(ret, "]"); #undef CATSEP @@ -1623,7 +2021,7 @@ addrinfo_mdump(VALUE self) afamily = rb_id2str(id); switch(afamily_int) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: { sockaddr = rb_str_new(rai->addr.un.sun_path, rai_unixsocket_len(rai)); @@ -1635,11 +2033,11 @@ addrinfo_mdump(VALUE self) { char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; int error; - error = getnameinfo(&rai->addr.addr, rai->sockaddr_len, - hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), - NI_NUMERICHOST|NI_NUMERICSERV); + error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len, + hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), + NI_NUMERICHOST|NI_NUMERICSERV); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } sockaddr = rb_assoc_new(rb_str_new_cstr(hbuf), rb_str_new_cstr(pbuf)); break; @@ -1716,7 +2114,7 @@ addrinfo_mload(VALUE self, VALUE ary) v = rb_ary_entry(ary, 1); switch(afamily) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: { struct sockaddr_un uaddr; @@ -1981,11 +2379,11 @@ addrinfo_getnameinfo(int argc, VALUE *argv, VALUE self) if (rai->socktype == SOCK_DGRAM) flags |= NI_DGRAM; - error = getnameinfo(&rai->addr.addr, rai->sockaddr_len, - hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), - flags); + error = rb_getnameinfo(&rai->addr.addr, rai->sockaddr_len, + hbuf, (socklen_t)sizeof(hbuf), pbuf, (socklen_t)sizeof(pbuf), + flags); if (error) { - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); } return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf)); @@ -2009,7 +2407,7 @@ addrinfo_ip_unpack(VALUE self) VALUE ret, portstr; if (!IS_IP_FAMILY(family)) - rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV); ret = addrinfo_getnameinfo(1, &vflags, self); @@ -2036,7 +2434,7 @@ addrinfo_ip_address(VALUE self) VALUE ret; if (!IS_IP_FAMILY(family)) - rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV); ret = addrinfo_getnameinfo(1, &vflags, self); @@ -2062,9 +2460,9 @@ addrinfo_ip_port(VALUE self) if (!IS_IP_FAMILY(family)) { bad_family: #ifdef AF_INET6 - rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); #else - rb_raise(rb_eSocket, "need IPv4 address"); + rb_raise(rb_eSocket, "need IPv4 address"); #endif } @@ -2084,7 +2482,7 @@ addrinfo_ip_port(VALUE self) #endif default: - goto bad_family; + goto bad_family; } return INT2NUM(port); @@ -2192,7 +2590,7 @@ addrinfo_ipv6_multicast_p(VALUE self) } /* - * Returns true for IPv6 link local address (ff80::/10). + * Returns true for IPv6 link local address (fe80::/10). * It returns false otherwise. */ static VALUE @@ -2204,7 +2602,7 @@ addrinfo_ipv6_linklocal_p(VALUE self) } /* - * Returns true for IPv6 site local address (ffc0::/10). + * Returns true for IPv6 site local address (fec0::/10). * It returns false otherwise. */ static VALUE @@ -2344,7 +2742,7 @@ addrinfo_ipv6_to_ipv4(VALUE self) #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: * addrinfo.unix_path => path @@ -2362,7 +2760,7 @@ addrinfo_unix_path(VALUE self) long n; if (family != AF_UNIX) - rb_raise(rb_eSocket, "need AF_UNIX address"); + rb_raise(rb_eSocket, "need AF_UNIX address"); addr = &rai->addr.un; @@ -2429,10 +2827,10 @@ addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self) VALUE node, service, family, socktype, protocol, flags, opts, timeout; rb_scan_args(argc, argv, "24:", &node, &service, &family, &socktype, - &protocol, &flags, &opts); + &protocol, &flags, &opts); rb_get_kwargs(opts, &id_timeout, 0, 1, &timeout); if (timeout == Qundef) { - timeout = Qnil; + timeout = Qnil; } return addrinfo_list_new(node, service, family, socktype, protocol, flags, timeout); @@ -2492,7 +2890,7 @@ addrinfo_s_udp(VALUE self, VALUE host, VALUE port) INT2NUM(PF_UNSPEC), INT2NUM(SOCK_DGRAM), INT2NUM(IPPROTO_UDP), INT2FIX(0)); } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: @@ -2615,12 +3013,12 @@ rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len) void rsock_init_addrinfo(void) { + id_timeout = rb_intern("timeout"); + /* * The Addrinfo class maps <tt>struct addrinfo</tt> to ruby. This * structure identifies an Internet host and a service. */ - id_timeout = rb_intern("timeout"); - rb_cAddrinfo = rb_define_class("Addrinfo", rb_cObject); rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate); rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1); @@ -2630,7 +3028,7 @@ rsock_init_addrinfo(void) rb_define_singleton_method(rb_cAddrinfo, "ip", addrinfo_s_ip, 1); rb_define_singleton_method(rb_cAddrinfo, "tcp", addrinfo_s_tcp, 2); rb_define_singleton_method(rb_cAddrinfo, "udp", addrinfo_s_udp, 2); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN rb_define_singleton_method(rb_cAddrinfo, "unix", addrinfo_s_unix, -1); #endif @@ -2671,7 +3069,7 @@ rsock_init_addrinfo(void) rb_define_method(rb_cAddrinfo, "ipv6_to_ipv4", addrinfo_ipv6_to_ipv4, 0); #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN rb_define_method(rb_cAddrinfo, "unix_path", addrinfo_unix_path, 0); #endif diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h index c0d40addca..f486db4262 100644 --- a/ext/socket/rubysocket.h +++ b/ext/socket/rubysocket.h @@ -33,6 +33,10 @@ #endif #ifdef _WIN32 +# include <winsock2.h> +# include <ws2tcpip.h> +# include <mswsock.h> +# include <iphlpapi.h> # if defined(_MSC_VER) # undef HAVE_TYPE_STRUCT_SOCKADDR_DL # endif @@ -69,6 +73,11 @@ # include <sys/un.h> #endif +#ifdef HAVE_AFUNIX_H +// Windows doesn't have sys/un.h, but it does have afunix.h just to be special: +# include <afunix.h> +#endif + #if defined(HAVE_FCNTL) # ifdef HAVE_SYS_SELECT_H # include <sys/select.h> @@ -268,7 +277,7 @@ extern VALUE rb_cIPSocket; extern VALUE rb_cTCPSocket; extern VALUE rb_cTCPServer; extern VALUE rb_cUDPSocket; -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN extern VALUE rb_cUNIXSocket; extern VALUE rb_cUNIXServer; #endif @@ -277,6 +286,7 @@ extern VALUE rb_cAddrinfo; extern VALUE rb_cSockOpt; extern VALUE rb_eSocket; +extern VALUE rb_eResolution; #ifdef SOCKS extern VALUE rb_cSOCKSSocket; @@ -299,7 +309,7 @@ VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *ai_ret VALUE rb_check_sockaddr_string_type(VALUE); -NORETURN(void rsock_raise_socket_error(const char *, int)); +NORETURN(void rsock_raise_resolution_error(const char *, int)); int rsock_family_arg(VALUE domain); int rsock_socktype_arg(VALUE type); @@ -336,7 +346,7 @@ VALUE rsock_sockaddr_obj(struct sockaddr *addr, socklen_t len); int rsock_revlookup_flag(VALUE revlookup, int *norevlookup); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN VALUE rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len); VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len); socklen_t rsock_unix_sockaddr_len(VALUE path); @@ -368,23 +378,23 @@ enum sock_recv_type { }; VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, - VALUE ex, enum sock_recv_type from); + VALUE ex, enum sock_recv_type from); VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from); int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout); VALUE rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len); VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, - struct sockaddr *sockaddr, socklen_t *len); + struct sockaddr *sockaddr, socklen_t *len); VALUE rsock_sock_listen(VALUE sock, VALUE log); VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data); #if defined(HAVE_SENDMSG) VALUE rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, - VALUE dest_sockaddr, VALUE controls); + VALUE dest_sockaddr, VALUE controls); VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, - VALUE dest_sockaddr, VALUE controls, VALUE ex); + VALUE dest_sockaddr, VALUE controls, VALUE ex); #else #define rsock_bsock_sendmsg rb_f_notimplement #define rsock_bsock_sendmsg_nonblock rb_f_notimplement @@ -392,9 +402,9 @@ VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, #if defined(HAVE_RECVMSG) VALUE rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE clen, VALUE flags, - VALUE scm_rights); + VALUE scm_rights); VALUE rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE clen, - VALUE flags, VALUE scm_rights, VALUE ex); + VALUE flags, VALUE scm_rights, VALUE ex); ssize_t rsock_recvmsg(int socket, struct msghdr *message, int flags); #else #define rsock_bsock_recvmsg rb_f_notimplement @@ -451,6 +461,8 @@ VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex); void rsock_make_fd_nonblock(int fd); +int rsock_is_dgram(rb_io_t *fptr); + #if !defined HAVE_INET_NTOP && ! defined _WIN32 const char *inet_ntop(int, const void *, char *, size_t); #elif defined __MINGW32__ diff --git a/ext/socket/socket.c b/ext/socket/socket.c index ccf990d11f..c780d77cf6 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -26,7 +26,11 @@ rsock_syserr_fail_host_port(int err, const char *mesg, VALUE host, VALUE port) VALUE message; message = rb_sprintf("%s for %+"PRIsVALUE" port % "PRIsVALUE"", - mesg, host, port); + mesg, host, port); + + if (err == ETIMEDOUT) { + rb_exc_raise(rb_exc_new3(rb_eIOTimeoutError, message)); + } rb_syserr_fail_str(err, message); } @@ -43,11 +47,11 @@ rsock_syserr_fail_path(int err, const char *mesg, VALUE path) VALUE message; if (RB_TYPE_P(path, T_STRING)) { - message = rb_sprintf("%s for % "PRIsVALUE"", mesg, path); - rb_syserr_fail_str(err, message); + message = rb_sprintf("%s for % "PRIsVALUE"", mesg, path); + rb_syserr_fail_str(err, message); } else { - rb_syserr_fail(err, mesg); + rb_syserr_fail(err, mesg); } } @@ -96,12 +100,12 @@ rsock_syserr_fail_raddrinfo_or_sockaddr(int err, const char *mesg, VALUE addr, V if (NIL_P(rai)) { StringValue(addr); - rsock_syserr_fail_sockaddr(err, mesg, + rsock_syserr_fail_sockaddr(err, mesg, (struct sockaddr *)RSTRING_PTR(addr), (socklen_t)RSTRING_LEN(addr)); /* overflow should be checked already */ } else - rsock_syserr_fail_raddrinfo(err, mesg, rai); + rsock_syserr_fail_raddrinfo(err, mesg, rai); } static void @@ -256,7 +260,7 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass) p = NUM2INT(protocol); ret = rsock_socketpair(d, t, p, sp); if (ret < 0) { - rb_sys_fail("socketpair(2)"); + rb_sys_fail("socketpair(2)"); } s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]); @@ -395,7 +399,7 @@ sock_connect(VALUE sock, VALUE addr) fd = fptr->fd; n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, NULL); if (n < 0) { - rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai); + rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai); } return INT2FIX(n); @@ -415,19 +419,19 @@ sock_connect_nonblock(VALUE sock, VALUE addr, VALUE ex) rb_io_set_nonblock(fptr); n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)); if (n < 0) { - int e = errno; - if (e == EINPROGRESS) { + int e = errno; + if (e == EINPROGRESS) { if (ex == Qfalse) { return sym_wait_writable; } rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e, "connect(2) would block"); - } - if (e == EISCONN) { + } + if (e == EISCONN) { if (ex == Qfalse) { return INT2FIX(0); } - } - rsock_syserr_fail_raddrinfo_or_sockaddr(e, "connect(2)", addr, rai); + } + rsock_syserr_fail_raddrinfo_or_sockaddr(e, "connect(2)", addr, rai); } return INT2FIX(n); @@ -528,7 +532,7 @@ sock_bind(VALUE sock, VALUE addr) SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) - rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); + rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); return INT2FIX(0); } @@ -612,7 +616,7 @@ rsock_sock_listen(VALUE sock, VALUE log) backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) - rb_sys_fail("listen(2)"); + rb_sys_fail("listen(2)"); return INT2FIX(0); } @@ -774,7 +778,7 @@ sock_accept_nonblock(VALUE sock, VALUE ex) sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) /* :wait_readable */ - return sock2; + return sock2; return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } @@ -855,19 +859,19 @@ sock_gethostname(VALUE obj) name = rb_str_new(0, len); while (gethostname(RSTRING_PTR(name), len) < 0) { - int e = errno; - switch (e) { - case ENAMETOOLONG: + int e = errno; + switch (e) { + case ENAMETOOLONG: #ifdef __linux__ - case EINVAL: - /* glibc before version 2.1 uses EINVAL instead of ENAMETOOLONG */ + case EINVAL: + /* glibc before version 2.1 uses EINVAL instead of ENAMETOOLONG */ #endif - break; - default: - rb_syserr_fail(e, "gethostname(3)"); - } - rb_str_modify_expand(name, len); - len += len; + break; + default: + rb_syserr_fail(e, "gethostname(3)"); + } + rb_str_modify_expand(name, len); + len += len; } rb_str_resize(name, strlen(RSTRING_PTR(name))); return name; @@ -897,18 +901,18 @@ make_addrinfo(struct rb_addrinfo *res0, int norevlookup) struct addrinfo *res; if (res0 == NULL) { - rb_raise(rb_eSocket, "host not found"); + rb_raise(rb_eSocket, "host not found"); } base = rb_ary_new(); for (res = res0->ai; res; res = res->ai_next) { - ary = rsock_ipaddr(res->ai_addr, res->ai_addrlen, norevlookup); - if (res->ai_canonname) { - RARRAY_ASET(ary, 2, rb_str_new2(res->ai_canonname)); - } - rb_ary_push(ary, INT2FIX(res->ai_family)); - rb_ary_push(ary, INT2FIX(res->ai_socktype)); - rb_ary_push(ary, INT2FIX(res->ai_protocol)); - rb_ary_push(base, ary); + ary = rsock_ipaddr(res->ai_addr, res->ai_addrlen, norevlookup); + if (res->ai_canonname) { + RARRAY_ASET(ary, 2, rb_str_new2(res->ai_canonname)); + } + rb_ary_push(ary, INT2FIX(res->ai_family)); + rb_ary_push(ary, INT2FIX(res->ai_socktype)); + rb_ary_push(ary, INT2FIX(res->ai_protocol)); + rb_ary_push(base, ary); } return base; } @@ -920,18 +924,18 @@ sock_sockaddr(struct sockaddr *addr, socklen_t len) switch (addr->sa_family) { case AF_INET: - ptr = (char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr; - len = (socklen_t)sizeof(((struct sockaddr_in*)addr)->sin_addr.s_addr); - break; + ptr = (char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr; + len = (socklen_t)sizeof(((struct sockaddr_in*)addr)->sin_addr.s_addr); + break; #ifdef AF_INET6 case AF_INET6: - ptr = (char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr; - len = (socklen_t)sizeof(((struct sockaddr_in6*)addr)->sin6_addr.s6_addr); - break; + ptr = (char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr; + len = (socklen_t)sizeof(((struct sockaddr_in6*)addr)->sin6_addr.s6_addr); + break; #endif default: rb_raise(rb_eSocket, "unknown socket family:%d", addr->sa_family); - break; + break; } return rb_str_new(ptr, len); } @@ -961,7 +965,7 @@ sock_s_gethostbyname(VALUE obj, VALUE host) { rb_warn("Socket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead."); struct rb_addrinfo *res = - rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); return rsock_make_hostent(host, res, sock_sockaddr); } @@ -1004,20 +1008,20 @@ sock_s_gethostbyaddr(int argc, VALUE *argv, VALUE _) rb_scan_args(argc, argv, "11", &addr, &family); StringValue(addr); if (!NIL_P(family)) { - t = rsock_family_arg(family); + t = rsock_family_arg(family); } #ifdef AF_INET6 else if (RSTRING_LEN(addr) == 16) { - t = AF_INET6; + t = AF_INET6; } #endif h = gethostbyaddr(RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), t); if (h == NULL) { #ifdef HAVE_HSTRERROR - extern int h_errno; - rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno)); + extern int h_errno; + rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno)); #else - rb_raise(rb_eSocket, "host not found"); + rb_raise(rb_eSocket, "host not found"); #endif } ary = rb_ary_new(); @@ -1025,14 +1029,14 @@ sock_s_gethostbyaddr(int argc, VALUE *argv, VALUE _) names = rb_ary_new(); rb_ary_push(ary, names); if (h->h_aliases != NULL) { - for (pch = h->h_aliases; *pch; pch++) { - rb_ary_push(names, rb_str_new2(*pch)); - } + for (pch = h->h_aliases; *pch; pch++) { + rb_ary_push(names, rb_str_new2(*pch)); + } } rb_ary_push(ary, INT2NUM(h->h_addrtype)); #ifdef h_addr for (pch = h->h_addr_list; *pch; pch++) { - rb_ary_push(ary, rb_str_new(*pch, h->h_length)); + rb_ary_push(ary, rb_str_new(*pch, h->h_length)); } #else rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length)); @@ -1069,15 +1073,15 @@ sock_s_getservbyname(int argc, VALUE *argv, VALUE _) if (!NIL_P(proto)) protoname = StringValueCStr(proto); sp = getservbyname(servicename, protoname); if (sp) { - port = ntohs(sp->s_port); + port = ntohs(sp->s_port); } else { - char *end; + char *end; - port = STRTOUL(servicename, &end, 0); - if (*end != '\0') { - rb_raise(rb_eSocket, "no such service %s/%s", servicename, protoname); - } + port = STRTOUL(servicename, &end, 0); + if (*end != '\0') { + rb_raise(rb_eSocket, "no such service %s/%s", servicename, protoname); + } } return INT2FIX(port); } @@ -1106,14 +1110,14 @@ sock_s_getservbyport(int argc, VALUE *argv, VALUE _) rb_scan_args(argc, argv, "11", &port, &proto); portnum = NUM2LONG(port); if (portnum != (uint16_t)portnum) { - const char *s = portnum > 0 ? "big" : "small"; - rb_raise(rb_eRangeError, "integer %ld too %s to convert into `int16_t'", portnum, s); + const char *s = portnum > 0 ? "big" : "small"; + rb_raise(rb_eRangeError, "integer %ld too %s to convert into `int16_t'", portnum, s); } if (!NIL_P(proto)) protoname = StringValueCStr(proto); sp = getservbyport((int)htons((uint16_t)portnum), protoname); if (!sp) { - rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname); + rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname); } return rb_str_new2(sp->s_name); } @@ -1167,16 +1171,16 @@ sock_s_getaddrinfo(int argc, VALUE *argv, VALUE _) hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family); if (!NIL_P(socktype)) { - hints.ai_socktype = rsock_socktype_arg(socktype); + hints.ai_socktype = rsock_socktype_arg(socktype); } if (!NIL_P(protocol)) { - hints.ai_protocol = NUM2INT(protocol); + hints.ai_protocol = NUM2INT(protocol); } if (!NIL_P(flags)) { - hints.ai_flags = NUM2INT(flags); + hints.ai_flags = NUM2INT(flags); } if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) { - norevlookup = rsock_do_not_reverse_lookup; + norevlookup = rsock_do_not_reverse_lookup; } res = rsock_getaddrinfo(host, port, &hints, 0); @@ -1226,82 +1230,82 @@ sock_s_getnameinfo(int argc, VALUE *argv, VALUE _) fl = 0; if (!NIL_P(flags)) { - fl = NUM2INT(flags); + fl = NUM2INT(flags); } tmp = rb_check_sockaddr_string_type(sa); if (!NIL_P(tmp)) { - sa = tmp; - if (sizeof(ss) < (size_t)RSTRING_LEN(sa)) { - rb_raise(rb_eTypeError, "sockaddr length too big"); - } - memcpy(&ss, RSTRING_PTR(sa), RSTRING_LEN(sa)); + sa = tmp; + if (sizeof(ss) < (size_t)RSTRING_LEN(sa)) { + rb_raise(rb_eTypeError, "sockaddr length too big"); + } + memcpy(&ss, RSTRING_PTR(sa), RSTRING_LEN(sa)); if (!VALIDATE_SOCKLEN(&ss.addr, RSTRING_LEN(sa))) { - rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); - } - sap = &ss.addr; + rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); + } + sap = &ss.addr; salen = RSTRING_SOCKLEN(sa); - goto call_nameinfo; + goto call_nameinfo; } tmp = rb_check_array_type(sa); if (!NIL_P(tmp)) { - sa = tmp; - MEMZERO(&hints, struct addrinfo, 1); - if (RARRAY_LEN(sa) == 3) { - af = RARRAY_AREF(sa, 0); - port = RARRAY_AREF(sa, 1); - host = RARRAY_AREF(sa, 2); - } - else if (RARRAY_LEN(sa) >= 4) { - af = RARRAY_AREF(sa, 0); - port = RARRAY_AREF(sa, 1); - host = RARRAY_AREF(sa, 3); - if (NIL_P(host)) { - host = RARRAY_AREF(sa, 2); - } - else { - /* - * 4th element holds numeric form, don't resolve. - * see rsock_ipaddr(). - */ + sa = tmp; + MEMZERO(&hints, struct addrinfo, 1); + if (RARRAY_LEN(sa) == 3) { + af = RARRAY_AREF(sa, 0); + port = RARRAY_AREF(sa, 1); + host = RARRAY_AREF(sa, 2); + } + else if (RARRAY_LEN(sa) >= 4) { + af = RARRAY_AREF(sa, 0); + port = RARRAY_AREF(sa, 1); + host = RARRAY_AREF(sa, 3); + if (NIL_P(host)) { + host = RARRAY_AREF(sa, 2); + } + else { + /* + * 4th element holds numeric form, don't resolve. + * see rsock_ipaddr(). + */ #ifdef AI_NUMERICHOST /* AIX 4.3.3 doesn't have AI_NUMERICHOST. */ - hints.ai_flags |= AI_NUMERICHOST; + hints.ai_flags |= AI_NUMERICHOST; #endif - } - } - else { - rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given", - RARRAY_LEN(sa)); - } - hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; - /* af */ + } + } + else { + rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given", + RARRAY_LEN(sa)); + } + hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; + /* af */ hints.ai_family = NIL_P(af) ? PF_UNSPEC : rsock_family_arg(af); - res = rsock_getaddrinfo(host, port, &hints, 0); - sap = res->ai->ai_addr; + res = rsock_getaddrinfo(host, port, &hints, 0); + sap = res->ai->ai_addr; salen = res->ai->ai_addrlen; } else { - rb_raise(rb_eTypeError, "expecting String or Array"); + rb_raise(rb_eTypeError, "expecting String or Array"); } call_nameinfo: error = rb_getnameinfo(sap, salen, hbuf, sizeof(hbuf), - pbuf, sizeof(pbuf), fl); + pbuf, sizeof(pbuf), fl); if (error) goto error_exit_name; if (res) { - for (r = res->ai->ai_next; r; r = r->ai_next) { - char hbuf2[1024], pbuf2[1024]; + for (r = res->ai->ai_next; r; r = r->ai_next) { + char hbuf2[1024], pbuf2[1024]; - sap = r->ai_addr; + sap = r->ai_addr; salen = r->ai_addrlen; - error = rb_getnameinfo(sap, salen, hbuf2, sizeof(hbuf2), - pbuf2, sizeof(pbuf2), fl); - if (error) goto error_exit_name; - if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) { - rb_freeaddrinfo(res); - rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename"); - } - } - rb_freeaddrinfo(res); + error = rb_getnameinfo(sap, salen, hbuf2, sizeof(hbuf2), + pbuf2, sizeof(pbuf2), fl); + if (error) goto error_exit_name; + if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) { + rb_freeaddrinfo(res); + rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename"); + } + } + rb_freeaddrinfo(res); } return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf)); @@ -1309,7 +1313,7 @@ sock_s_getnameinfo(int argc, VALUE *argv, VALUE _) saved_errno = errno; if (res) rb_freeaddrinfo(res); errno = saved_errno; - rsock_raise_socket_error("getnameinfo", error); + rsock_raise_resolution_error("getnameinfo", error); UNREACHABLE_RETURN(Qnil); } @@ -1379,7 +1383,7 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr) return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host); } -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: @@ -1437,8 +1441,8 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr) rb_raise(rb_eArgError, "not an AF_UNIX sockaddr"); } if (sizeof(struct sockaddr_un) < (size_t)RSTRING_LEN(addr)) { - rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d", - RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un)); + rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d", + RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un)); } path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr)); return path; @@ -1467,7 +1471,7 @@ sockaddr_len(struct sockaddr *addr) return (socklen_t)sizeof(struct sockaddr_in6); #endif -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN case AF_UNIX: return (socklen_t)sizeof(struct sockaddr_un); #endif @@ -1502,19 +1506,19 @@ sockaddr_obj(struct sockaddr *addr, socklen_t len) #if defined(__KAME__) && defined(AF_INET6) if (addr->sa_family == AF_INET6) { - /* KAME uses the 2nd 16bit word of link local IPv6 address as interface index internally */ + /* KAME uses the 2nd 16bit word of link local IPv6 address as interface index internally */ /* http://orange.kame.net/dev/cvsweb.cgi/kame/IMPLEMENTATION */ - /* convert fe80:1::1 to fe80::1%1 */ + /* convert fe80:1::1 to fe80::1%1 */ len = (socklen_t)sizeof(struct sockaddr_in6); - memcpy(&addr6, addr, len); - addr = (struct sockaddr *)&addr6; - if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) && - addr6.sin6_scope_id == 0 && - (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) { - addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3]; - addr6.sin6_addr.s6_addr[2] = 0; - addr6.sin6_addr.s6_addr[3] = 0; - } + memcpy(&addr6, addr, len); + addr = (struct sockaddr *)&addr6; + if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) && + addr6.sin6_scope_id == 0 && + (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) { + addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3]; + addr6.sin6_addr.s6_addr[2] = 0; + addr6.sin6_addr.s6_addr[3] = 0; + } } #endif @@ -1529,7 +1533,7 @@ rsock_sockaddr_obj(struct sockaddr *addr, socklen_t len) #endif -#if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32) +#if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM)) || defined(SIOCGIFCONF) || defined(_WIN32) /* * call-seq: * Socket.ip_address_list => array @@ -1590,9 +1594,8 @@ socket_s_ip_address_list(VALUE self) freeifaddrs(ifp); return list; -#elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux) +#elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) /* Solaris if_tcp(7P) */ - /* HP-UX has SIOCGLIFCONF too. But it uses different struct */ int fd = -1; int ret; struct lifnum ln; @@ -1613,8 +1616,8 @@ socket_s_ip_address_list(VALUE self) ret = ioctl(fd, SIOCGLIFNUM, &ln); if (ret == -1) { - reason = "SIOCGLIFNUM"; - goto finish; + reason = "SIOCGLIFNUM"; + goto finish; } memset(&lc, 0, sizeof(lc)); @@ -1625,13 +1628,13 @@ socket_s_ip_address_list(VALUE self) ret = ioctl(fd, SIOCGLIFCONF, &lc); if (ret == -1) { - reason = "SIOCGLIFCONF"; - goto finish; + reason = "SIOCGLIFCONF"; + goto finish; } list = rb_ary_new(); for (i = 0; i < ln.lifn_count; i++) { - struct lifreq *req = &lc.lifc_req[i]; + struct lifreq *req = &lc.lifc_req[i]; if (IS_IP_FAMILY(req->lifr_addr.ss_family)) { if (req->lifr_addr.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) && @@ -1651,14 +1654,13 @@ socket_s_ip_address_list(VALUE self) finish: save_errno = errno; - if (lc.lifc_buf != NULL) - xfree(lc.lifc_req); + xfree(lc.lifc_req); if (fd != -1) - close(fd); + close(fd); errno = save_errno; if (reason) - rb_syserr_fail(save_errno, reason); + rb_syserr_fail(save_errno, reason); return list; #elif defined(SIOCGIFCONF) @@ -1696,17 +1698,17 @@ socket_s_ip_address_list(VALUE self) /* fprintf(stderr, "conf.ifc_len: %d\n", conf.ifc_len); */ if (bufsize - EXTRA_SPACE < conf.ifc_len) { - if (bufsize < conf.ifc_len) { - /* NetBSD returns required size for all interfaces. */ - bufsize = conf.ifc_len + EXTRA_SPACE; - } - else { - bufsize = bufsize << 1; - } - if (buf == initbuf) - buf = NULL; - buf = xrealloc(buf, bufsize); - goto retry; + if (bufsize < conf.ifc_len) { + /* NetBSD returns required size for all interfaces. */ + bufsize = conf.ifc_len + EXTRA_SPACE; + } + else { + bufsize = bufsize << 1; + } + if (buf == initbuf) + buf = NULL; + buf = xrealloc(buf, bufsize); + goto retry; } close(fd); @@ -1715,10 +1717,10 @@ socket_s_ip_address_list(VALUE self) list = rb_ary_new(); req = conf.ifc_req; while ((char*)req < (char*)conf.ifc_req + conf.ifc_len) { - struct sockaddr *addr = &req->ifr_addr; + struct sockaddr *addr = &req->ifr_addr; if (IS_IP_FAMILY(addr->sa_family)) { - rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr))); - } + rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr))); + } #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN # ifndef _SIZEOF_ADDR_IFREQ # define _SIZEOF_ADDR_IFREQ(r) \ @@ -1727,9 +1729,9 @@ socket_s_ip_address_list(VALUE self) (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \ 0)) # endif - req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req)); + req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req)); #else - req = (struct ifreq *)((char*)req + sizeof(struct ifreq)); + req = (struct ifreq *)((char*)req + sizeof(struct ifreq)); #endif } @@ -1739,57 +1741,57 @@ socket_s_ip_address_list(VALUE self) if (buf != initbuf) xfree(buf); if (fd != -1) - close(fd); + close(fd); errno = save_errno; if (reason) - rb_syserr_fail(save_errno, reason); + rb_syserr_fail(save_errno, reason); return list; #undef EXTRA_SPACE #elif defined(_WIN32) typedef struct ip_adapter_unicast_address_st { - unsigned LONG_LONG dummy0; - struct ip_adapter_unicast_address_st *Next; - struct { - struct sockaddr *lpSockaddr; - int iSockaddrLength; - } Address; - int dummy1; - int dummy2; - int dummy3; - long dummy4; - long dummy5; - long dummy6; + unsigned LONG_LONG dummy0; + struct ip_adapter_unicast_address_st *Next; + struct { + struct sockaddr *lpSockaddr; + int iSockaddrLength; + } Address; + int dummy1; + int dummy2; + int dummy3; + long dummy4; + long dummy5; + long dummy6; } ip_adapter_unicast_address_t; typedef struct ip_adapter_anycast_address_st { - unsigned LONG_LONG dummy0; - struct ip_adapter_anycast_address_st *Next; - struct { - struct sockaddr *lpSockaddr; - int iSockaddrLength; - } Address; + unsigned LONG_LONG dummy0; + struct ip_adapter_anycast_address_st *Next; + struct { + struct sockaddr *lpSockaddr; + int iSockaddrLength; + } Address; } ip_adapter_anycast_address_t; typedef struct ip_adapter_addresses_st { - unsigned LONG_LONG dummy0; - struct ip_adapter_addresses_st *Next; - void *dummy1; - ip_adapter_unicast_address_t *FirstUnicastAddress; - ip_adapter_anycast_address_t *FirstAnycastAddress; - void *dummy2; - void *dummy3; - void *dummy4; - void *dummy5; - void *dummy6; - BYTE dummy7[8]; - DWORD dummy8; - DWORD dummy9; - DWORD dummy10; - DWORD IfType; - int OperStatus; - DWORD dummy12; - DWORD dummy13[16]; - void *dummy14; + unsigned LONG_LONG dummy0; + struct ip_adapter_addresses_st *Next; + void *dummy1; + ip_adapter_unicast_address_t *FirstUnicastAddress; + ip_adapter_anycast_address_t *FirstAnycastAddress; + void *dummy2; + void *dummy3; + void *dummy4; + void *dummy5; + void *dummy6; + BYTE dummy7[8]; + DWORD dummy8; + DWORD dummy9; + DWORD dummy10; + DWORD IfType; + int OperStatus; + DWORD dummy12; + DWORD dummy13[16]; + void *dummy14; } ip_adapter_addresses_t; typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG); HMODULE h; @@ -1801,49 +1803,49 @@ socket_s_ip_address_list(VALUE self) h = LoadLibrary("iphlpapi.dll"); if (!h) - rb_notimplement(); + rb_notimplement(); pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h, "GetAdaptersAddresses"); if (!pGetAdaptersAddresses) { - FreeLibrary(h); - rb_notimplement(); + FreeLibrary(h); + rb_notimplement(); } ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &len); if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) { - errno = rb_w32_map_errno(ret); - FreeLibrary(h); - rb_sys_fail("GetAdaptersAddresses"); + errno = rb_w32_map_errno(ret); + FreeLibrary(h); + rb_sys_fail("GetAdaptersAddresses"); } adapters = (ip_adapter_addresses_t *)ALLOCA_N(BYTE, len); ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len); if (ret != ERROR_SUCCESS) { - errno = rb_w32_map_errno(ret); - FreeLibrary(h); - rb_sys_fail("GetAdaptersAddresses"); + errno = rb_w32_map_errno(ret); + FreeLibrary(h); + rb_sys_fail("GetAdaptersAddresses"); } list = rb_ary_new(); for (; adapters; adapters = adapters->Next) { - ip_adapter_unicast_address_t *uni; - ip_adapter_anycast_address_t *any; - if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */ - continue; - for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) { + ip_adapter_unicast_address_t *uni; + ip_adapter_anycast_address_t *any; + if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */ + continue; + for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) { #ifndef INET6 - if (uni->Address.lpSockaddr->sa_family == AF_INET) + if (uni->Address.lpSockaddr->sa_family == AF_INET) #else - if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family)) + if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family)) #endif - rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength)); - } - for (any = adapters->FirstAnycastAddress; any; any = any->Next) { + rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength)); + } + for (any = adapters->FirstAnycastAddress; any; any = any->Next) { #ifndef INET6 - if (any->Address.lpSockaddr->sa_family == AF_INET) + if (any->Address.lpSockaddr->sa_family == AF_INET) #else - if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family)) + if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family)) #endif - rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength)); - } + rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength)); + } } FreeLibrary(h); @@ -1987,7 +1989,7 @@ Init_socket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, - "__connect_nonblock", sock_connect_nonblock, 2); + "__connect_nonblock", sock_connect_nonblock, 2); rb_define_method(rb_cSocket, "bind", sock_bind, 1); rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1); @@ -1995,7 +1997,7 @@ Init_socket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, - "__accept_nonblock", sock_accept_nonblock, 1); + "__accept_nonblock", sock_accept_nonblock, 1); rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0); @@ -2003,7 +2005,7 @@ Init_socket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, - "__recvfrom_nonblock", sock_recvfrom_nonblock, 4); + "__recvfrom_nonblock", sock_recvfrom_nonblock, 4); rb_define_singleton_method(rb_cSocket, "socketpair", rsock_sock_s_socketpair, -1); rb_define_singleton_method(rb_cSocket, "pair", rsock_sock_s_socketpair, -1); @@ -2017,7 +2019,7 @@ Init_socket(void) rb_define_singleton_method(rb_cSocket, "sockaddr_in", sock_s_pack_sockaddr_in, 2); rb_define_singleton_method(rb_cSocket, "pack_sockaddr_in", sock_s_pack_sockaddr_in, 2); rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_in", sock_s_unpack_sockaddr_in, 1); -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN rb_define_singleton_method(rb_cSocket, "sockaddr_un", sock_s_pack_sockaddr_un, 1); rb_define_singleton_method(rb_cSocket, "pack_sockaddr_un", sock_s_pack_sockaddr_un, 1); rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_un", sock_s_unpack_sockaddr_un, 1); diff --git a/ext/socket/sockssocket.c b/ext/socket/sockssocket.c index b8b7e12998..f263ac3804 100644 --- a/ext/socket/sockssocket.c +++ b/ext/socket/sockssocket.c @@ -30,8 +30,8 @@ socks_init(VALUE sock, VALUE host, VALUE port) static int init = 0; if (init == 0) { - SOCKSinit("ruby"); - init = 1; + SOCKSinit("ruby"); + init = 1; } return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS, Qnil, Qnil); diff --git a/ext/socket/tcpserver.c b/ext/socket/tcpserver.c index 675733c6f9..04e5a0bb51 100644 --- a/ext/socket/tcpserver.c +++ b/ext/socket/tcpserver.c @@ -133,7 +133,7 @@ rsock_init_tcpserver(void) rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket); rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0); rb_define_private_method(rb_cTCPServer, - "__accept_nonblock", tcp_accept_nonblock, 1); + "__accept_nonblock", tcp_accept_nonblock, 1); rb_define_method(rb_cTCPServer, "sysaccept", tcp_sysaccept, 0); rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1); rb_define_method(rb_cTCPServer, "listen", rsock_sock_listen, 1); /* in socket.c */ diff --git a/ext/socket/tcpsocket.c b/ext/socket/tcpsocket.c index 51e77a0de9..03787272f3 100644 --- a/ext/socket/tcpsocket.c +++ b/ext/socket/tcpsocket.c @@ -32,22 +32,22 @@ tcp_init(int argc, VALUE *argv, VALUE sock) VALUE connect_timeout = Qnil; if (!keyword_ids[0]) { - CONST_ID(keyword_ids[0], "resolv_timeout"); - CONST_ID(keyword_ids[1], "connect_timeout"); + CONST_ID(keyword_ids[0], "resolv_timeout"); + CONST_ID(keyword_ids[1], "connect_timeout"); } rb_scan_args(argc, argv, "22:", &remote_host, &remote_serv, - &local_host, &local_serv, &opt); + &local_host, &local_serv, &opt); if (!NIL_P(opt)) { - rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs); - if (kwargs[0] != Qundef) { resolv_timeout = kwargs[0]; } - if (kwargs[1] != Qundef) { connect_timeout = kwargs[1]; } + rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs); + if (kwargs[0] != Qundef) { resolv_timeout = kwargs[0]; } + if (kwargs[1] != Qundef) { connect_timeout = kwargs[1]; } } return rsock_init_inetsock(sock, remote_host, remote_serv, - local_host, local_serv, INET_CLIENT, - resolv_timeout, connect_timeout); + local_host, local_serv, INET_CLIENT, + resolv_timeout, connect_timeout); } static VALUE @@ -80,7 +80,7 @@ tcp_s_gethostbyname(VALUE obj, VALUE host) { rb_warn("TCPSocket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead."); struct rb_addrinfo *res = - rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); return rsock_make_hostent(host, res, tcp_sockaddr); } diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index 2bfd7c8560..5224e48a96 100644 --- a/ext/socket/udpsocket.c +++ b/ext/socket/udpsocket.c @@ -33,11 +33,11 @@ udp_init(int argc, VALUE *argv, VALUE sock) int fd; if (rb_scan_args(argc, argv, "01", &arg) == 1) { - family = rsock_family_arg(arg); + family = rsock_family_arg(arg); } fd = rsock_socket(family, SOCK_DGRAM, 0); if (fd < 0) { - rb_sys_fail("socket(2) - udp"); + rb_sys_fail("socket(2) - udp"); } return rsock_init_sock(sock, fd); @@ -60,9 +60,9 @@ udp_connect_internal(VALUE v) rb_io_check_closed(fptr = arg->fptr); fd = fptr->fd; for (res = arg->res->ai; res; res = res->ai_next) { - if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0, NULL) >= 0) { - return Qtrue; - } + if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0, NULL) >= 0) { + return Qtrue; + } } return Qfalse; } @@ -92,7 +92,7 @@ udp_connect(VALUE sock, VALUE host, VALUE port) GetOpenFile(sock, arg.fptr); arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); ret = rb_ensure(udp_connect_internal, (VALUE)&arg, - rsock_freeaddrinfo, (VALUE)arg.res); + rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("connect(2)", host, port); return INT2FIX(0); } @@ -108,10 +108,10 @@ udp_bind_internal(VALUE v) rb_io_check_closed(fptr = arg->fptr); fd = fptr->fd; for (res = arg->res->ai; res; res = res->ai_next) { - if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { - continue; - } - return Qtrue; + if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { + continue; + } + return Qtrue; } return Qfalse; } @@ -137,7 +137,7 @@ udp_bind(VALUE sock, VALUE host, VALUE port) GetOpenFile(sock, arg.fptr); arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); ret = rb_ensure(udp_bind_internal, (VALUE)&arg, - rsock_freeaddrinfo, (VALUE)arg.res); + rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("bind(2)", host, port); return INT2FIX(0); } @@ -170,7 +170,7 @@ udp_send_internal(VALUE v) if (n >= 0) return RB_SSIZE2NUM(n); - if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + if (rb_io_maybe_wait_writable(errno, fptr->self, RUBY_IO_TIMEOUT_DEFAULT)) { goto retry; } } @@ -207,7 +207,7 @@ udp_send(int argc, VALUE *argv, VALUE sock) VALUE ret; if (argc == 2 || argc == 3) { - return rsock_bsock_send(argc, argv, sock); + return rsock_bsock_send(argc, argv, sock); } rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port); @@ -217,7 +217,7 @@ udp_send(int argc, VALUE *argv, VALUE sock) arg.sarg.flags = NUM2INT(flags); arg.res = rsock_addrinfo(host, port, rsock_fd_family(arg.fptr->fd), SOCK_DGRAM, 0); ret = rb_ensure(udp_send_internal, (VALUE)&arg, - rsock_freeaddrinfo, (VALUE)arg.res); + rsock_freeaddrinfo, (VALUE)arg.res); if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port); return ret; } @@ -246,5 +246,5 @@ rsock_init_udpsocket(void) /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cUDPSocket, - "__recvfrom_nonblock", udp_recvfrom_nonblock, 4); + "__recvfrom_nonblock", udp_recvfrom_nonblock, 4); } diff --git a/ext/socket/unixserver.c b/ext/socket/unixserver.c index 890f9d3fae..0ea5ac083c 100644 --- a/ext/socket/unixserver.c +++ b/ext/socket/unixserver.c @@ -10,7 +10,7 @@ #include "rubysocket.h" -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * call-seq: * UNIXServer.new(path) => unixserver @@ -66,7 +66,7 @@ unix_accept_nonblock(VALUE sock, VALUE ex) GetOpenFile(sock, fptr); fromlen = (socklen_t)sizeof(from); return rsock_s_accept_nonblock(rb_cUNIXSocket, ex, fptr, - (struct sockaddr *)&from, &fromlen); + (struct sockaddr *)&from, &fromlen); } /* @@ -101,7 +101,7 @@ unix_sysaccept(VALUE server) void rsock_init_unixserver(void) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * Document-class: UNIXServer < UNIXSocket * @@ -113,7 +113,7 @@ rsock_init_unixserver(void) rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); rb_define_private_method(rb_cUNIXServer, - "__accept_nonblock", unix_accept_nonblock, 1); + "__accept_nonblock", unix_accept_nonblock, 1); rb_define_method(rb_cUNIXServer, "sysaccept", unix_sysaccept, 0); rb_define_method(rb_cUNIXServer, "listen", rsock_sock_listen, 1); /* in socket.c */ diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index 857cfa6002..a8475e3e60 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -10,7 +10,7 @@ #include "rubysocket.h" -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN struct unixsock_arg { struct sockaddr_un *sockaddr; socklen_t sockaddrlen; @@ -22,7 +22,7 @@ unixsock_connect_internal(VALUE a) { struct unixsock_arg *arg = (struct unixsock_arg *)a; return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, - arg->sockaddrlen, 0, NULL); + arg->sockaddrlen, 0, NULL); } static VALUE @@ -43,6 +43,10 @@ unixsock_path_value(VALUE path) } } #endif +#ifdef _WIN32 + /* UNIXSocket requires UTF-8 per spec. */ + path = rb_str_export_to_enc(path, rb_utf8_encoding()); +#endif return rb_get_path(path); } @@ -66,42 +70,42 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) fd = rsock_socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { - rsock_sys_fail_path("socket(2)", path); + rsock_sys_fail_path("socket(2)", path); } if (server) { status = bind(fd, (struct sockaddr*)&sockaddr, sockaddrlen); } else { - int prot; - struct unixsock_arg arg; - arg.sockaddr = &sockaddr; - arg.sockaddrlen = sockaddrlen; - arg.fd = fd; + int prot; + struct unixsock_arg arg; + arg.sockaddr = &sockaddr; + arg.sockaddrlen = sockaddrlen; + arg.fd = fd; status = (int)rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot); - if (prot) { - close(fd); - rb_jump_tag(prot); - } + if (prot) { + close(fd); + rb_jump_tag(prot); + } } if (status < 0) { - int e = errno; - close(fd); - rsock_syserr_fail_path(e, "connect(2)", path); + int e = errno; + close(fd); + rsock_syserr_fail_path(e, "connect(2)", path); } if (server) { - if (listen(fd, SOMAXCONN) < 0) { - int e = errno; - close(fd); - rsock_syserr_fail_path(e, "listen(2)", path); - } + if (listen(fd, SOMAXCONN) < 0) { + int e = errno; + close(fd); + rsock_syserr_fail_path(e, "listen(2)", path); + } } rsock_init_sock(sock, fd); if (server) { - GetOpenFile(sock, fptr); + GetOpenFile(sock, fptr); fptr->pathv = rb_str_new_frozen(path); } @@ -143,13 +147,13 @@ unix_path(VALUE sock) GetOpenFile(sock, fptr); if (NIL_P(fptr->pathv)) { - struct sockaddr_un addr; - socklen_t len = (socklen_t)sizeof(addr); - socklen_t len0 = len; - if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) + struct sockaddr_un addr; + socklen_t len = (socklen_t)sizeof(addr); + socklen_t len0 = len; + if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rsock_sys_fail_path("getsockname(2)", fptr->pathv); if (len0 < len) len = len0; - fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len)); + fptr->pathv = rb_obj_freeze(rsock_unixpath_str(&addr, len)); } return rb_str_dup(fptr->pathv); } @@ -240,21 +244,21 @@ unix_send_io(VALUE sock, VALUE val) #if FD_PASSING_BY_MSG_CONTROL union { - struct cmsghdr hdr; - char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; + struct cmsghdr hdr; + char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; } cmsg; #endif if (rb_obj_is_kind_of(val, rb_cIO)) { rb_io_t *valfptr; - GetOpenFile(val, valfptr); - fd = valfptr->fd; + GetOpenFile(val, valfptr); + fd = valfptr->fd; } else if (FIXNUM_P(val)) { fd = FIX2INT(val); } else { - rb_raise(rb_eTypeError, "neither IO nor file descriptor"); + rb_raise(rb_eTypeError, "neither IO nor file descriptor"); } GetOpenFile(sock, fptr); @@ -285,8 +289,8 @@ unix_send_io(VALUE sock, VALUE val) arg.fd = fptr->fd; while ((int)BLOCKING_REGION_FD(sendmsg_blocking, &arg) == -1) { - if (!rb_io_wait_writable(arg.fd)) - rsock_sys_fail_path("sendmsg(2)", fptr->pathv); + if (!rb_io_wait_writable(arg.fd)) + rsock_sys_fail_path("sendmsg(2)", fptr->pathv); } return Qnil; @@ -348,16 +352,16 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) int fd; #if FD_PASSING_BY_MSG_CONTROL union { - struct cmsghdr hdr; - char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; + struct cmsghdr hdr; + char pad[sizeof(struct cmsghdr)+8+sizeof(int)+8]; } cmsg; #endif rb_scan_args(argc, argv, "02", &klass, &mode); if (argc == 0) - klass = rb_cIO; + klass = rb_cIO; if (argc <= 1) - mode = Qnil; + mode = Qnil; retry: GetOpenFile(sock, fptr); @@ -400,8 +404,8 @@ retry: rb_gc_for_fd(e); goto retry; } - if (!rb_io_wait_readable(arg.fd)) - rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv); + if (!rb_io_wait_readable(arg.fd)) + rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv); } #if FD_PASSING_BY_MSG_CONTROL @@ -412,41 +416,41 @@ retry: rb_gc_for_fd(EMFILE); goto retry; } - rb_raise(rb_eSocket, - "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)", - (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr)); + rb_raise(rb_eSocket, + "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)", + (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr)); } if (cmsg.hdr.cmsg_level != SOL_SOCKET) { - rb_raise(rb_eSocket, - "file descriptor was not passed (cmsg_level=%d, %d expected)", - cmsg.hdr.cmsg_level, SOL_SOCKET); + rb_raise(rb_eSocket, + "file descriptor was not passed (cmsg_level=%d, %d expected)", + cmsg.hdr.cmsg_level, SOL_SOCKET); } if (cmsg.hdr.cmsg_type != SCM_RIGHTS) { - rb_raise(rb_eSocket, - "file descriptor was not passed (cmsg_type=%d, %d expected)", - cmsg.hdr.cmsg_type, SCM_RIGHTS); + rb_raise(rb_eSocket, + "file descriptor was not passed (cmsg_type=%d, %d expected)", + cmsg.hdr.cmsg_type, SCM_RIGHTS); } if (arg.msg.msg_controllen < (socklen_t)CMSG_LEN(sizeof(int))) { - rb_raise(rb_eSocket, - "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)", - (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int))); + rb_raise(rb_eSocket, + "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)", + (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int))); } if ((socklen_t)CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) { - rb_raise(rb_eSocket, - "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)", - (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int))); + rb_raise(rb_eSocket, + "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)", + (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int))); } if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) { - rsock_discard_cmsg_resource(&arg.msg, 0); - rb_raise(rb_eSocket, - "file descriptor was not passed (cmsg_len=%d, %d expected)", - (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); + rsock_discard_cmsg_resource(&arg.msg, 0); + rb_raise(rb_eSocket, + "file descriptor was not passed (cmsg_len=%d, %d expected)", + (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); } #else if (arg.msg.msg_accrightslen != sizeof(fd)) { - rb_raise(rb_eSocket, - "file descriptor was not passed (accrightslen=%d, %d expected)", - arg.msg.msg_accrightslen, (int)sizeof(fd)); + rb_raise(rb_eSocket, + "file descriptor was not passed (accrightslen=%d, %d expected)", + arg.msg.msg_accrightslen, (int)sizeof(fd)); } #endif @@ -458,15 +462,15 @@ retry: rb_maygvl_fd_fix_cloexec(fd); if (klass == Qnil) - return INT2FIX(fd); + return INT2FIX(fd); else { - ID for_fd; - int ff_argc; - VALUE ff_argv[2]; - CONST_ID(for_fd, "for_fd"); - ff_argc = mode == Qnil ? 1 : 2; - ff_argv[0] = INT2FIX(fd); - ff_argv[1] = mode; + ID for_fd; + int ff_argc; + VALUE ff_argv[2]; + CONST_ID(for_fd, "for_fd"); + ff_argc = mode == Qnil ? 1 : 2; + ff_argv[0] = INT2FIX(fd); + ff_argv[1] = mode; return rb_funcallv(klass, for_fd, ff_argc, ff_argv); } } @@ -536,7 +540,7 @@ unix_peeraddr(VALUE sock) * * Creates a pair of sockets connected to each other. * - * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. + * _type_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. * * _protocol_ should be a protocol defined in the domain. * 0 is default protocol for the domain. @@ -556,9 +560,9 @@ unix_s_socketpair(int argc, VALUE *argv, VALUE klass) domain = INT2FIX(PF_UNIX); rb_scan_args(argc, argv, "02", &type, &protocol); if (argc == 0) - type = INT2FIX(SOCK_STREAM); + type = INT2FIX(SOCK_STREAM); if (argc <= 1) - protocol = INT2FIX(0); + protocol = INT2FIX(0); args[0] = domain; args[1] = type; @@ -571,7 +575,7 @@ unix_s_socketpair(int argc, VALUE *argv, VALUE klass) void rsock_init_unixsocket(void) { -#ifdef HAVE_SYS_UN_H +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN /* * Document-class: UNIXSocket < BasicSocket * |