diff options
Diffstat (limited to 'ext/socket')
| -rw-r--r-- | ext/socket/ancdata.c | 310 | ||||
| -rw-r--r-- | ext/socket/basicsocket.c | 205 | ||||
| -rw-r--r-- | ext/socket/constants.c | 3 | ||||
| -rw-r--r-- | ext/socket/depend | 2603 | ||||
| -rw-r--r-- | ext/socket/extconf.rb | 47 | ||||
| -rw-r--r-- | ext/socket/getaddrinfo.c | 16 | ||||
| -rw-r--r-- | ext/socket/getnameinfo.c | 10 | ||||
| -rw-r--r-- | ext/socket/ifaddr.c | 93 | ||||
| -rw-r--r-- | ext/socket/init.c | 533 | ||||
| -rw-r--r-- | ext/socket/ipsocket.c | 91 | ||||
| -rw-r--r-- | ext/socket/lib/socket.rb | 614 | ||||
| -rw-r--r-- | ext/socket/mkconstants.rb | 65 | ||||
| -rw-r--r-- | ext/socket/option.c | 44 | ||||
| -rw-r--r-- | ext/socket/raddrinfo.c | 340 | ||||
| -rw-r--r-- | ext/socket/rubysocket.h | 139 | ||||
| -rw-r--r-- | ext/socket/socket.c | 606 | ||||
| -rw-r--r-- | ext/socket/sockssocket.c | 14 | ||||
| -rw-r--r-- | ext/socket/tcpserver.c | 68 | ||||
| -rw-r--r-- | ext/socket/tcpsocket.c | 45 | ||||
| -rw-r--r-- | ext/socket/udpsocket.c | 196 | ||||
| -rw-r--r-- | ext/socket/unixserver.c | 68 | ||||
| -rw-r--r-- | ext/socket/unixsocket.c | 81 |
22 files changed, 4710 insertions, 1481 deletions
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index b69417e9db..aa62cab0ec 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -2,7 +2,7 @@ #include <time.h> -int rsock_cmsg_cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */ +static VALUE sym_wait_readable, sym_wait_writable; #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) static VALUE rb_cAncillaryData; @@ -88,9 +88,9 @@ ancillary_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE vtype, VALUE static VALUE ancdata_new(int family, int level, int type, VALUE data) { - NEWOBJ_OF(obj, struct RObject, rb_cAncillaryData, T_OBJECT); + VALUE obj = rb_obj_alloc(rb_cAncillaryData); StringValue(data); - ancillary_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(type), data); + ancillary_initialize(obj, INT2NUM(family), INT2NUM(level), INT2NUM(type), data); return (VALUE)obj; } @@ -206,7 +206,7 @@ ancillary_s_unix_rights(int argc, VALUE *argv, VALUE klass) str = rb_str_buf_new(sizeof(int) * argc); for (i = 0 ; i < argc; i++) { - VALUE obj = RARRAY_PTR(ary)[i]; + VALUE obj = RARRAY_AREF(ary, i); rb_io_t *fptr; int fd; GetOpenFile(obj, fptr); @@ -359,6 +359,8 @@ ancillary_timestamp(VALUE self) * * The size and endian is dependent on the host. * + * require 'socket' + * * p Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, STDERR.fileno) * #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 2> */ @@ -849,6 +851,12 @@ anc_inspect_ipv6_pktinfo(int level, int type, VALUE data, VALUE ret) } #endif +#ifdef HAVE_GMTIME_R +# define LOCALTIME(time, tm) localtime_r(&(time), &(tm)) +#else +# define LOCALTIME(time, tm) ((tm) = *localtime(&(time))) +#endif + #if defined(SCM_TIMESTAMP) /* GNU/Linux, FreeBSD, NetBSD, OpenBSD, MacOS X, Solaris */ static int inspect_timeval_as_abstime(int level, int optname, VALUE data, VALUE ret) @@ -860,7 +868,7 @@ inspect_timeval_as_abstime(int level, int optname, VALUE data, VALUE ret) char buf[32]; memcpy((char*)&tv, RSTRING_PTR(data), sizeof(tv)); time = tv.tv_sec; - tm = *localtime(&time); + LOCALTIME(time, tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); rb_str_catf(ret, " %s.%06ld", buf, (long)tv.tv_usec); return 1; @@ -880,7 +888,7 @@ inspect_timespec_as_abstime(int level, int optname, VALUE data, VALUE ret) struct tm tm; char buf[32]; memcpy((char*)&ts, RSTRING_PTR(data), sizeof(ts)); - tm = *localtime(&ts.tv_sec); + LOCALTIME(ts.tv_sec, tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); rb_str_catf(ret, " %s.%09ld", buf, (long)ts.tv_nsec); return 1; @@ -904,7 +912,7 @@ inspect_bintime_as_abstime(int level, int optname, VALUE data, VALUE ret) uint64_t res_h, res_l; char buf[32]; memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt)); - tm = *localtime(&bt.sec); + LOCALTIME(bt.sec, tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); /* res_h = frac * 10**19 / 2**64 */ @@ -989,7 +997,7 @@ ancillary_inspect(VALUE self) vtype = ip_cmsg_type_to_sym(level, type); if (SYMBOL_P(vtype)) - rb_str_catf(ret, " %s", rb_id2name(SYM2ID(vtype))); + rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(vtype)); else rb_str_catf(ret, " cmsg_type:%d", type); } @@ -1127,16 +1135,17 @@ rb_sendmsg(int fd, const struct msghdr *msg, int flags) } static VALUE -bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) +bsock_sendmsg_internal(VALUE sock, VALUE data, VALUE vflags, + VALUE dest_sockaddr, VALUE controls, VALUE ex, + int nonblock) { rb_io_t *fptr; - VALUE data, vflags, dest_sockaddr; - int controls_num; struct msghdr mh; struct iovec iov; + VALUE tmp; + int controls_num; #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) VALUE controls_str = 0; - VALUE *controls_ptr = NULL; int family; #endif int flags; @@ -1144,27 +1153,22 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) GetOpenFile(sock, fptr); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - family = rsock_getfamily(fptr->fd); -#endif - - data = vflags = dest_sockaddr = Qnil; - - if (argc == 0) - rb_raise(rb_eArgError, "mesg argument required"); - data = argv[0]; - if (1 < argc) vflags = argv[1]; - if (2 < argc) dest_sockaddr = argv[2]; - controls_num = 3 < argc ? argc - 3 : 0; -#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (3 < argc) { controls_ptr = &argv[3]; } + family = rsock_getfamily(fptr); #endif StringValue(data); + tmp = rb_str_tmp_frozen_acquire(data); + + if (!RB_TYPE_P(controls, T_ARRAY)) { + 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); #if defined(__NetBSD__) int last_level = 0; int last_type = 0; @@ -1239,6 +1243,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) rb_str_set_len(controls_str, RSTRING_LEN(controls_str)-last_pad); #endif } + RB_GC_GUARD(controls); #else rb_raise(rb_eNotImpError, "control message for sendmsg is unimplemented"); #endif @@ -1263,98 +1268,63 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) } mh.msg_iovlen = 1; mh.msg_iov = &iov; - iov.iov_base = RSTRING_PTR(data); - iov.iov_len = RSTRING_LEN(data); + iov.iov_base = RSTRING_PTR(tmp); + iov.iov_len = RSTRING_LEN(tmp); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (controls_str) { mh.msg_control = RSTRING_PTR(controls_str); mh.msg_controllen = RSTRING_SOCKLEN(controls_str); } - else { - mh.msg_control = NULL; - mh.msg_controllen = 0; - } #endif rb_io_check_closed(fptr); - if (nonblock) + if (nonblock && !MSG_DONTWAIT_RELIABLE) rb_io_set_nonblock(fptr); ss = rb_sendmsg(fptr->fd, &mh, flags); if (ss == -1) { - if (!nonblock && rb_io_wait_writable(fptr->fd)) { + int e; + if (!nonblock && rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { rb_io_check_closed(fptr); goto retry; } - if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) - rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block"); - rb_sys_fail("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); #endif + rb_str_tmp_frozen_release(data, tmp); return SSIZET2NUM(ss); } #endif #if defined(HAVE_SENDMSG) -/* - * call-seq: - * basicsocket.sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent - * - * sendmsg sends a message using sendmsg(2) system call in blocking manner. - * - * _mesg_ is a string to send. - * - * _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_OOB. - * - * _dest_sockaddr_ is a destination socket address for connection-less socket. - * It should be a sockaddr such as a result of Socket.sockaddr_in. - * An Addrinfo object can be used too. - * - * _controls_ is a list of ancillary data. - * The element of _controls_ should be Socket::AncillaryData or - * 3-elements array. - * The 3-element array should contains cmsg_level, cmsg_type and data. - * - * The return value, _numbytes_sent_ is an integer which is the number of bytes sent. - * - * sendmsg can be used to implement send_io as follows: - * - * # use Socket::AncillaryData. - * ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno) - * sock.sendmsg("a", 0, nil, ancdata) - * - * # use 3-element array. - * ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")] - * sock.sendmsg("\0", 0, nil, ancdata) - * - */ VALUE -rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock) +rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, VALUE dest_sockaddr, + VALUE controls) { - return bsock_sendmsg_internal(argc, argv, sock, 0); + return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, controls, + Qtrue, 0); } #endif #if defined(HAVE_SENDMSG) -/* - * call-seq: - * basicsocket.sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent - * - * sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner. - * - * It is similar to BasicSocket#sendmsg - * but the non-blocking flag is set before the system call - * and it doesn't retry the system call. - * - */ VALUE -rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock) +rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, + VALUE dest_sockaddr, VALUE controls, VALUE ex) { - return bsock_sendmsg_internal(argc, argv, sock, 1); + return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, + controls, ex, 1); } #endif @@ -1464,10 +1434,7 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end) if (fstat(fd, &stbuf) == -1) rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS"); rb_update_max_fd(fd); - if (rsock_cmsg_cloexec_state < 0) - rsock_cmsg_cloexec_state = rsock_detect_cloexec(fd); - if (rsock_cmsg_cloexec_state == 0 || fd <= 2) - rb_maygvl_fd_fix_cloexec(fd); + rb_maygvl_fd_fix_cloexec(fd); if (S_ISSOCK(stbuf.st_mode)) io = rsock_init_sock(rb_obj_alloc(rb_cSocket), fd); else @@ -1482,18 +1449,18 @@ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end) #endif static VALUE -bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) +bsock_recvmsg_internal(VALUE sock, + VALUE vmaxdatlen, VALUE vflags, VALUE vmaxctllen, + VALUE scm_rights, VALUE ex, int nonblock) { rb_io_t *fptr; - VALUE vmaxdatlen, vmaxctllen, vflags; - VALUE vopts; int grow_buffer; size_t maxdatlen; int flags, orig_flags; struct msghdr mh; struct iovec iov; union_sockaddr namebuf; - char datbuf0[4096], *datbuf; + char *datbuf; VALUE dat_str = Qnil; VALUE ret; ssize_t ss; @@ -1501,27 +1468,20 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) struct cmsghdr *cmh; size_t maxctllen; - union { - char bytes[4096]; - struct cmsghdr align; - } ctlbuf0; char *ctlbuf; VALUE ctl_str = Qnil; int family; int gc_done = 0; #endif - - rb_scan_args(argc, argv, "03:", &vmaxdatlen, &vflags, &vmaxctllen, &vopts); - - maxdatlen = NIL_P(vmaxdatlen) ? sizeof(datbuf0) : NUM2SIZET(vmaxdatlen); + maxdatlen = NIL_P(vmaxdatlen) ? 4096 : NUM2SIZET(vmaxdatlen); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - maxctllen = NIL_P(vmaxctllen) ? sizeof(ctlbuf0) : NUM2SIZET(vmaxctllen); + maxctllen = NIL_P(vmaxctllen) ? 4096 : NUM2SIZET(vmaxctllen); #else if (!NIL_P(vmaxctllen)) rb_raise(rb_eArgError, "control message not supported"); #endif - flags = NIL_P(vflags) ? 0 : NUM2INT(vflags); + flags = NUM2INT(vflags); #ifdef MSG_DONTWAIT if (nonblock) flags |= MSG_DONTWAIT; @@ -1531,7 +1491,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) grow_buffer = NIL_P(vmaxdatlen) || NIL_P(vmaxctllen); request_scm_rights = 0; - if (!NIL_P(vopts) && RTEST(rb_hash_aref(vopts, ID2SYM(rb_intern("scm_rights"))))) + if (RTEST(scm_rights)) request_scm_rights = 1; #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (request_scm_rights) @@ -1556,26 +1516,18 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) #endif retry: - if (maxdatlen <= sizeof(datbuf0)) - datbuf = datbuf0; - else { - if (NIL_P(dat_str)) - dat_str = rb_str_tmp_new(maxdatlen); - else - rb_str_resize(dat_str, maxdatlen); - datbuf = RSTRING_PTR(dat_str); - } + if (NIL_P(dat_str)) + dat_str = rb_str_tmp_new(maxdatlen); + else + rb_str_resize(dat_str, maxdatlen); + datbuf = RSTRING_PTR(dat_str); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (maxctllen <= sizeof(ctlbuf0)) - ctlbuf = ctlbuf0.bytes; - else { - if (NIL_P(ctl_str)) - ctl_str = rb_str_tmp_new(maxctllen); - else - rb_str_resize(ctl_str, maxctllen); - ctlbuf = RSTRING_PTR(ctl_str); - } + if (NIL_P(ctl_str)) + ctl_str = rb_str_tmp_new(maxctllen); + else + rb_str_resize(ctl_str, maxctllen); + ctlbuf = RSTRING_PTR(ctl_str); #endif memset(&mh, 0, sizeof(mh)); @@ -1598,20 +1550,26 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) flags |= MSG_PEEK; rb_io_check_closed(fptr); - if (nonblock) + if (nonblock && !MSG_DONTWAIT_RELIABLE) rb_io_set_nonblock(fptr); ss = rb_recvmsg(fptr->fd, &mh, flags); if (ss == -1) { - if (!nonblock && rb_io_wait_readable(fptr->fd)) { + int e; + if (!nonblock && rb_io_maybe_wait_readable(errno, fptr->self, Qnil)) { rb_io_check_closed(fptr); goto retry; } - if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN)) - rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvmsg(2) would block"); + 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"); + } #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (!gc_done && (errno == EMFILE || errno == 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 @@ -1623,19 +1581,23 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) gc_done = 1; goto retry; } +#else + if (NIL_P(vmaxdatlen) && grow_buffer && e == EMSGSIZE) + ss = (ssize_t)iov.iov_len; + else #endif - rb_sys_fail("recvmsg(2)"); + rb_syserr_fail(e, "recvmsg(2)"); } if (grow_buffer) { int grown = 0; -#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - if (NIL_P(vmaxdatlen) && (mh.msg_flags & MSG_TRUNC)) { + 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; } +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) if (NIL_P(vmaxctllen) && (mh.msg_flags & MSG_CTRUNC)) { #define BIG_ENOUGH_SPACE 65536 if (BIG_ENOUGH_SPACE < maxctllen && @@ -1655,13 +1617,6 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) } #undef BIG_ENOUGH_SPACE } -#else - 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; - } #endif if (grown) { rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); @@ -1678,10 +1633,9 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) } if (NIL_P(dat_str)) - dat_str = rb_tainted_str_new(datbuf, ss); + dat_str = rb_str_new(datbuf, ss); else { rb_str_resize(dat_str, ss); - OBJ_TAINT(dat_str); rb_obj_reveal(dat_str, rb_cString); } @@ -1695,7 +1649,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) ); #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) - family = rsock_getfamily(fptr->fd); + family = rsock_getfamily(fptr); if (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)) { @@ -1707,7 +1661,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) } ctl_end = (char*)cmh + cmh->cmsg_len; clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh); - ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_tainted_str_new((char*)CMSG_DATA(cmh), clen)); + 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); else @@ -1723,82 +1677,21 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) #endif #if defined(HAVE_RECVMSG) -/* - * call-seq: - * basicsocket.recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) => [mesg, sender_addrinfo, rflags, *controls] - * - * recvmsg receives a message using recvmsg(2) system call in blocking manner. - * - * _maxmesglen_ is the maximum length of mesg to receive. - * - * _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_PEEK. - * - * _maxcontrollen_ is the maximum length of controls (ancillary data) to receive. - * - * _opts_ is option hash. - * Currently :scm_rights=>bool is the only option. - * - * :scm_rights option specifies that application expects SCM_RIGHTS control message. - * If the value is nil or false, application don't expects SCM_RIGHTS control message. - * In this case, recvmsg closes the passed file descriptors immediately. - * This is the default behavior. - * - * If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message. - * In this case, recvmsg creates IO objects for each file descriptors for - * Socket::AncillaryData#unix_rights method. - * - * The return value is 4-elements array. - * - * _mesg_ is a string of the received message. - * - * _sender_addrinfo_ is a sender socket address for connection-less socket. - * It is an Addrinfo object. - * For connection-oriented socket such as TCP, sender_addrinfo is platform dependent. - * - * _rflags_ is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC. - * It will be nil if the system uses 4.3BSD style old recvmsg system call. - * - * _controls_ is ancillary data which is an array of Socket::AncillaryData objects such as: - * - * #<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7> - * - * _maxmesglen_ and _maxcontrollen_ can be nil. - * In that case, the buffer will be grown until the message is not truncated. - * Internally, MSG_PEEK is used and MSG_TRUNC/MSG_CTRUNC are checked. - * - * recvmsg can be used to implement recv_io as follows: - * - * mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true) - * controls.each {|ancdata| - * if ancdata.cmsg_is?(:SOCKET, :RIGHTS) - * return ancdata.unix_rights[0] - * end - * } - * - */ VALUE -rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock) +rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, + VALUE scm_rights) { - return bsock_recvmsg_internal(argc, argv, sock, 0); + VALUE ex = Qtrue; + return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 0); } #endif #if defined(HAVE_RECVMSG) -/* - * call-seq: - * basicsocket.recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) => [data, sender_addrinfo, rflags, *controls] - * - * recvmsg receives a message using recvmsg(2) system call in non-blocking manner. - * - * It is similar to BasicSocket#recvmsg - * but non-blocking flag is set before the system call - * and it doesn't retry the system call. - * - */ VALUE -rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock) +rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE flags, VALUE clen, + VALUE scm_rights, VALUE ex) { - return bsock_recvmsg_internal(argc, argv, sock, 1); + return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 1); } #endif @@ -1839,4 +1732,7 @@ rsock_init_ancdata(void) rb_define_method(rb_cAncillaryData, "ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0); rb_define_method(rb_cAncillaryData, "ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0); #endif +#undef rb_intern + sym_wait_readable = ID2SYM(rb_intern("wait_readable")); + sym_wait_writable = ID2SYM(rb_intern("wait_writable")); } diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 54559779cf..44fb7a4eb7 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -10,6 +10,28 @@ #include "rubysocket.h" +#ifdef _WIN32 +#define is_socket(fd) rb_w32_is_socket(fd) +#else +static int +is_socket(int fd) +{ + struct stat sbuf; + + if (fstat(fd, &sbuf) < 0) + rb_sys_fail("fstat(2)"); + return S_ISSOCK(sbuf.st_mode); +} +#endif + +static void +rsock_validate_descriptor(int descriptor) +{ + if (!is_socket(descriptor) || rb_reserved_fd_p(descriptor)) { + rb_syserr_fail(EBADF, "not a socket file descriptor"); + } +} + /* * call-seq: * BasicSocket.for_fd(fd) => basicsocket @@ -22,10 +44,14 @@ * */ static VALUE -bsock_s_for_fd(VALUE klass, VALUE fd) +bsock_s_for_fd(VALUE klass, VALUE _descriptor) { rb_io_t *fptr; - VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd)); + + int descriptor = RB_NUM2INT(_descriptor); + rsock_validate_descriptor(descriptor); + + VALUE sock = rsock_init_sock(rb_obj_alloc(klass), descriptor); GetOpenFile(sock, fptr); @@ -158,10 +184,10 @@ bsock_close_write(VALUE sock) * * +optval+ is the value of the option, it is passed to the underlying * setsockopt() as a pointer to a certain number of bytes. How this is * done depends on the type: - * - Fixnum: value is assigned to an int, and a pointer to the int is + * - Integer: value is assigned to an int, and a pointer to the int is * passed, with length of sizeof(int). * - true or false: 1 or 0 (respectively) is assigned to an int, and the - * int is passed as for a Fixnum. Note that +false+ must be passed, + * int is passed as for an Integer. Note that +false+ must be passed, * not +nil+. * - String: the string's data and length is passed to the socket. * * +socketoption+ is an instance of Socket::Option @@ -213,9 +239,8 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock) rb_scan_args(argc, argv, "30", &lev, &optname, &val); } - rb_secure(2); GetOpenFile(sock, fptr); - family = rsock_getfamily(fptr->fd); + family = rsock_getfamily(fptr); level = rsock_level_arg(family, lev); option = rsock_optname_arg(family, level, optname); @@ -245,7 +270,6 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock) return INT2FIX(0); } -#if !defined(__BEOS__) /* * Document-method: getsockopt * call-seq: @@ -282,7 +306,7 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock) * ipttl = sock.getsockopt(:IP, :TTL).int * * optval = sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL) - * ipttl = optval.unpack("i")[0] + * ipttl = optval.unpack1("i") * * Option values may be structs. Decoding them can be complex as it involves * examining your system headers to determine the correct definition. An @@ -312,10 +336,22 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname) int family; GetOpenFile(sock, fptr); - family = rsock_getfamily(fptr->fd); + family = rsock_getfamily(fptr); level = rsock_level_arg(family, lev); option = rsock_optname_arg(family, level, optname); len = 256; +#ifdef _AIX + switch (option) { + case SO_DEBUG: + case SO_REUSEADDR: + case SO_KEEPALIVE: + case SO_DONTROUTE: + case SO_BROADCAST: + case SO_OOBINLINE: + /* AIX doesn't set len for boolean options */ + len = sizeof(int); + } +#endif buf = ALLOCA_N(char,len); rb_io_check_closed(fptr); @@ -325,9 +361,6 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname) return rsock_sockopt_new(family, level, option, rb_str_new(buf, len)); } -#else -#define bsock_getsockopt rb_f_notimplement -#endif /* * call-seq: @@ -530,38 +563,50 @@ bsock_remote_address(VALUE sock) * } */ VALUE -rsock_bsock_send(int argc, VALUE *argv, VALUE sock) +rsock_bsock_send(int argc, VALUE *argv, VALUE socket) { struct rsock_send_arg arg; VALUE flags, to; rb_io_t *fptr; - int n; rb_blocking_function_t *func; + const char *funcname; rb_scan_args(argc, argv, "21", &arg.mesg, &flags, &to); StringValue(arg.mesg); if (!NIL_P(to)) { - SockAddrStringValue(to); - to = rb_str_new4(to); - arg.to = (struct sockaddr *)RSTRING_PTR(to); - arg.tolen = RSTRING_SOCKLEN(to); - func = rsock_sendto_blocking; + SockAddrStringValue(to); + to = rb_str_new4(to); + arg.to = (struct sockaddr *)RSTRING_PTR(to); + arg.tolen = RSTRING_SOCKLEN(to); + func = rsock_sendto_blocking; + funcname = "sendto(2)"; } else { - func = rsock_send_blocking; + func = rsock_send_blocking; + funcname = "send(2)"; } - GetOpenFile(sock, fptr); + + RB_IO_POINTER(socket, fptr); + arg.fd = fptr->fd; arg.flags = NUM2INT(flags); - while (rsock_maybe_fd_writable(arg.fd), - (n = (int)BLOCKING_REGION_FD(func, &arg)) < 0) { - if (rb_io_wait_writable(arg.fd)) { - continue; - } - rb_sys_fail("send(2)"); + + while (true) { +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(socket, RB_INT2NUM(RUBY_IO_WRITABLE), Qnil); +#endif + + ssize_t n = (ssize_t)BLOCKING_REGION_FD(func, &arg); + + if (n >= 0) return SSIZET2NUM(n); + + if (rb_io_maybe_wait_writable(errno, socket, Qnil)) { + continue; + } + + rb_sys_fail(funcname); } - return INT2FIX(n); } /* @@ -570,11 +615,15 @@ rsock_bsock_send(int argc, VALUE *argv, VALUE sock) * * Gets the do_not_reverse_lookup flag of _basicsocket_. * + * require 'socket' + * + * BasicSocket.do_not_reverse_lookup = false * TCPSocket.open("www.ruby-lang.org", 80) {|sock| * p sock.do_not_reverse_lookup #=> false - * p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68"] - * sock.do_not_reverse_lookup = true - * p sock.peeraddr #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"] + * } + * BasicSocket.do_not_reverse_lookup = true + * TCPSocket.open("www.ruby-lang.org", 80) {|sock| + * p sock.do_not_reverse_lookup #=> true * } */ static VALUE @@ -592,10 +641,12 @@ bsock_do_not_reverse_lookup(VALUE sock) * * Sets the do_not_reverse_lookup flag of _basicsocket_. * - * BasicSocket.do_not_reverse_lookup = false - * p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> false - * BasicSocket.do_not_reverse_lookup = true - * p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> true + * TCPSocket.open("www.ruby-lang.org", 80) {|sock| + * p sock.do_not_reverse_lookup #=> true + * p sock.peeraddr #=> ["AF_INET", 80, "221.186.184.68", "221.186.184.68"] + * sock.do_not_reverse_lookup = false + * p sock.peeraddr #=> ["AF_INET", 80, "carbon.ruby-lang.org", "54.163.249.195"] + * } * */ static VALUE @@ -615,8 +666,7 @@ bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state) /* * call-seq: - * basicsocket.recv(maxlen) => mesg - * basicsocket.recv(maxlen, flags) => mesg + * basicsocket.recv(maxlen[, flags[, outbuf]]) => mesg * * Receives a message. * @@ -624,6 +674,9 @@ bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state) * * _flags_ should be a bitwise OR of Socket::MSG_* constants. * + * _outbuf_ will contain only the received data after the method call + * even if it is not empty at the beginning. + * * UNIXSocket.pair {|s1, s2| * s1.puts "Hello World" * p s2.recv(4) #=> "Hell" @@ -638,55 +691,11 @@ bsock_recv(int argc, VALUE *argv, VALUE sock) return rsock_s_recvfrom(sock, argc, argv, RECV_RECV); } -/* - * call-seq: - * basicsocket.recv_nonblock(maxlen) => mesg - * basicsocket.recv_nonblock(maxlen, flags) => mesg - * - * Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * _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. - * - * === Parameters - * * +maxlen+ - the number of bytes to receive from the socket - * * +flags+ - zero or more of the +MSG_+ options - * - * === Example - * serv = TCPServer.new("127.0.0.1", 0) - * af, port, host, addr = serv.addr - * c = TCPSocket.new(addr, port) - * s = serv.accept - * c.send "aaa", 0 - * begin # emulate blocking recv. - * p s.recv_nonblock(10) #=> "aaa" - * rescue IO::WaitReadable - * IO.select([s]) - * retry - * end - * - * Refer to Socket#recvfrom for the exceptions that may be thrown if the call - * to _recv_nonblock_ fails. - * - * BasicSocket#recv_nonblock may raise any error corresponding to recvfrom(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock. - * - * === See - * * Socket#recvfrom - */ - +/* :nodoc: */ static VALUE -bsock_recv_nonblock(int argc, VALUE *argv, VALUE sock) +bsock_recv_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex) { - return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_RECV); + return rsock_s_recvfrom_nonblock(sock, len, flg, str, ex, RECV_RECV); } /* @@ -698,7 +707,7 @@ bsock_recv_nonblock(int argc, VALUE *argv, VALUE sock) * BasicSocket.do_not_reverse_lookup #=> false */ static VALUE -bsock_do_not_rev_lookup(void) +bsock_do_not_rev_lookup(VALUE _) { return rsock_do_not_reverse_lookup?Qtrue:Qfalse; } @@ -755,13 +764,29 @@ rsock_init_basicsocket(void) rb_define_method(rb_cBasicSocket, "remote_address", bsock_remote_address, 0); rb_define_method(rb_cBasicSocket, "send", rsock_bsock_send, -1); rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1); - rb_define_method(rb_cBasicSocket, "recv_nonblock", bsock_recv_nonblock, -1); + rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_reverse_lookup, 0); rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_reverse_lookup_set, 1); - rb_define_method(rb_cBasicSocket, "sendmsg", rsock_bsock_sendmsg, -1); /* in ancdata.c */ - rb_define_method(rb_cBasicSocket, "sendmsg_nonblock", rsock_bsock_sendmsg_nonblock, -1); /* in ancdata.c */ - rb_define_method(rb_cBasicSocket, "recvmsg", rsock_bsock_recvmsg, -1); /* in ancdata.c */ - rb_define_method(rb_cBasicSocket, "recvmsg_nonblock", rsock_bsock_recvmsg_nonblock, -1); /* in ancdata.c */ + /* for ext/socket/lib/socket.rb use only: */ + rb_define_private_method(rb_cBasicSocket, + "__recv_nonblock", bsock_recv_nonblock, 4); + +#if MSG_DONTWAIT_RELIABLE + rb_define_private_method(rb_cBasicSocket, + "__read_nonblock", rsock_read_nonblock, 3); + rb_define_private_method(rb_cBasicSocket, + "__write_nonblock", rsock_write_nonblock, 2); +#endif + + /* in ancdata.c */ + rb_define_private_method(rb_cBasicSocket, "__sendmsg", + rsock_bsock_sendmsg, 4); + rb_define_private_method(rb_cBasicSocket, "__sendmsg_nonblock", + rsock_bsock_sendmsg_nonblock, 5); + rb_define_private_method(rb_cBasicSocket, "__recvmsg", + rsock_bsock_recvmsg, 4); + rb_define_private_method(rb_cBasicSocket, "__recvmsg_nonblock", + rsock_bsock_recvmsg_nonblock, 5); } diff --git a/ext/socket/constants.c b/ext/socket/constants.c index bab27b23bb..1bbb53b173 100644 --- a/ext/socket/constants.c +++ b/ext/socket/constants.c @@ -22,13 +22,12 @@ constant_arg(VALUE arg, int (*str_to_int)(const char*, long, int*), const char * int ret; if (SYMBOL_P(arg)) { - arg = rb_sym_to_s(arg); + arg = rb_sym2str(arg); goto str; } else if (!NIL_P(tmp = rb_check_string_type(arg))) { arg = tmp; str: - rb_check_safe_obj(arg); ptr = RSTRING_PTR(arg); if (str_to_int(ptr, RSTRING_LEN(arg), &ret) == -1) rb_raise(rb_eSocket, "%s: %s", errmsg, ptr); diff --git a/ext/socket/depend b/ext/socket/depend index 30ecfc5b52..99617e2532 100644 --- a/ext/socket/depend +++ b/ext/socket/depend @@ -1,64 +1,581 @@ -getnameinfo.o: getnameinfo.c $(arch_hdrdir)/ruby/config.h addrinfo.h sockport.h +srcs: constdefs.h constdefs.c + +getnameinfo.o: getnameinfo.c $(arch_hdrdir)/ruby/config.h addrinfo.h sockport.h rubysocket.h getaddrinfo.o: getaddrinfo.c $(arch_hdrdir)/ruby/config.h addrinfo.h sockport.h -constdefs.h constdefs.c : $(srcdir)/mkconstants.rb +constdefs.h: $(srcdir)/mkconstants.rb @echo "generating constant definitions" @$(RUBY) $(srcdir)/mkconstants.rb -H constdefs.h -o constdefs.c +constdefs.c: constdefs.h + # AUTOGENERATED DEPENDENCIES START ancdata.o: $(RUBY_EXTCONF_H) ancdata.o: $(arch_hdrdir)/ruby/config.h +ancdata.o: $(hdrdir)/ruby/assert.h +ancdata.o: $(hdrdir)/ruby/backward.h +ancdata.o: $(hdrdir)/ruby/backward/2/assume.h +ancdata.o: $(hdrdir)/ruby/backward/2/attributes.h +ancdata.o: $(hdrdir)/ruby/backward/2/bool.h +ancdata.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +ancdata.o: $(hdrdir)/ruby/backward/2/inttypes.h +ancdata.o: $(hdrdir)/ruby/backward/2/limits.h +ancdata.o: $(hdrdir)/ruby/backward/2/long_long.h +ancdata.o: $(hdrdir)/ruby/backward/2/stdalign.h +ancdata.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ancdata.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ancdata.o: $(hdrdir)/ruby/internal/assume.h +ancdata.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ancdata.o: $(hdrdir)/ruby/internal/attr/artificial.h +ancdata.o: $(hdrdir)/ruby/internal/attr/cold.h +ancdata.o: $(hdrdir)/ruby/internal/attr/const.h +ancdata.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ancdata.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ancdata.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ancdata.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ancdata.o: $(hdrdir)/ruby/internal/attr/error.h +ancdata.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ancdata.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ancdata.o: $(hdrdir)/ruby/internal/attr/format.h +ancdata.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ancdata.o: $(hdrdir)/ruby/internal/attr/noalias.h +ancdata.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +ancdata.o: $(hdrdir)/ruby/internal/attr/restrict.h +ancdata.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ancdata.o: $(hdrdir)/ruby/internal/attr/warning.h +ancdata.o: $(hdrdir)/ruby/internal/attr/weakref.h +ancdata.o: $(hdrdir)/ruby/internal/cast.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ancdata.o: $(hdrdir)/ruby/internal/compiler_since.h +ancdata.o: $(hdrdir)/ruby/internal/config.h +ancdata.o: $(hdrdir)/ruby/internal/constant_p.h +ancdata.o: $(hdrdir)/ruby/internal/core.h +ancdata.o: $(hdrdir)/ruby/internal/core/rarray.h +ancdata.o: $(hdrdir)/ruby/internal/core/rbasic.h +ancdata.o: $(hdrdir)/ruby/internal/core/rbignum.h +ancdata.o: $(hdrdir)/ruby/internal/core/rclass.h +ancdata.o: $(hdrdir)/ruby/internal/core/rdata.h +ancdata.o: $(hdrdir)/ruby/internal/core/rfile.h +ancdata.o: $(hdrdir)/ruby/internal/core/rhash.h +ancdata.o: $(hdrdir)/ruby/internal/core/robject.h +ancdata.o: $(hdrdir)/ruby/internal/core/rregexp.h +ancdata.o: $(hdrdir)/ruby/internal/core/rstring.h +ancdata.o: $(hdrdir)/ruby/internal/core/rstruct.h +ancdata.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ancdata.o: $(hdrdir)/ruby/internal/ctype.h +ancdata.o: $(hdrdir)/ruby/internal/dllexport.h +ancdata.o: $(hdrdir)/ruby/internal/dosish.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/re.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/string.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ancdata.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ancdata.o: $(hdrdir)/ruby/internal/error.h +ancdata.o: $(hdrdir)/ruby/internal/eval.h +ancdata.o: $(hdrdir)/ruby/internal/event.h +ancdata.o: $(hdrdir)/ruby/internal/fl_type.h +ancdata.o: $(hdrdir)/ruby/internal/gc.h +ancdata.o: $(hdrdir)/ruby/internal/glob.h +ancdata.o: $(hdrdir)/ruby/internal/globals.h +ancdata.o: $(hdrdir)/ruby/internal/has/attribute.h +ancdata.o: $(hdrdir)/ruby/internal/has/builtin.h +ancdata.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ancdata.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ancdata.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ancdata.o: $(hdrdir)/ruby/internal/has/extension.h +ancdata.o: $(hdrdir)/ruby/internal/has/feature.h +ancdata.o: $(hdrdir)/ruby/internal/has/warning.h +ancdata.o: $(hdrdir)/ruby/internal/intern/array.h +ancdata.o: $(hdrdir)/ruby/internal/intern/bignum.h +ancdata.o: $(hdrdir)/ruby/internal/intern/class.h +ancdata.o: $(hdrdir)/ruby/internal/intern/compar.h +ancdata.o: $(hdrdir)/ruby/internal/intern/complex.h +ancdata.o: $(hdrdir)/ruby/internal/intern/cont.h +ancdata.o: $(hdrdir)/ruby/internal/intern/dir.h +ancdata.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +ancdata.o: $(hdrdir)/ruby/internal/intern/marshal.h +ancdata.o: $(hdrdir)/ruby/internal/intern/numeric.h +ancdata.o: $(hdrdir)/ruby/internal/intern/object.h +ancdata.o: $(hdrdir)/ruby/internal/intern/parse.h +ancdata.o: $(hdrdir)/ruby/internal/intern/proc.h +ancdata.o: $(hdrdir)/ruby/internal/intern/process.h +ancdata.o: $(hdrdir)/ruby/internal/intern/random.h +ancdata.o: $(hdrdir)/ruby/internal/intern/range.h +ancdata.o: $(hdrdir)/ruby/internal/intern/rational.h +ancdata.o: $(hdrdir)/ruby/internal/intern/re.h +ancdata.o: $(hdrdir)/ruby/internal/intern/ruby.h +ancdata.o: $(hdrdir)/ruby/internal/intern/select.h +ancdata.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ancdata.o: $(hdrdir)/ruby/internal/intern/signal.h +ancdata.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ancdata.o: $(hdrdir)/ruby/internal/intern/string.h +ancdata.o: $(hdrdir)/ruby/internal/intern/struct.h +ancdata.o: $(hdrdir)/ruby/internal/intern/thread.h +ancdata.o: $(hdrdir)/ruby/internal/intern/time.h +ancdata.o: $(hdrdir)/ruby/internal/intern/variable.h +ancdata.o: $(hdrdir)/ruby/internal/intern/vm.h +ancdata.o: $(hdrdir)/ruby/internal/interpreter.h +ancdata.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +ancdata.o: $(hdrdir)/ruby/internal/value.h +ancdata.o: $(hdrdir)/ruby/internal/value_type.h +ancdata.o: $(hdrdir)/ruby/internal/variable.h +ancdata.o: $(hdrdir)/ruby/internal/warning_push.h +ancdata.o: $(hdrdir)/ruby/internal/xmalloc.h ancdata.o: $(hdrdir)/ruby/io.h ancdata.o: $(hdrdir)/ruby/missing.h +ancdata.o: $(hdrdir)/ruby/onigmo.h ancdata.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -ancdata.o: $(top_srcdir)/include/ruby.h ancdata.o: $(top_srcdir)/internal.h +ancdata.o: $(top_srcdir)/internal/array.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/io.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: ancdata.c ancdata.o: constdefs.h ancdata.o: rubysocket.h ancdata.o: sockport.h basicsocket.o: $(RUBY_EXTCONF_H) basicsocket.o: $(arch_hdrdir)/ruby/config.h +basicsocket.o: $(hdrdir)/ruby/assert.h +basicsocket.o: $(hdrdir)/ruby/backward.h +basicsocket.o: $(hdrdir)/ruby/backward/2/assume.h +basicsocket.o: $(hdrdir)/ruby/backward/2/attributes.h +basicsocket.o: $(hdrdir)/ruby/backward/2/bool.h +basicsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +basicsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h +basicsocket.o: $(hdrdir)/ruby/backward/2/limits.h +basicsocket.o: $(hdrdir)/ruby/backward/2/long_long.h +basicsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h +basicsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +basicsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +basicsocket.o: $(hdrdir)/ruby/internal/assume.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/cold.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/const.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/error.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/format.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/warning.h +basicsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h +basicsocket.o: $(hdrdir)/ruby/internal/cast.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +basicsocket.o: $(hdrdir)/ruby/internal/compiler_since.h +basicsocket.o: $(hdrdir)/ruby/internal/config.h +basicsocket.o: $(hdrdir)/ruby/internal/constant_p.h +basicsocket.o: $(hdrdir)/ruby/internal/core.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rarray.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rclass.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rdata.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rfile.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rhash.h +basicsocket.o: $(hdrdir)/ruby/internal/core/robject.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rstring.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h +basicsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +basicsocket.o: $(hdrdir)/ruby/internal/ctype.h +basicsocket.o: $(hdrdir)/ruby/internal/dllexport.h +basicsocket.o: $(hdrdir)/ruby/internal/dosish.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/re.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/string.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +basicsocket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +basicsocket.o: $(hdrdir)/ruby/internal/error.h +basicsocket.o: $(hdrdir)/ruby/internal/eval.h +basicsocket.o: $(hdrdir)/ruby/internal/event.h +basicsocket.o: $(hdrdir)/ruby/internal/fl_type.h +basicsocket.o: $(hdrdir)/ruby/internal/gc.h +basicsocket.o: $(hdrdir)/ruby/internal/glob.h +basicsocket.o: $(hdrdir)/ruby/internal/globals.h +basicsocket.o: $(hdrdir)/ruby/internal/has/attribute.h +basicsocket.o: $(hdrdir)/ruby/internal/has/builtin.h +basicsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +basicsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +basicsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +basicsocket.o: $(hdrdir)/ruby/internal/has/extension.h +basicsocket.o: $(hdrdir)/ruby/internal/has/feature.h +basicsocket.o: $(hdrdir)/ruby/internal/has/warning.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/array.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/class.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/compar.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/complex.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/cont.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/dir.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +basicsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/object.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/parse.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/proc.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/process.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/random.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/range.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/rational.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/re.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/select.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/signal.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/string.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/struct.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/thread.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/time.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/variable.h +basicsocket.o: $(hdrdir)/ruby/internal/intern/vm.h +basicsocket.o: $(hdrdir)/ruby/internal/interpreter.h +basicsocket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +basicsocket.o: $(hdrdir)/ruby/internal/value.h +basicsocket.o: $(hdrdir)/ruby/internal/value_type.h +basicsocket.o: $(hdrdir)/ruby/internal/variable.h +basicsocket.o: $(hdrdir)/ruby/internal/warning_push.h +basicsocket.o: $(hdrdir)/ruby/internal/xmalloc.h basicsocket.o: $(hdrdir)/ruby/io.h basicsocket.o: $(hdrdir)/ruby/missing.h +basicsocket.o: $(hdrdir)/ruby/onigmo.h basicsocket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -basicsocket.o: $(top_srcdir)/include/ruby.h basicsocket.o: $(top_srcdir)/internal.h +basicsocket.o: $(top_srcdir)/internal/array.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/io.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: basicsocket.c basicsocket.o: constdefs.h basicsocket.o: rubysocket.h basicsocket.o: sockport.h constants.o: $(RUBY_EXTCONF_H) constants.o: $(arch_hdrdir)/ruby/config.h +constants.o: $(hdrdir)/ruby/assert.h +constants.o: $(hdrdir)/ruby/backward.h +constants.o: $(hdrdir)/ruby/backward/2/assume.h +constants.o: $(hdrdir)/ruby/backward/2/attributes.h +constants.o: $(hdrdir)/ruby/backward/2/bool.h +constants.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +constants.o: $(hdrdir)/ruby/backward/2/inttypes.h +constants.o: $(hdrdir)/ruby/backward/2/limits.h +constants.o: $(hdrdir)/ruby/backward/2/long_long.h +constants.o: $(hdrdir)/ruby/backward/2/stdalign.h +constants.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +constants.o: $(hdrdir)/ruby/internal/arithmetic.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/char.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/double.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/int.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/long.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/short.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +constants.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +constants.o: $(hdrdir)/ruby/internal/assume.h +constants.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +constants.o: $(hdrdir)/ruby/internal/attr/artificial.h +constants.o: $(hdrdir)/ruby/internal/attr/cold.h +constants.o: $(hdrdir)/ruby/internal/attr/const.h +constants.o: $(hdrdir)/ruby/internal/attr/constexpr.h +constants.o: $(hdrdir)/ruby/internal/attr/deprecated.h +constants.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +constants.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +constants.o: $(hdrdir)/ruby/internal/attr/error.h +constants.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +constants.o: $(hdrdir)/ruby/internal/attr/forceinline.h +constants.o: $(hdrdir)/ruby/internal/attr/format.h +constants.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +constants.o: $(hdrdir)/ruby/internal/attr/noalias.h +constants.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +constants.o: $(hdrdir)/ruby/internal/attr/restrict.h +constants.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +constants.o: $(hdrdir)/ruby/internal/attr/warning.h +constants.o: $(hdrdir)/ruby/internal/attr/weakref.h +constants.o: $(hdrdir)/ruby/internal/cast.h +constants.o: $(hdrdir)/ruby/internal/compiler_is.h +constants.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +constants.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +constants.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +constants.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +constants.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +constants.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +constants.o: $(hdrdir)/ruby/internal/compiler_since.h +constants.o: $(hdrdir)/ruby/internal/config.h +constants.o: $(hdrdir)/ruby/internal/constant_p.h +constants.o: $(hdrdir)/ruby/internal/core.h +constants.o: $(hdrdir)/ruby/internal/core/rarray.h +constants.o: $(hdrdir)/ruby/internal/core/rbasic.h +constants.o: $(hdrdir)/ruby/internal/core/rbignum.h +constants.o: $(hdrdir)/ruby/internal/core/rclass.h +constants.o: $(hdrdir)/ruby/internal/core/rdata.h +constants.o: $(hdrdir)/ruby/internal/core/rfile.h +constants.o: $(hdrdir)/ruby/internal/core/rhash.h +constants.o: $(hdrdir)/ruby/internal/core/robject.h +constants.o: $(hdrdir)/ruby/internal/core/rregexp.h +constants.o: $(hdrdir)/ruby/internal/core/rstring.h +constants.o: $(hdrdir)/ruby/internal/core/rstruct.h +constants.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +constants.o: $(hdrdir)/ruby/internal/ctype.h +constants.o: $(hdrdir)/ruby/internal/dllexport.h +constants.o: $(hdrdir)/ruby/internal/dosish.h +constants.o: $(hdrdir)/ruby/internal/encoding/coderange.h +constants.o: $(hdrdir)/ruby/internal/encoding/ctype.h +constants.o: $(hdrdir)/ruby/internal/encoding/encoding.h +constants.o: $(hdrdir)/ruby/internal/encoding/pathname.h +constants.o: $(hdrdir)/ruby/internal/encoding/re.h +constants.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +constants.o: $(hdrdir)/ruby/internal/encoding/string.h +constants.o: $(hdrdir)/ruby/internal/encoding/symbol.h +constants.o: $(hdrdir)/ruby/internal/encoding/transcode.h +constants.o: $(hdrdir)/ruby/internal/error.h +constants.o: $(hdrdir)/ruby/internal/eval.h +constants.o: $(hdrdir)/ruby/internal/event.h +constants.o: $(hdrdir)/ruby/internal/fl_type.h +constants.o: $(hdrdir)/ruby/internal/gc.h +constants.o: $(hdrdir)/ruby/internal/glob.h +constants.o: $(hdrdir)/ruby/internal/globals.h +constants.o: $(hdrdir)/ruby/internal/has/attribute.h +constants.o: $(hdrdir)/ruby/internal/has/builtin.h +constants.o: $(hdrdir)/ruby/internal/has/c_attribute.h +constants.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +constants.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +constants.o: $(hdrdir)/ruby/internal/has/extension.h +constants.o: $(hdrdir)/ruby/internal/has/feature.h +constants.o: $(hdrdir)/ruby/internal/has/warning.h +constants.o: $(hdrdir)/ruby/internal/intern/array.h +constants.o: $(hdrdir)/ruby/internal/intern/bignum.h +constants.o: $(hdrdir)/ruby/internal/intern/class.h +constants.o: $(hdrdir)/ruby/internal/intern/compar.h +constants.o: $(hdrdir)/ruby/internal/intern/complex.h +constants.o: $(hdrdir)/ruby/internal/intern/cont.h +constants.o: $(hdrdir)/ruby/internal/intern/dir.h +constants.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +constants.o: $(hdrdir)/ruby/internal/intern/marshal.h +constants.o: $(hdrdir)/ruby/internal/intern/numeric.h +constants.o: $(hdrdir)/ruby/internal/intern/object.h +constants.o: $(hdrdir)/ruby/internal/intern/parse.h +constants.o: $(hdrdir)/ruby/internal/intern/proc.h +constants.o: $(hdrdir)/ruby/internal/intern/process.h +constants.o: $(hdrdir)/ruby/internal/intern/random.h +constants.o: $(hdrdir)/ruby/internal/intern/range.h +constants.o: $(hdrdir)/ruby/internal/intern/rational.h +constants.o: $(hdrdir)/ruby/internal/intern/re.h +constants.o: $(hdrdir)/ruby/internal/intern/ruby.h +constants.o: $(hdrdir)/ruby/internal/intern/select.h +constants.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +constants.o: $(hdrdir)/ruby/internal/intern/signal.h +constants.o: $(hdrdir)/ruby/internal/intern/sprintf.h +constants.o: $(hdrdir)/ruby/internal/intern/string.h +constants.o: $(hdrdir)/ruby/internal/intern/struct.h +constants.o: $(hdrdir)/ruby/internal/intern/thread.h +constants.o: $(hdrdir)/ruby/internal/intern/time.h +constants.o: $(hdrdir)/ruby/internal/intern/variable.h +constants.o: $(hdrdir)/ruby/internal/intern/vm.h +constants.o: $(hdrdir)/ruby/internal/interpreter.h +constants.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +constants.o: $(hdrdir)/ruby/internal/value.h +constants.o: $(hdrdir)/ruby/internal/value_type.h +constants.o: $(hdrdir)/ruby/internal/variable.h +constants.o: $(hdrdir)/ruby/internal/warning_push.h +constants.o: $(hdrdir)/ruby/internal/xmalloc.h constants.o: $(hdrdir)/ruby/io.h constants.o: $(hdrdir)/ruby/missing.h +constants.o: $(hdrdir)/ruby/onigmo.h constants.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -constants.o: $(top_srcdir)/include/ruby.h constants.o: $(top_srcdir)/internal.h +constants.o: $(top_srcdir)/internal/array.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/io.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: constants.c constants.o: constdefs.c constants.o: constdefs.h @@ -66,228 +583,2280 @@ constants.o: rubysocket.h constants.o: sockport.h ifaddr.o: $(RUBY_EXTCONF_H) ifaddr.o: $(arch_hdrdir)/ruby/config.h +ifaddr.o: $(hdrdir)/ruby/assert.h +ifaddr.o: $(hdrdir)/ruby/backward.h +ifaddr.o: $(hdrdir)/ruby/backward/2/assume.h +ifaddr.o: $(hdrdir)/ruby/backward/2/attributes.h +ifaddr.o: $(hdrdir)/ruby/backward/2/bool.h +ifaddr.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +ifaddr.o: $(hdrdir)/ruby/backward/2/inttypes.h +ifaddr.o: $(hdrdir)/ruby/backward/2/limits.h +ifaddr.o: $(hdrdir)/ruby/backward/2/long_long.h +ifaddr.o: $(hdrdir)/ruby/backward/2/stdalign.h +ifaddr.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ifaddr.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ifaddr.o: $(hdrdir)/ruby/internal/assume.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/artificial.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/cold.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/const.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/error.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/format.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/noalias.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/restrict.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/warning.h +ifaddr.o: $(hdrdir)/ruby/internal/attr/weakref.h +ifaddr.o: $(hdrdir)/ruby/internal/cast.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ifaddr.o: $(hdrdir)/ruby/internal/compiler_since.h +ifaddr.o: $(hdrdir)/ruby/internal/config.h +ifaddr.o: $(hdrdir)/ruby/internal/constant_p.h +ifaddr.o: $(hdrdir)/ruby/internal/core.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rarray.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rbasic.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rbignum.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rclass.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rdata.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rfile.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rhash.h +ifaddr.o: $(hdrdir)/ruby/internal/core/robject.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rregexp.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rstring.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rstruct.h +ifaddr.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ifaddr.o: $(hdrdir)/ruby/internal/ctype.h +ifaddr.o: $(hdrdir)/ruby/internal/dllexport.h +ifaddr.o: $(hdrdir)/ruby/internal/dosish.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/re.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/string.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ifaddr.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ifaddr.o: $(hdrdir)/ruby/internal/error.h +ifaddr.o: $(hdrdir)/ruby/internal/eval.h +ifaddr.o: $(hdrdir)/ruby/internal/event.h +ifaddr.o: $(hdrdir)/ruby/internal/fl_type.h +ifaddr.o: $(hdrdir)/ruby/internal/gc.h +ifaddr.o: $(hdrdir)/ruby/internal/glob.h +ifaddr.o: $(hdrdir)/ruby/internal/globals.h +ifaddr.o: $(hdrdir)/ruby/internal/has/attribute.h +ifaddr.o: $(hdrdir)/ruby/internal/has/builtin.h +ifaddr.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ifaddr.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ifaddr.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ifaddr.o: $(hdrdir)/ruby/internal/has/extension.h +ifaddr.o: $(hdrdir)/ruby/internal/has/feature.h +ifaddr.o: $(hdrdir)/ruby/internal/has/warning.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/array.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/bignum.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/class.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/compar.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/complex.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/cont.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/dir.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +ifaddr.o: $(hdrdir)/ruby/internal/intern/marshal.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/numeric.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/object.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/parse.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/proc.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/process.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/random.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/range.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/rational.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/re.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/ruby.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/select.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/signal.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/string.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/struct.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/thread.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/time.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/variable.h +ifaddr.o: $(hdrdir)/ruby/internal/intern/vm.h +ifaddr.o: $(hdrdir)/ruby/internal/interpreter.h +ifaddr.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +ifaddr.o: $(hdrdir)/ruby/internal/value.h +ifaddr.o: $(hdrdir)/ruby/internal/value_type.h +ifaddr.o: $(hdrdir)/ruby/internal/variable.h +ifaddr.o: $(hdrdir)/ruby/internal/warning_push.h +ifaddr.o: $(hdrdir)/ruby/internal/xmalloc.h ifaddr.o: $(hdrdir)/ruby/io.h ifaddr.o: $(hdrdir)/ruby/missing.h +ifaddr.o: $(hdrdir)/ruby/onigmo.h ifaddr.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -ifaddr.o: $(top_srcdir)/include/ruby.h ifaddr.o: $(top_srcdir)/internal.h +ifaddr.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h ifaddr.o: ifaddr.c ifaddr.o: rubysocket.h ifaddr.o: sockport.h init.o: $(RUBY_EXTCONF_H) init.o: $(arch_hdrdir)/ruby/config.h +init.o: $(hdrdir)/ruby/assert.h +init.o: $(hdrdir)/ruby/backward.h +init.o: $(hdrdir)/ruby/backward/2/assume.h +init.o: $(hdrdir)/ruby/backward/2/attributes.h +init.o: $(hdrdir)/ruby/backward/2/bool.h +init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +init.o: $(hdrdir)/ruby/backward/2/inttypes.h +init.o: $(hdrdir)/ruby/backward/2/limits.h +init.o: $(hdrdir)/ruby/backward/2/long_long.h +init.o: $(hdrdir)/ruby/backward/2/stdalign.h +init.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +init.o: $(hdrdir)/ruby/internal/arithmetic.h +init.o: $(hdrdir)/ruby/internal/arithmetic/char.h +init.o: $(hdrdir)/ruby/internal/arithmetic/double.h +init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/int.h +init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/long.h +init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/short.h +init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +init.o: $(hdrdir)/ruby/internal/assume.h +init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +init.o: $(hdrdir)/ruby/internal/attr/artificial.h +init.o: $(hdrdir)/ruby/internal/attr/cold.h +init.o: $(hdrdir)/ruby/internal/attr/const.h +init.o: $(hdrdir)/ruby/internal/attr/constexpr.h +init.o: $(hdrdir)/ruby/internal/attr/deprecated.h +init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +init.o: $(hdrdir)/ruby/internal/attr/error.h +init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +init.o: $(hdrdir)/ruby/internal/attr/forceinline.h +init.o: $(hdrdir)/ruby/internal/attr/format.h +init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +init.o: $(hdrdir)/ruby/internal/attr/noalias.h +init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +init.o: $(hdrdir)/ruby/internal/attr/restrict.h +init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +init.o: $(hdrdir)/ruby/internal/attr/warning.h +init.o: $(hdrdir)/ruby/internal/attr/weakref.h +init.o: $(hdrdir)/ruby/internal/cast.h +init.o: $(hdrdir)/ruby/internal/compiler_is.h +init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +init.o: $(hdrdir)/ruby/internal/compiler_since.h +init.o: $(hdrdir)/ruby/internal/config.h +init.o: $(hdrdir)/ruby/internal/constant_p.h +init.o: $(hdrdir)/ruby/internal/core.h +init.o: $(hdrdir)/ruby/internal/core/rarray.h +init.o: $(hdrdir)/ruby/internal/core/rbasic.h +init.o: $(hdrdir)/ruby/internal/core/rbignum.h +init.o: $(hdrdir)/ruby/internal/core/rclass.h +init.o: $(hdrdir)/ruby/internal/core/rdata.h +init.o: $(hdrdir)/ruby/internal/core/rfile.h +init.o: $(hdrdir)/ruby/internal/core/rhash.h +init.o: $(hdrdir)/ruby/internal/core/robject.h +init.o: $(hdrdir)/ruby/internal/core/rregexp.h +init.o: $(hdrdir)/ruby/internal/core/rstring.h +init.o: $(hdrdir)/ruby/internal/core/rstruct.h +init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +init.o: $(hdrdir)/ruby/internal/ctype.h +init.o: $(hdrdir)/ruby/internal/dllexport.h +init.o: $(hdrdir)/ruby/internal/dosish.h +init.o: $(hdrdir)/ruby/internal/encoding/coderange.h +init.o: $(hdrdir)/ruby/internal/encoding/ctype.h +init.o: $(hdrdir)/ruby/internal/encoding/encoding.h +init.o: $(hdrdir)/ruby/internal/encoding/pathname.h +init.o: $(hdrdir)/ruby/internal/encoding/re.h +init.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +init.o: $(hdrdir)/ruby/internal/encoding/string.h +init.o: $(hdrdir)/ruby/internal/encoding/symbol.h +init.o: $(hdrdir)/ruby/internal/encoding/transcode.h +init.o: $(hdrdir)/ruby/internal/error.h +init.o: $(hdrdir)/ruby/internal/eval.h +init.o: $(hdrdir)/ruby/internal/event.h +init.o: $(hdrdir)/ruby/internal/fl_type.h +init.o: $(hdrdir)/ruby/internal/gc.h +init.o: $(hdrdir)/ruby/internal/glob.h +init.o: $(hdrdir)/ruby/internal/globals.h +init.o: $(hdrdir)/ruby/internal/has/attribute.h +init.o: $(hdrdir)/ruby/internal/has/builtin.h +init.o: $(hdrdir)/ruby/internal/has/c_attribute.h +init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +init.o: $(hdrdir)/ruby/internal/has/extension.h +init.o: $(hdrdir)/ruby/internal/has/feature.h +init.o: $(hdrdir)/ruby/internal/has/warning.h +init.o: $(hdrdir)/ruby/internal/intern/array.h +init.o: $(hdrdir)/ruby/internal/intern/bignum.h +init.o: $(hdrdir)/ruby/internal/intern/class.h +init.o: $(hdrdir)/ruby/internal/intern/compar.h +init.o: $(hdrdir)/ruby/internal/intern/complex.h +init.o: $(hdrdir)/ruby/internal/intern/cont.h +init.o: $(hdrdir)/ruby/internal/intern/dir.h +init.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +init.o: $(hdrdir)/ruby/internal/intern/marshal.h +init.o: $(hdrdir)/ruby/internal/intern/numeric.h +init.o: $(hdrdir)/ruby/internal/intern/object.h +init.o: $(hdrdir)/ruby/internal/intern/parse.h +init.o: $(hdrdir)/ruby/internal/intern/proc.h +init.o: $(hdrdir)/ruby/internal/intern/process.h +init.o: $(hdrdir)/ruby/internal/intern/random.h +init.o: $(hdrdir)/ruby/internal/intern/range.h +init.o: $(hdrdir)/ruby/internal/intern/rational.h +init.o: $(hdrdir)/ruby/internal/intern/re.h +init.o: $(hdrdir)/ruby/internal/intern/ruby.h +init.o: $(hdrdir)/ruby/internal/intern/select.h +init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +init.o: $(hdrdir)/ruby/internal/intern/signal.h +init.o: $(hdrdir)/ruby/internal/intern/sprintf.h +init.o: $(hdrdir)/ruby/internal/intern/string.h +init.o: $(hdrdir)/ruby/internal/intern/struct.h +init.o: $(hdrdir)/ruby/internal/intern/thread.h +init.o: $(hdrdir)/ruby/internal/intern/time.h +init.o: $(hdrdir)/ruby/internal/intern/variable.h +init.o: $(hdrdir)/ruby/internal/intern/vm.h +init.o: $(hdrdir)/ruby/internal/interpreter.h +init.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +init.o: $(hdrdir)/ruby/internal/value.h +init.o: $(hdrdir)/ruby/internal/value_type.h +init.o: $(hdrdir)/ruby/internal/variable.h +init.o: $(hdrdir)/ruby/internal/warning_push.h +init.o: $(hdrdir)/ruby/internal/xmalloc.h init.o: $(hdrdir)/ruby/io.h init.o: $(hdrdir)/ruby/missing.h +init.o: $(hdrdir)/ruby/onigmo.h init.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -init.o: $(top_srcdir)/include/ruby.h init.o: $(top_srcdir)/internal.h +init.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h init.o: init.c init.o: rubysocket.h init.o: sockport.h ipsocket.o: $(RUBY_EXTCONF_H) ipsocket.o: $(arch_hdrdir)/ruby/config.h +ipsocket.o: $(hdrdir)/ruby/assert.h +ipsocket.o: $(hdrdir)/ruby/backward.h +ipsocket.o: $(hdrdir)/ruby/backward/2/assume.h +ipsocket.o: $(hdrdir)/ruby/backward/2/attributes.h +ipsocket.o: $(hdrdir)/ruby/backward/2/bool.h +ipsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +ipsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h +ipsocket.o: $(hdrdir)/ruby/backward/2/limits.h +ipsocket.o: $(hdrdir)/ruby/backward/2/long_long.h +ipsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h +ipsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ipsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ipsocket.o: $(hdrdir)/ruby/internal/assume.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/cold.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/const.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/error.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/format.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/warning.h +ipsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h +ipsocket.o: $(hdrdir)/ruby/internal/cast.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ipsocket.o: $(hdrdir)/ruby/internal/compiler_since.h +ipsocket.o: $(hdrdir)/ruby/internal/config.h +ipsocket.o: $(hdrdir)/ruby/internal/constant_p.h +ipsocket.o: $(hdrdir)/ruby/internal/core.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rarray.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rclass.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rdata.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rfile.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rhash.h +ipsocket.o: $(hdrdir)/ruby/internal/core/robject.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rstring.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h +ipsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ipsocket.o: $(hdrdir)/ruby/internal/ctype.h +ipsocket.o: $(hdrdir)/ruby/internal/dllexport.h +ipsocket.o: $(hdrdir)/ruby/internal/dosish.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/re.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/string.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ipsocket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ipsocket.o: $(hdrdir)/ruby/internal/error.h +ipsocket.o: $(hdrdir)/ruby/internal/eval.h +ipsocket.o: $(hdrdir)/ruby/internal/event.h +ipsocket.o: $(hdrdir)/ruby/internal/fl_type.h +ipsocket.o: $(hdrdir)/ruby/internal/gc.h +ipsocket.o: $(hdrdir)/ruby/internal/glob.h +ipsocket.o: $(hdrdir)/ruby/internal/globals.h +ipsocket.o: $(hdrdir)/ruby/internal/has/attribute.h +ipsocket.o: $(hdrdir)/ruby/internal/has/builtin.h +ipsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ipsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ipsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ipsocket.o: $(hdrdir)/ruby/internal/has/extension.h +ipsocket.o: $(hdrdir)/ruby/internal/has/feature.h +ipsocket.o: $(hdrdir)/ruby/internal/has/warning.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/array.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/class.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/compar.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/complex.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/cont.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/dir.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +ipsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/object.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/parse.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/proc.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/process.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/random.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/range.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/rational.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/re.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/select.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/signal.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/string.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/struct.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/thread.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/time.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/variable.h +ipsocket.o: $(hdrdir)/ruby/internal/intern/vm.h +ipsocket.o: $(hdrdir)/ruby/internal/interpreter.h +ipsocket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +ipsocket.o: $(hdrdir)/ruby/internal/value.h +ipsocket.o: $(hdrdir)/ruby/internal/value_type.h +ipsocket.o: $(hdrdir)/ruby/internal/variable.h +ipsocket.o: $(hdrdir)/ruby/internal/warning_push.h +ipsocket.o: $(hdrdir)/ruby/internal/xmalloc.h ipsocket.o: $(hdrdir)/ruby/io.h ipsocket.o: $(hdrdir)/ruby/missing.h +ipsocket.o: $(hdrdir)/ruby/onigmo.h ipsocket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -ipsocket.o: $(top_srcdir)/include/ruby.h ipsocket.o: $(top_srcdir)/internal.h +ipsocket.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h ipsocket.o: ipsocket.c ipsocket.o: rubysocket.h ipsocket.o: sockport.h option.o: $(RUBY_EXTCONF_H) option.o: $(arch_hdrdir)/ruby/config.h +option.o: $(hdrdir)/ruby/assert.h +option.o: $(hdrdir)/ruby/backward.h +option.o: $(hdrdir)/ruby/backward/2/assume.h +option.o: $(hdrdir)/ruby/backward/2/attributes.h +option.o: $(hdrdir)/ruby/backward/2/bool.h +option.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +option.o: $(hdrdir)/ruby/backward/2/inttypes.h +option.o: $(hdrdir)/ruby/backward/2/limits.h +option.o: $(hdrdir)/ruby/backward/2/long_long.h +option.o: $(hdrdir)/ruby/backward/2/stdalign.h +option.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +option.o: $(hdrdir)/ruby/internal/arithmetic.h +option.o: $(hdrdir)/ruby/internal/arithmetic/char.h +option.o: $(hdrdir)/ruby/internal/arithmetic/double.h +option.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +option.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/int.h +option.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/long.h +option.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +option.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/short.h +option.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +option.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +option.o: $(hdrdir)/ruby/internal/assume.h +option.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +option.o: $(hdrdir)/ruby/internal/attr/artificial.h +option.o: $(hdrdir)/ruby/internal/attr/cold.h +option.o: $(hdrdir)/ruby/internal/attr/const.h +option.o: $(hdrdir)/ruby/internal/attr/constexpr.h +option.o: $(hdrdir)/ruby/internal/attr/deprecated.h +option.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +option.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +option.o: $(hdrdir)/ruby/internal/attr/error.h +option.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +option.o: $(hdrdir)/ruby/internal/attr/forceinline.h +option.o: $(hdrdir)/ruby/internal/attr/format.h +option.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +option.o: $(hdrdir)/ruby/internal/attr/noalias.h +option.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +option.o: $(hdrdir)/ruby/internal/attr/restrict.h +option.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +option.o: $(hdrdir)/ruby/internal/attr/warning.h +option.o: $(hdrdir)/ruby/internal/attr/weakref.h +option.o: $(hdrdir)/ruby/internal/cast.h +option.o: $(hdrdir)/ruby/internal/compiler_is.h +option.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +option.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +option.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +option.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +option.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +option.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +option.o: $(hdrdir)/ruby/internal/compiler_since.h +option.o: $(hdrdir)/ruby/internal/config.h +option.o: $(hdrdir)/ruby/internal/constant_p.h +option.o: $(hdrdir)/ruby/internal/core.h +option.o: $(hdrdir)/ruby/internal/core/rarray.h +option.o: $(hdrdir)/ruby/internal/core/rbasic.h +option.o: $(hdrdir)/ruby/internal/core/rbignum.h +option.o: $(hdrdir)/ruby/internal/core/rclass.h +option.o: $(hdrdir)/ruby/internal/core/rdata.h +option.o: $(hdrdir)/ruby/internal/core/rfile.h +option.o: $(hdrdir)/ruby/internal/core/rhash.h +option.o: $(hdrdir)/ruby/internal/core/robject.h +option.o: $(hdrdir)/ruby/internal/core/rregexp.h +option.o: $(hdrdir)/ruby/internal/core/rstring.h +option.o: $(hdrdir)/ruby/internal/core/rstruct.h +option.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +option.o: $(hdrdir)/ruby/internal/ctype.h +option.o: $(hdrdir)/ruby/internal/dllexport.h +option.o: $(hdrdir)/ruby/internal/dosish.h +option.o: $(hdrdir)/ruby/internal/encoding/coderange.h +option.o: $(hdrdir)/ruby/internal/encoding/ctype.h +option.o: $(hdrdir)/ruby/internal/encoding/encoding.h +option.o: $(hdrdir)/ruby/internal/encoding/pathname.h +option.o: $(hdrdir)/ruby/internal/encoding/re.h +option.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +option.o: $(hdrdir)/ruby/internal/encoding/string.h +option.o: $(hdrdir)/ruby/internal/encoding/symbol.h +option.o: $(hdrdir)/ruby/internal/encoding/transcode.h +option.o: $(hdrdir)/ruby/internal/error.h +option.o: $(hdrdir)/ruby/internal/eval.h +option.o: $(hdrdir)/ruby/internal/event.h +option.o: $(hdrdir)/ruby/internal/fl_type.h +option.o: $(hdrdir)/ruby/internal/gc.h +option.o: $(hdrdir)/ruby/internal/glob.h +option.o: $(hdrdir)/ruby/internal/globals.h +option.o: $(hdrdir)/ruby/internal/has/attribute.h +option.o: $(hdrdir)/ruby/internal/has/builtin.h +option.o: $(hdrdir)/ruby/internal/has/c_attribute.h +option.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +option.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +option.o: $(hdrdir)/ruby/internal/has/extension.h +option.o: $(hdrdir)/ruby/internal/has/feature.h +option.o: $(hdrdir)/ruby/internal/has/warning.h +option.o: $(hdrdir)/ruby/internal/intern/array.h +option.o: $(hdrdir)/ruby/internal/intern/bignum.h +option.o: $(hdrdir)/ruby/internal/intern/class.h +option.o: $(hdrdir)/ruby/internal/intern/compar.h +option.o: $(hdrdir)/ruby/internal/intern/complex.h +option.o: $(hdrdir)/ruby/internal/intern/cont.h +option.o: $(hdrdir)/ruby/internal/intern/dir.h +option.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +option.o: $(hdrdir)/ruby/internal/intern/marshal.h +option.o: $(hdrdir)/ruby/internal/intern/numeric.h +option.o: $(hdrdir)/ruby/internal/intern/object.h +option.o: $(hdrdir)/ruby/internal/intern/parse.h +option.o: $(hdrdir)/ruby/internal/intern/proc.h +option.o: $(hdrdir)/ruby/internal/intern/process.h +option.o: $(hdrdir)/ruby/internal/intern/random.h +option.o: $(hdrdir)/ruby/internal/intern/range.h +option.o: $(hdrdir)/ruby/internal/intern/rational.h +option.o: $(hdrdir)/ruby/internal/intern/re.h +option.o: $(hdrdir)/ruby/internal/intern/ruby.h +option.o: $(hdrdir)/ruby/internal/intern/select.h +option.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +option.o: $(hdrdir)/ruby/internal/intern/signal.h +option.o: $(hdrdir)/ruby/internal/intern/sprintf.h +option.o: $(hdrdir)/ruby/internal/intern/string.h +option.o: $(hdrdir)/ruby/internal/intern/struct.h +option.o: $(hdrdir)/ruby/internal/intern/thread.h +option.o: $(hdrdir)/ruby/internal/intern/time.h +option.o: $(hdrdir)/ruby/internal/intern/variable.h +option.o: $(hdrdir)/ruby/internal/intern/vm.h +option.o: $(hdrdir)/ruby/internal/interpreter.h +option.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +option.o: $(hdrdir)/ruby/internal/value.h +option.o: $(hdrdir)/ruby/internal/value_type.h +option.o: $(hdrdir)/ruby/internal/variable.h +option.o: $(hdrdir)/ruby/internal/warning_push.h +option.o: $(hdrdir)/ruby/internal/xmalloc.h option.o: $(hdrdir)/ruby/io.h option.o: $(hdrdir)/ruby/missing.h +option.o: $(hdrdir)/ruby/onigmo.h option.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -option.o: $(top_srcdir)/include/ruby.h option.o: $(top_srcdir)/internal.h +option.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h option.o: option.c option.o: rubysocket.h option.o: sockport.h raddrinfo.o: $(RUBY_EXTCONF_H) raddrinfo.o: $(arch_hdrdir)/ruby/config.h +raddrinfo.o: $(hdrdir)/ruby/assert.h +raddrinfo.o: $(hdrdir)/ruby/backward.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/assume.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/attributes.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/bool.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/inttypes.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/limits.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/long_long.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/stdalign.h +raddrinfo.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/char.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/double.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/int.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/long.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/short.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +raddrinfo.o: $(hdrdir)/ruby/internal/assume.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/artificial.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/cold.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/const.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/constexpr.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/deprecated.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/error.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/forceinline.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/format.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/noalias.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/restrict.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/warning.h +raddrinfo.o: $(hdrdir)/ruby/internal/attr/weakref.h +raddrinfo.o: $(hdrdir)/ruby/internal/cast.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +raddrinfo.o: $(hdrdir)/ruby/internal/compiler_since.h +raddrinfo.o: $(hdrdir)/ruby/internal/config.h +raddrinfo.o: $(hdrdir)/ruby/internal/constant_p.h +raddrinfo.o: $(hdrdir)/ruby/internal/core.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rarray.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rbasic.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rbignum.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rclass.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rdata.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rfile.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rhash.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/robject.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rregexp.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rstring.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rstruct.h +raddrinfo.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +raddrinfo.o: $(hdrdir)/ruby/internal/ctype.h +raddrinfo.o: $(hdrdir)/ruby/internal/dllexport.h +raddrinfo.o: $(hdrdir)/ruby/internal/dosish.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/coderange.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/ctype.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/encoding.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/pathname.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/re.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/string.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/symbol.h +raddrinfo.o: $(hdrdir)/ruby/internal/encoding/transcode.h +raddrinfo.o: $(hdrdir)/ruby/internal/error.h +raddrinfo.o: $(hdrdir)/ruby/internal/eval.h +raddrinfo.o: $(hdrdir)/ruby/internal/event.h +raddrinfo.o: $(hdrdir)/ruby/internal/fl_type.h +raddrinfo.o: $(hdrdir)/ruby/internal/gc.h +raddrinfo.o: $(hdrdir)/ruby/internal/glob.h +raddrinfo.o: $(hdrdir)/ruby/internal/globals.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/attribute.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/builtin.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/c_attribute.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/extension.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/feature.h +raddrinfo.o: $(hdrdir)/ruby/internal/has/warning.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/array.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/bignum.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/class.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/compar.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/complex.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/cont.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/dir.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +raddrinfo.o: $(hdrdir)/ruby/internal/intern/marshal.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/numeric.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/object.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/parse.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/proc.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/process.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/random.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/range.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/rational.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/re.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/ruby.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/select.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/signal.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/sprintf.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/string.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/struct.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/thread.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/time.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/variable.h +raddrinfo.o: $(hdrdir)/ruby/internal/intern/vm.h +raddrinfo.o: $(hdrdir)/ruby/internal/interpreter.h +raddrinfo.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +raddrinfo.o: $(hdrdir)/ruby/internal/value.h +raddrinfo.o: $(hdrdir)/ruby/internal/value_type.h +raddrinfo.o: $(hdrdir)/ruby/internal/variable.h +raddrinfo.o: $(hdrdir)/ruby/internal/warning_push.h +raddrinfo.o: $(hdrdir)/ruby/internal/xmalloc.h raddrinfo.o: $(hdrdir)/ruby/io.h raddrinfo.o: $(hdrdir)/ruby/missing.h +raddrinfo.o: $(hdrdir)/ruby/onigmo.h raddrinfo.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -raddrinfo.o: $(top_srcdir)/include/ruby.h raddrinfo.o: $(top_srcdir)/internal.h +raddrinfo.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h raddrinfo.o: raddrinfo.c raddrinfo.o: rubysocket.h raddrinfo.o: sockport.h socket.o: $(RUBY_EXTCONF_H) socket.o: $(arch_hdrdir)/ruby/config.h +socket.o: $(hdrdir)/ruby/assert.h +socket.o: $(hdrdir)/ruby/backward.h +socket.o: $(hdrdir)/ruby/backward/2/assume.h +socket.o: $(hdrdir)/ruby/backward/2/attributes.h +socket.o: $(hdrdir)/ruby/backward/2/bool.h +socket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +socket.o: $(hdrdir)/ruby/backward/2/inttypes.h +socket.o: $(hdrdir)/ruby/backward/2/limits.h +socket.o: $(hdrdir)/ruby/backward/2/long_long.h +socket.o: $(hdrdir)/ruby/backward/2/stdalign.h +socket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +socket.o: $(hdrdir)/ruby/internal/arithmetic.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +socket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +socket.o: $(hdrdir)/ruby/internal/assume.h +socket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +socket.o: $(hdrdir)/ruby/internal/attr/artificial.h +socket.o: $(hdrdir)/ruby/internal/attr/cold.h +socket.o: $(hdrdir)/ruby/internal/attr/const.h +socket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +socket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +socket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +socket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +socket.o: $(hdrdir)/ruby/internal/attr/error.h +socket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +socket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +socket.o: $(hdrdir)/ruby/internal/attr/format.h +socket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +socket.o: $(hdrdir)/ruby/internal/attr/noalias.h +socket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +socket.o: $(hdrdir)/ruby/internal/attr/restrict.h +socket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +socket.o: $(hdrdir)/ruby/internal/attr/warning.h +socket.o: $(hdrdir)/ruby/internal/attr/weakref.h +socket.o: $(hdrdir)/ruby/internal/cast.h +socket.o: $(hdrdir)/ruby/internal/compiler_is.h +socket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +socket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +socket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +socket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +socket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +socket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +socket.o: $(hdrdir)/ruby/internal/compiler_since.h +socket.o: $(hdrdir)/ruby/internal/config.h +socket.o: $(hdrdir)/ruby/internal/constant_p.h +socket.o: $(hdrdir)/ruby/internal/core.h +socket.o: $(hdrdir)/ruby/internal/core/rarray.h +socket.o: $(hdrdir)/ruby/internal/core/rbasic.h +socket.o: $(hdrdir)/ruby/internal/core/rbignum.h +socket.o: $(hdrdir)/ruby/internal/core/rclass.h +socket.o: $(hdrdir)/ruby/internal/core/rdata.h +socket.o: $(hdrdir)/ruby/internal/core/rfile.h +socket.o: $(hdrdir)/ruby/internal/core/rhash.h +socket.o: $(hdrdir)/ruby/internal/core/robject.h +socket.o: $(hdrdir)/ruby/internal/core/rregexp.h +socket.o: $(hdrdir)/ruby/internal/core/rstring.h +socket.o: $(hdrdir)/ruby/internal/core/rstruct.h +socket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +socket.o: $(hdrdir)/ruby/internal/ctype.h +socket.o: $(hdrdir)/ruby/internal/dllexport.h +socket.o: $(hdrdir)/ruby/internal/dosish.h +socket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +socket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +socket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +socket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +socket.o: $(hdrdir)/ruby/internal/encoding/re.h +socket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +socket.o: $(hdrdir)/ruby/internal/encoding/string.h +socket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +socket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +socket.o: $(hdrdir)/ruby/internal/error.h +socket.o: $(hdrdir)/ruby/internal/eval.h +socket.o: $(hdrdir)/ruby/internal/event.h +socket.o: $(hdrdir)/ruby/internal/fl_type.h +socket.o: $(hdrdir)/ruby/internal/gc.h +socket.o: $(hdrdir)/ruby/internal/glob.h +socket.o: $(hdrdir)/ruby/internal/globals.h +socket.o: $(hdrdir)/ruby/internal/has/attribute.h +socket.o: $(hdrdir)/ruby/internal/has/builtin.h +socket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +socket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +socket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +socket.o: $(hdrdir)/ruby/internal/has/extension.h +socket.o: $(hdrdir)/ruby/internal/has/feature.h +socket.o: $(hdrdir)/ruby/internal/has/warning.h +socket.o: $(hdrdir)/ruby/internal/intern/array.h +socket.o: $(hdrdir)/ruby/internal/intern/bignum.h +socket.o: $(hdrdir)/ruby/internal/intern/class.h +socket.o: $(hdrdir)/ruby/internal/intern/compar.h +socket.o: $(hdrdir)/ruby/internal/intern/complex.h +socket.o: $(hdrdir)/ruby/internal/intern/cont.h +socket.o: $(hdrdir)/ruby/internal/intern/dir.h +socket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +socket.o: $(hdrdir)/ruby/internal/intern/marshal.h +socket.o: $(hdrdir)/ruby/internal/intern/numeric.h +socket.o: $(hdrdir)/ruby/internal/intern/object.h +socket.o: $(hdrdir)/ruby/internal/intern/parse.h +socket.o: $(hdrdir)/ruby/internal/intern/proc.h +socket.o: $(hdrdir)/ruby/internal/intern/process.h +socket.o: $(hdrdir)/ruby/internal/intern/random.h +socket.o: $(hdrdir)/ruby/internal/intern/range.h +socket.o: $(hdrdir)/ruby/internal/intern/rational.h +socket.o: $(hdrdir)/ruby/internal/intern/re.h +socket.o: $(hdrdir)/ruby/internal/intern/ruby.h +socket.o: $(hdrdir)/ruby/internal/intern/select.h +socket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +socket.o: $(hdrdir)/ruby/internal/intern/signal.h +socket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +socket.o: $(hdrdir)/ruby/internal/intern/string.h +socket.o: $(hdrdir)/ruby/internal/intern/struct.h +socket.o: $(hdrdir)/ruby/internal/intern/thread.h +socket.o: $(hdrdir)/ruby/internal/intern/time.h +socket.o: $(hdrdir)/ruby/internal/intern/variable.h +socket.o: $(hdrdir)/ruby/internal/intern/vm.h +socket.o: $(hdrdir)/ruby/internal/interpreter.h +socket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +socket.o: $(hdrdir)/ruby/internal/value.h +socket.o: $(hdrdir)/ruby/internal/value_type.h +socket.o: $(hdrdir)/ruby/internal/variable.h +socket.o: $(hdrdir)/ruby/internal/warning_push.h +socket.o: $(hdrdir)/ruby/internal/xmalloc.h socket.o: $(hdrdir)/ruby/io.h socket.o: $(hdrdir)/ruby/missing.h +socket.o: $(hdrdir)/ruby/onigmo.h socket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -socket.o: $(top_srcdir)/include/ruby.h socket.o: $(top_srcdir)/internal.h +socket.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h socket.o: rubysocket.h socket.o: socket.c socket.o: sockport.h sockssocket.o: $(RUBY_EXTCONF_H) sockssocket.o: $(arch_hdrdir)/ruby/config.h +sockssocket.o: $(hdrdir)/ruby/assert.h +sockssocket.o: $(hdrdir)/ruby/backward.h +sockssocket.o: $(hdrdir)/ruby/backward/2/assume.h +sockssocket.o: $(hdrdir)/ruby/backward/2/attributes.h +sockssocket.o: $(hdrdir)/ruby/backward/2/bool.h +sockssocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +sockssocket.o: $(hdrdir)/ruby/backward/2/inttypes.h +sockssocket.o: $(hdrdir)/ruby/backward/2/limits.h +sockssocket.o: $(hdrdir)/ruby/backward/2/long_long.h +sockssocket.o: $(hdrdir)/ruby/backward/2/stdalign.h +sockssocket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +sockssocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +sockssocket.o: $(hdrdir)/ruby/internal/assume.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/artificial.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/cold.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/const.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/error.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/format.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/noalias.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/restrict.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/warning.h +sockssocket.o: $(hdrdir)/ruby/internal/attr/weakref.h +sockssocket.o: $(hdrdir)/ruby/internal/cast.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +sockssocket.o: $(hdrdir)/ruby/internal/compiler_since.h +sockssocket.o: $(hdrdir)/ruby/internal/config.h +sockssocket.o: $(hdrdir)/ruby/internal/constant_p.h +sockssocket.o: $(hdrdir)/ruby/internal/core.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rarray.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rbasic.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rbignum.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rclass.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rdata.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rfile.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rhash.h +sockssocket.o: $(hdrdir)/ruby/internal/core/robject.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rregexp.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rstring.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rstruct.h +sockssocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +sockssocket.o: $(hdrdir)/ruby/internal/ctype.h +sockssocket.o: $(hdrdir)/ruby/internal/dllexport.h +sockssocket.o: $(hdrdir)/ruby/internal/dosish.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/re.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/string.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +sockssocket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +sockssocket.o: $(hdrdir)/ruby/internal/error.h +sockssocket.o: $(hdrdir)/ruby/internal/eval.h +sockssocket.o: $(hdrdir)/ruby/internal/event.h +sockssocket.o: $(hdrdir)/ruby/internal/fl_type.h +sockssocket.o: $(hdrdir)/ruby/internal/gc.h +sockssocket.o: $(hdrdir)/ruby/internal/glob.h +sockssocket.o: $(hdrdir)/ruby/internal/globals.h +sockssocket.o: $(hdrdir)/ruby/internal/has/attribute.h +sockssocket.o: $(hdrdir)/ruby/internal/has/builtin.h +sockssocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +sockssocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +sockssocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +sockssocket.o: $(hdrdir)/ruby/internal/has/extension.h +sockssocket.o: $(hdrdir)/ruby/internal/has/feature.h +sockssocket.o: $(hdrdir)/ruby/internal/has/warning.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/array.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/bignum.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/class.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/compar.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/complex.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/cont.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/dir.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +sockssocket.o: $(hdrdir)/ruby/internal/intern/marshal.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/numeric.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/object.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/parse.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/proc.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/process.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/random.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/range.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/rational.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/re.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/ruby.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/select.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/signal.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/string.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/struct.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/thread.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/time.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/variable.h +sockssocket.o: $(hdrdir)/ruby/internal/intern/vm.h +sockssocket.o: $(hdrdir)/ruby/internal/interpreter.h +sockssocket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +sockssocket.o: $(hdrdir)/ruby/internal/value.h +sockssocket.o: $(hdrdir)/ruby/internal/value_type.h +sockssocket.o: $(hdrdir)/ruby/internal/variable.h +sockssocket.o: $(hdrdir)/ruby/internal/warning_push.h +sockssocket.o: $(hdrdir)/ruby/internal/xmalloc.h sockssocket.o: $(hdrdir)/ruby/io.h sockssocket.o: $(hdrdir)/ruby/missing.h +sockssocket.o: $(hdrdir)/ruby/onigmo.h sockssocket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -sockssocket.o: $(top_srcdir)/include/ruby.h sockssocket.o: $(top_srcdir)/internal.h +sockssocket.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h sockssocket.o: rubysocket.h sockssocket.o: sockport.h sockssocket.o: sockssocket.c tcpserver.o: $(RUBY_EXTCONF_H) tcpserver.o: $(arch_hdrdir)/ruby/config.h +tcpserver.o: $(hdrdir)/ruby/assert.h +tcpserver.o: $(hdrdir)/ruby/backward.h +tcpserver.o: $(hdrdir)/ruby/backward/2/assume.h +tcpserver.o: $(hdrdir)/ruby/backward/2/attributes.h +tcpserver.o: $(hdrdir)/ruby/backward/2/bool.h +tcpserver.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +tcpserver.o: $(hdrdir)/ruby/backward/2/inttypes.h +tcpserver.o: $(hdrdir)/ruby/backward/2/limits.h +tcpserver.o: $(hdrdir)/ruby/backward/2/long_long.h +tcpserver.o: $(hdrdir)/ruby/backward/2/stdalign.h +tcpserver.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/double.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/int.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/long.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/short.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +tcpserver.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +tcpserver.o: $(hdrdir)/ruby/internal/assume.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/artificial.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/cold.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/const.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/constexpr.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/deprecated.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/error.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/forceinline.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/format.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/noalias.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/restrict.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/warning.h +tcpserver.o: $(hdrdir)/ruby/internal/attr/weakref.h +tcpserver.o: $(hdrdir)/ruby/internal/cast.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +tcpserver.o: $(hdrdir)/ruby/internal/compiler_since.h +tcpserver.o: $(hdrdir)/ruby/internal/config.h +tcpserver.o: $(hdrdir)/ruby/internal/constant_p.h +tcpserver.o: $(hdrdir)/ruby/internal/core.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rarray.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rbasic.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rbignum.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rclass.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rdata.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rfile.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rhash.h +tcpserver.o: $(hdrdir)/ruby/internal/core/robject.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rregexp.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rstring.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rstruct.h +tcpserver.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +tcpserver.o: $(hdrdir)/ruby/internal/ctype.h +tcpserver.o: $(hdrdir)/ruby/internal/dllexport.h +tcpserver.o: $(hdrdir)/ruby/internal/dosish.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/coderange.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/ctype.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/encoding.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/pathname.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/re.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/string.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/symbol.h +tcpserver.o: $(hdrdir)/ruby/internal/encoding/transcode.h +tcpserver.o: $(hdrdir)/ruby/internal/error.h +tcpserver.o: $(hdrdir)/ruby/internal/eval.h +tcpserver.o: $(hdrdir)/ruby/internal/event.h +tcpserver.o: $(hdrdir)/ruby/internal/fl_type.h +tcpserver.o: $(hdrdir)/ruby/internal/gc.h +tcpserver.o: $(hdrdir)/ruby/internal/glob.h +tcpserver.o: $(hdrdir)/ruby/internal/globals.h +tcpserver.o: $(hdrdir)/ruby/internal/has/attribute.h +tcpserver.o: $(hdrdir)/ruby/internal/has/builtin.h +tcpserver.o: $(hdrdir)/ruby/internal/has/c_attribute.h +tcpserver.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +tcpserver.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +tcpserver.o: $(hdrdir)/ruby/internal/has/extension.h +tcpserver.o: $(hdrdir)/ruby/internal/has/feature.h +tcpserver.o: $(hdrdir)/ruby/internal/has/warning.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/array.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/bignum.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/class.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/compar.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/complex.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/cont.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/dir.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +tcpserver.o: $(hdrdir)/ruby/internal/intern/marshal.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/numeric.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/object.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/parse.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/proc.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/process.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/random.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/range.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/rational.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/re.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/ruby.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/select.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/signal.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/sprintf.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/string.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/struct.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/thread.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/time.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/variable.h +tcpserver.o: $(hdrdir)/ruby/internal/intern/vm.h +tcpserver.o: $(hdrdir)/ruby/internal/interpreter.h +tcpserver.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +tcpserver.o: $(hdrdir)/ruby/internal/value.h +tcpserver.o: $(hdrdir)/ruby/internal/value_type.h +tcpserver.o: $(hdrdir)/ruby/internal/variable.h +tcpserver.o: $(hdrdir)/ruby/internal/warning_push.h +tcpserver.o: $(hdrdir)/ruby/internal/xmalloc.h tcpserver.o: $(hdrdir)/ruby/io.h tcpserver.o: $(hdrdir)/ruby/missing.h +tcpserver.o: $(hdrdir)/ruby/onigmo.h tcpserver.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -tcpserver.o: $(top_srcdir)/include/ruby.h tcpserver.o: $(top_srcdir)/internal.h +tcpserver.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h tcpserver.o: rubysocket.h tcpserver.o: sockport.h tcpserver.o: tcpserver.c tcpsocket.o: $(RUBY_EXTCONF_H) tcpsocket.o: $(arch_hdrdir)/ruby/config.h +tcpsocket.o: $(hdrdir)/ruby/assert.h +tcpsocket.o: $(hdrdir)/ruby/backward.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/assume.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/bool.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/limits.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/long_long.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h +tcpsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +tcpsocket.o: $(hdrdir)/ruby/internal/assume.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/cold.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/const.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/error.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/format.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/warning.h +tcpsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h +tcpsocket.o: $(hdrdir)/ruby/internal/cast.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +tcpsocket.o: $(hdrdir)/ruby/internal/compiler_since.h +tcpsocket.o: $(hdrdir)/ruby/internal/config.h +tcpsocket.o: $(hdrdir)/ruby/internal/constant_p.h +tcpsocket.o: $(hdrdir)/ruby/internal/core.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rarray.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rclass.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rdata.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rfile.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rhash.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/robject.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rstring.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h +tcpsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +tcpsocket.o: $(hdrdir)/ruby/internal/ctype.h +tcpsocket.o: $(hdrdir)/ruby/internal/dllexport.h +tcpsocket.o: $(hdrdir)/ruby/internal/dosish.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/re.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/string.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +tcpsocket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +tcpsocket.o: $(hdrdir)/ruby/internal/error.h +tcpsocket.o: $(hdrdir)/ruby/internal/eval.h +tcpsocket.o: $(hdrdir)/ruby/internal/event.h +tcpsocket.o: $(hdrdir)/ruby/internal/fl_type.h +tcpsocket.o: $(hdrdir)/ruby/internal/gc.h +tcpsocket.o: $(hdrdir)/ruby/internal/glob.h +tcpsocket.o: $(hdrdir)/ruby/internal/globals.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/attribute.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/builtin.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/extension.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/feature.h +tcpsocket.o: $(hdrdir)/ruby/internal/has/warning.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/array.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/class.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/compar.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/complex.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/cont.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/dir.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +tcpsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/object.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/parse.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/proc.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/process.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/random.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/range.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/rational.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/re.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/select.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/signal.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/string.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/struct.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/thread.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/time.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/variable.h +tcpsocket.o: $(hdrdir)/ruby/internal/intern/vm.h +tcpsocket.o: $(hdrdir)/ruby/internal/interpreter.h +tcpsocket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +tcpsocket.o: $(hdrdir)/ruby/internal/value.h +tcpsocket.o: $(hdrdir)/ruby/internal/value_type.h +tcpsocket.o: $(hdrdir)/ruby/internal/variable.h +tcpsocket.o: $(hdrdir)/ruby/internal/warning_push.h +tcpsocket.o: $(hdrdir)/ruby/internal/xmalloc.h tcpsocket.o: $(hdrdir)/ruby/io.h tcpsocket.o: $(hdrdir)/ruby/missing.h +tcpsocket.o: $(hdrdir)/ruby/onigmo.h tcpsocket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -tcpsocket.o: $(top_srcdir)/include/ruby.h tcpsocket.o: $(top_srcdir)/internal.h +tcpsocket.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h tcpsocket.o: rubysocket.h tcpsocket.o: sockport.h tcpsocket.o: tcpsocket.c udpsocket.o: $(RUBY_EXTCONF_H) udpsocket.o: $(arch_hdrdir)/ruby/config.h +udpsocket.o: $(hdrdir)/ruby/assert.h +udpsocket.o: $(hdrdir)/ruby/backward.h +udpsocket.o: $(hdrdir)/ruby/backward/2/assume.h +udpsocket.o: $(hdrdir)/ruby/backward/2/attributes.h +udpsocket.o: $(hdrdir)/ruby/backward/2/bool.h +udpsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +udpsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h +udpsocket.o: $(hdrdir)/ruby/backward/2/limits.h +udpsocket.o: $(hdrdir)/ruby/backward/2/long_long.h +udpsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h +udpsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +udpsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +udpsocket.o: $(hdrdir)/ruby/internal/assume.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/cold.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/const.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/error.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/format.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/warning.h +udpsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h +udpsocket.o: $(hdrdir)/ruby/internal/cast.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +udpsocket.o: $(hdrdir)/ruby/internal/compiler_since.h +udpsocket.o: $(hdrdir)/ruby/internal/config.h +udpsocket.o: $(hdrdir)/ruby/internal/constant_p.h +udpsocket.o: $(hdrdir)/ruby/internal/core.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rarray.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rclass.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rdata.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rfile.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rhash.h +udpsocket.o: $(hdrdir)/ruby/internal/core/robject.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rstring.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h +udpsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +udpsocket.o: $(hdrdir)/ruby/internal/ctype.h +udpsocket.o: $(hdrdir)/ruby/internal/dllexport.h +udpsocket.o: $(hdrdir)/ruby/internal/dosish.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/re.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/string.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +udpsocket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +udpsocket.o: $(hdrdir)/ruby/internal/error.h +udpsocket.o: $(hdrdir)/ruby/internal/eval.h +udpsocket.o: $(hdrdir)/ruby/internal/event.h +udpsocket.o: $(hdrdir)/ruby/internal/fl_type.h +udpsocket.o: $(hdrdir)/ruby/internal/gc.h +udpsocket.o: $(hdrdir)/ruby/internal/glob.h +udpsocket.o: $(hdrdir)/ruby/internal/globals.h +udpsocket.o: $(hdrdir)/ruby/internal/has/attribute.h +udpsocket.o: $(hdrdir)/ruby/internal/has/builtin.h +udpsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +udpsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +udpsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +udpsocket.o: $(hdrdir)/ruby/internal/has/extension.h +udpsocket.o: $(hdrdir)/ruby/internal/has/feature.h +udpsocket.o: $(hdrdir)/ruby/internal/has/warning.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/array.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/class.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/compar.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/complex.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/cont.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/dir.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +udpsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/object.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/parse.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/proc.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/process.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/random.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/range.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/rational.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/re.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/select.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/signal.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/string.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/struct.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/thread.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/time.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/variable.h +udpsocket.o: $(hdrdir)/ruby/internal/intern/vm.h +udpsocket.o: $(hdrdir)/ruby/internal/interpreter.h +udpsocket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +udpsocket.o: $(hdrdir)/ruby/internal/value.h +udpsocket.o: $(hdrdir)/ruby/internal/value_type.h +udpsocket.o: $(hdrdir)/ruby/internal/variable.h +udpsocket.o: $(hdrdir)/ruby/internal/warning_push.h +udpsocket.o: $(hdrdir)/ruby/internal/xmalloc.h udpsocket.o: $(hdrdir)/ruby/io.h udpsocket.o: $(hdrdir)/ruby/missing.h +udpsocket.o: $(hdrdir)/ruby/onigmo.h udpsocket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -udpsocket.o: $(top_srcdir)/include/ruby.h udpsocket.o: $(top_srcdir)/internal.h +udpsocket.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h udpsocket.o: rubysocket.h udpsocket.o: sockport.h udpsocket.o: udpsocket.c unixserver.o: $(RUBY_EXTCONF_H) unixserver.o: $(arch_hdrdir)/ruby/config.h +unixserver.o: $(hdrdir)/ruby/assert.h +unixserver.o: $(hdrdir)/ruby/backward.h +unixserver.o: $(hdrdir)/ruby/backward/2/assume.h +unixserver.o: $(hdrdir)/ruby/backward/2/attributes.h +unixserver.o: $(hdrdir)/ruby/backward/2/bool.h +unixserver.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +unixserver.o: $(hdrdir)/ruby/backward/2/inttypes.h +unixserver.o: $(hdrdir)/ruby/backward/2/limits.h +unixserver.o: $(hdrdir)/ruby/backward/2/long_long.h +unixserver.o: $(hdrdir)/ruby/backward/2/stdalign.h +unixserver.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/char.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/double.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/int.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/long.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/short.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +unixserver.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +unixserver.o: $(hdrdir)/ruby/internal/assume.h +unixserver.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +unixserver.o: $(hdrdir)/ruby/internal/attr/artificial.h +unixserver.o: $(hdrdir)/ruby/internal/attr/cold.h +unixserver.o: $(hdrdir)/ruby/internal/attr/const.h +unixserver.o: $(hdrdir)/ruby/internal/attr/constexpr.h +unixserver.o: $(hdrdir)/ruby/internal/attr/deprecated.h +unixserver.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +unixserver.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +unixserver.o: $(hdrdir)/ruby/internal/attr/error.h +unixserver.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +unixserver.o: $(hdrdir)/ruby/internal/attr/forceinline.h +unixserver.o: $(hdrdir)/ruby/internal/attr/format.h +unixserver.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +unixserver.o: $(hdrdir)/ruby/internal/attr/noalias.h +unixserver.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +unixserver.o: $(hdrdir)/ruby/internal/attr/restrict.h +unixserver.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +unixserver.o: $(hdrdir)/ruby/internal/attr/warning.h +unixserver.o: $(hdrdir)/ruby/internal/attr/weakref.h +unixserver.o: $(hdrdir)/ruby/internal/cast.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +unixserver.o: $(hdrdir)/ruby/internal/compiler_since.h +unixserver.o: $(hdrdir)/ruby/internal/config.h +unixserver.o: $(hdrdir)/ruby/internal/constant_p.h +unixserver.o: $(hdrdir)/ruby/internal/core.h +unixserver.o: $(hdrdir)/ruby/internal/core/rarray.h +unixserver.o: $(hdrdir)/ruby/internal/core/rbasic.h +unixserver.o: $(hdrdir)/ruby/internal/core/rbignum.h +unixserver.o: $(hdrdir)/ruby/internal/core/rclass.h +unixserver.o: $(hdrdir)/ruby/internal/core/rdata.h +unixserver.o: $(hdrdir)/ruby/internal/core/rfile.h +unixserver.o: $(hdrdir)/ruby/internal/core/rhash.h +unixserver.o: $(hdrdir)/ruby/internal/core/robject.h +unixserver.o: $(hdrdir)/ruby/internal/core/rregexp.h +unixserver.o: $(hdrdir)/ruby/internal/core/rstring.h +unixserver.o: $(hdrdir)/ruby/internal/core/rstruct.h +unixserver.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +unixserver.o: $(hdrdir)/ruby/internal/ctype.h +unixserver.o: $(hdrdir)/ruby/internal/dllexport.h +unixserver.o: $(hdrdir)/ruby/internal/dosish.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/coderange.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/ctype.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/encoding.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/pathname.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/re.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/string.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/symbol.h +unixserver.o: $(hdrdir)/ruby/internal/encoding/transcode.h +unixserver.o: $(hdrdir)/ruby/internal/error.h +unixserver.o: $(hdrdir)/ruby/internal/eval.h +unixserver.o: $(hdrdir)/ruby/internal/event.h +unixserver.o: $(hdrdir)/ruby/internal/fl_type.h +unixserver.o: $(hdrdir)/ruby/internal/gc.h +unixserver.o: $(hdrdir)/ruby/internal/glob.h +unixserver.o: $(hdrdir)/ruby/internal/globals.h +unixserver.o: $(hdrdir)/ruby/internal/has/attribute.h +unixserver.o: $(hdrdir)/ruby/internal/has/builtin.h +unixserver.o: $(hdrdir)/ruby/internal/has/c_attribute.h +unixserver.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +unixserver.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +unixserver.o: $(hdrdir)/ruby/internal/has/extension.h +unixserver.o: $(hdrdir)/ruby/internal/has/feature.h +unixserver.o: $(hdrdir)/ruby/internal/has/warning.h +unixserver.o: $(hdrdir)/ruby/internal/intern/array.h +unixserver.o: $(hdrdir)/ruby/internal/intern/bignum.h +unixserver.o: $(hdrdir)/ruby/internal/intern/class.h +unixserver.o: $(hdrdir)/ruby/internal/intern/compar.h +unixserver.o: $(hdrdir)/ruby/internal/intern/complex.h +unixserver.o: $(hdrdir)/ruby/internal/intern/cont.h +unixserver.o: $(hdrdir)/ruby/internal/intern/dir.h +unixserver.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +unixserver.o: $(hdrdir)/ruby/internal/intern/marshal.h +unixserver.o: $(hdrdir)/ruby/internal/intern/numeric.h +unixserver.o: $(hdrdir)/ruby/internal/intern/object.h +unixserver.o: $(hdrdir)/ruby/internal/intern/parse.h +unixserver.o: $(hdrdir)/ruby/internal/intern/proc.h +unixserver.o: $(hdrdir)/ruby/internal/intern/process.h +unixserver.o: $(hdrdir)/ruby/internal/intern/random.h +unixserver.o: $(hdrdir)/ruby/internal/intern/range.h +unixserver.o: $(hdrdir)/ruby/internal/intern/rational.h +unixserver.o: $(hdrdir)/ruby/internal/intern/re.h +unixserver.o: $(hdrdir)/ruby/internal/intern/ruby.h +unixserver.o: $(hdrdir)/ruby/internal/intern/select.h +unixserver.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +unixserver.o: $(hdrdir)/ruby/internal/intern/signal.h +unixserver.o: $(hdrdir)/ruby/internal/intern/sprintf.h +unixserver.o: $(hdrdir)/ruby/internal/intern/string.h +unixserver.o: $(hdrdir)/ruby/internal/intern/struct.h +unixserver.o: $(hdrdir)/ruby/internal/intern/thread.h +unixserver.o: $(hdrdir)/ruby/internal/intern/time.h +unixserver.o: $(hdrdir)/ruby/internal/intern/variable.h +unixserver.o: $(hdrdir)/ruby/internal/intern/vm.h +unixserver.o: $(hdrdir)/ruby/internal/interpreter.h +unixserver.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +unixserver.o: $(hdrdir)/ruby/internal/value.h +unixserver.o: $(hdrdir)/ruby/internal/value_type.h +unixserver.o: $(hdrdir)/ruby/internal/variable.h +unixserver.o: $(hdrdir)/ruby/internal/warning_push.h +unixserver.o: $(hdrdir)/ruby/internal/xmalloc.h unixserver.o: $(hdrdir)/ruby/io.h unixserver.o: $(hdrdir)/ruby/missing.h +unixserver.o: $(hdrdir)/ruby/onigmo.h unixserver.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -unixserver.o: $(top_srcdir)/include/ruby.h unixserver.o: $(top_srcdir)/internal.h +unixserver.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h unixserver.o: rubysocket.h unixserver.o: sockport.h unixserver.o: unixserver.c unixsocket.o: $(RUBY_EXTCONF_H) unixsocket.o: $(arch_hdrdir)/ruby/config.h +unixsocket.o: $(hdrdir)/ruby/assert.h +unixsocket.o: $(hdrdir)/ruby/backward.h +unixsocket.o: $(hdrdir)/ruby/backward/2/assume.h +unixsocket.o: $(hdrdir)/ruby/backward/2/attributes.h +unixsocket.o: $(hdrdir)/ruby/backward/2/bool.h +unixsocket.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +unixsocket.o: $(hdrdir)/ruby/backward/2/inttypes.h +unixsocket.o: $(hdrdir)/ruby/backward/2/limits.h +unixsocket.o: $(hdrdir)/ruby/backward/2/long_long.h +unixsocket.o: $(hdrdir)/ruby/backward/2/stdalign.h +unixsocket.o: $(hdrdir)/ruby/backward/2/stdarg.h 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/anyargs.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/char.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/double.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/int.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/long.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/short.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +unixsocket.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +unixsocket.o: $(hdrdir)/ruby/internal/assume.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/artificial.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/cold.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/const.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/constexpr.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/deprecated.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/error.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/forceinline.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/format.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/noalias.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +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/pure.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/restrict.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/warning.h +unixsocket.o: $(hdrdir)/ruby/internal/attr/weakref.h +unixsocket.o: $(hdrdir)/ruby/internal/cast.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +unixsocket.o: $(hdrdir)/ruby/internal/compiler_since.h +unixsocket.o: $(hdrdir)/ruby/internal/config.h +unixsocket.o: $(hdrdir)/ruby/internal/constant_p.h +unixsocket.o: $(hdrdir)/ruby/internal/core.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rarray.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rbasic.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rbignum.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rclass.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rdata.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rfile.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rhash.h +unixsocket.o: $(hdrdir)/ruby/internal/core/robject.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rregexp.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rstring.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rstruct.h +unixsocket.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +unixsocket.o: $(hdrdir)/ruby/internal/ctype.h +unixsocket.o: $(hdrdir)/ruby/internal/dllexport.h +unixsocket.o: $(hdrdir)/ruby/internal/dosish.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/coderange.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/ctype.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/encoding.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/pathname.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/re.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/string.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/symbol.h +unixsocket.o: $(hdrdir)/ruby/internal/encoding/transcode.h +unixsocket.o: $(hdrdir)/ruby/internal/error.h +unixsocket.o: $(hdrdir)/ruby/internal/eval.h +unixsocket.o: $(hdrdir)/ruby/internal/event.h +unixsocket.o: $(hdrdir)/ruby/internal/fl_type.h +unixsocket.o: $(hdrdir)/ruby/internal/gc.h +unixsocket.o: $(hdrdir)/ruby/internal/glob.h +unixsocket.o: $(hdrdir)/ruby/internal/globals.h +unixsocket.o: $(hdrdir)/ruby/internal/has/attribute.h +unixsocket.o: $(hdrdir)/ruby/internal/has/builtin.h +unixsocket.o: $(hdrdir)/ruby/internal/has/c_attribute.h +unixsocket.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +unixsocket.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +unixsocket.o: $(hdrdir)/ruby/internal/has/extension.h +unixsocket.o: $(hdrdir)/ruby/internal/has/feature.h +unixsocket.o: $(hdrdir)/ruby/internal/has/warning.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/array.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/bignum.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/class.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/compar.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/complex.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/cont.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/dir.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/enum.h +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 +unixsocket.o: $(hdrdir)/ruby/internal/intern/marshal.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/numeric.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/object.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/parse.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/proc.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/process.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/random.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/range.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/rational.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/re.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/ruby.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/select.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/signal.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/sprintf.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/string.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/struct.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/thread.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/time.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/variable.h +unixsocket.o: $(hdrdir)/ruby/internal/intern/vm.h +unixsocket.o: $(hdrdir)/ruby/internal/interpreter.h +unixsocket.o: $(hdrdir)/ruby/internal/iterator.h +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/symbol.h +unixsocket.o: $(hdrdir)/ruby/internal/value.h +unixsocket.o: $(hdrdir)/ruby/internal/value_type.h +unixsocket.o: $(hdrdir)/ruby/internal/variable.h +unixsocket.o: $(hdrdir)/ruby/internal/warning_push.h +unixsocket.o: $(hdrdir)/ruby/internal/xmalloc.h unixsocket.o: $(hdrdir)/ruby/io.h unixsocket.o: $(hdrdir)/ruby/missing.h +unixsocket.o: $(hdrdir)/ruby/onigmo.h unixsocket.o: $(hdrdir)/ruby/oniguruma.h 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/util.h -unixsocket.o: $(top_srcdir)/include/ruby.h unixsocket.o: $(top_srcdir)/internal.h +unixsocket.o: $(top_srcdir)/internal/array.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/io.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: constdefs.h unixsocket.o: rubysocket.h unixsocket.o: sockport.h diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 6d15bbac6e..b70a862414 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: false require 'mkmf' AF_INET6_SOCKET_CREATION_TEST = <<EOF @@ -432,18 +433,13 @@ end case RUBY_PLATFORM when /mswin(32|64)|mingw/ test_func = "WSACleanup" + have_library("iphlpapi") have_library("ws2_32", "WSACleanup", headers) when /cygwin/ test_func = "socket(0,0,0)" -when /beos/ - test_func = "socket(0,0,0)" - have_library("net", "socket(0,0,0)", headers) when /haiku/ test_func = "socket(0,0,0)" have_library("network", "socket(0,0,0)", headers) -when /i386-os2_emx/ - test_func = "socket(0,0,0)" - have_library("socket", "socket(0,0,0)", headers) else test_func = "socket(0,0,0)" have_library("nsl", 't_open("", 0, (struct t_info *)NULL)', headers) # SunOS @@ -481,12 +477,16 @@ EOF have_func('inet_aton("", (struct in_addr *)0)', headers) have_func('getservbyport(0, "")', headers) have_func("getifaddrs((struct ifaddrs **)NULL)", headers) + have_struct_member("struct if_data", "ifi_vhid", headers) # FreeBSD have_func("getpeereid", headers) 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); @@ -495,10 +495,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) @@ -510,7 +510,7 @@ EOF end ipv6 = false - default_ipv6 = /beos|haiku/ !~ RUBY_PLATFORM + default_ipv6 = /haiku/ !~ RUBY_PLATFORM if enable_config("ipv6", default_ipv6) if checking_for("ipv6") {try_link(AF_INET6_SOCKET_CREATION_TEST)} $defs << "-DENABLE_IPV6" << "-DINET6" @@ -567,29 +567,16 @@ EOS case enable_config("wide-getaddrinfo") when true getaddr_info_ok = :wide - when nil + when nil, false + getaddr_info_ok = (:wide if getaddr_info_ok.nil?) if have_func("getnameinfo", headers) and have_func("getaddrinfo", headers) - getaddr_info_ok = :os - if !CROSS_COMPILING && - !checking_for("system getaddrinfo working") { + if CROSS_COMPILING || + $mingw || $mswin || + checking_for("system getaddrinfo working") { try_run(cpp_include(headers) + GETADDRINFO_GETNAMEINFO_TEST) } - getaddr_info_ok = :wide + getaddr_info_ok = :os end - else - getaddr_info_ok = :wide - end - when false - if have_func("getnameinfo", headers) and have_func("getaddrinfo", headers) - getaddr_info_ok = :os - if !CROSS_COMPILING && - !checking_for("system getaddrinfo working") { - try_run(cpp_include(headers) + GETADDRINFO_GETNAMEINFO_TEST) - } - getaddr_info_ok = nil - end - else - getaddr_info_ok = nil end else raise "unexpected enable_config() value" @@ -662,7 +649,7 @@ EOS if enable_config("socks", ENV["SOCKS_SERVER"]) if have_library("socks5", "SOCKSinit") $defs << "-DSOCKS5" << "-DSOCKS" - elsif have_library("socks", "Rconnect") + elsif have_library("socksd", "Rconnect") || have_library("socks", "Rconnect") $defs << "-DSOCKS" end end @@ -672,7 +659,7 @@ EOS #include <netinet/in.h> int t(struct in6_addr *addr) {return IN6_IS_ADDR_UNSPECIFIED(addr);} SRC - print "fixing apple's netinet6/in6.rb ..."; $stdout.flush + print "fixing apple's netinet6/in6.h ..."; $stdout.flush in6 = File.read("/usr/include/#{hdr}") if in6.gsub!(/\*\(const\s+__uint32_t\s+\*\)\(const\s+void\s+\*\)\(&(\(\w+\))->s6_addr\[(\d+)\]\)/) do i, r = $2.to_i.divmod(4) diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c index 68f610e807..ce6dc40478 100644 --- a/ext/socket/getaddrinfo.c +++ b/ext/socket/getaddrinfo.c @@ -45,11 +45,7 @@ #include <sys/types.h> #ifndef _WIN32 #include <sys/param.h> -#if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE) -# include <net/socket.h> -#else -# include <sys/socket.h> -#endif +#include <sys/socket.h> #include <netinet/in.h> #if defined(HAVE_ARPA_INET_H) #include <arpa/inet.h> @@ -66,6 +62,9 @@ #endif #include <unistd.h> #else +#if defined(_MSC_VER) && _MSC_VER <= 1200 +#include <windows.h> +#endif #include <winsock2.h> #include <ws2tcpip.h> #include <io.h> @@ -150,6 +149,7 @@ static int get_addr __P((const char *, int, struct addrinfo **, 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 */ @@ -167,6 +167,7 @@ static const char *const ai_errlist[] = { "resolved protocol is unknown.", /* EAI_PROTOCOL */ "unknown error.", /* EAI_MAX */ }; +#endif #define GET_CANONNAME(ai, str) \ if (pai->ai_flags & AI_CANONNAME) {\ @@ -436,11 +437,8 @@ getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *h s = socket(afd->a_af, SOCK_DGRAM, 0); if (s < 0) continue; -#if defined(__BEOS__) - closesocket(s); -#else + close(s); -#endif if (pai->ai_flags & AI_PASSIVE) { GET_AI(cur->ai_next, afd, afd->a_addrany, port); diff --git a/ext/socket/getnameinfo.c b/ext/socket/getnameinfo.c index c238c8e501..94a5eb9439 100644 --- a/ext/socket/getnameinfo.c +++ b/ext/socket/getnameinfo.c @@ -41,11 +41,7 @@ #include <stdio.h> #include <sys/types.h> #ifndef _WIN32 -#if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE) -# include <net/socket.h> -#else -# include <sys/socket.h> -#endif +#include <sys/socket.h> #include <netinet/in.h> #if defined(HAVE_ARPA_INET_H) #include <arpa/inet.h> @@ -59,6 +55,9 @@ #endif #endif #ifdef _WIN32 +#if defined(_MSC_VER) && _MSC_VER <= 1200 +#include <windows.h> +#endif #include <winsock2.h> #include <ws2tcpip.h> #define snprintf _snprintf @@ -77,6 +76,7 @@ typedef int socklen_t; #include "addrinfo.h" #include "sockport.h" +#include "rubysocket.h" #define SUCCESS 0 #define ANY 0 diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c index 15395d7088..1da259bd6f 100644 --- a/ext/socket/ifaddr.c +++ b/ext/socket/ifaddr.c @@ -24,7 +24,6 @@ typedef struct rb_ifaddr_root_tag rb_ifaddr_root_t; struct rb_ifaddr_tag { int ord; struct ifaddrs *ifaddr; - rb_ifaddr_root_t *root; }; struct rb_ifaddr_root_tag { @@ -41,11 +40,6 @@ get_root(const rb_ifaddr_t *ifaddr) } static void -ifaddr_mark(void *ptr) -{ -} - -static void ifaddr_free(void *ptr) { rb_ifaddr_t *ifaddr = ptr; @@ -60,18 +54,17 @@ ifaddr_free(void *ptr) static size_t ifaddr_memsize(const void *ptr) { + size_t size = offsetof(rb_ifaddr_root_t, ary); const rb_ifaddr_t *ifaddr; - const rb_ifaddr_root_t *root; - if (ptr == NULL) - return 0; ifaddr = ptr; - root = get_root(ifaddr); - return sizeof(rb_ifaddr_root_t) + (root->numifaddrs - 1) * sizeof(rb_ifaddr_t); + if (ifaddr->ord == 0) size = sizeof(rb_ifaddr_root_t); + size += sizeof(struct ifaddrs); + return size; } static const rb_data_type_t ifaddr_type = { "socket/ifaddr", - {ifaddr_mark, ifaddr_free, ifaddr_memsize,}, + {0, ifaddr_free, ifaddr_memsize,}, }; static inline rb_ifaddr_t * @@ -91,6 +84,12 @@ get_ifaddr(VALUE self) return rifaddr; } +static struct ifaddrs * +get_ifaddrs(VALUE self) +{ + return get_ifaddr(self)->ifaddr; +} + static VALUE rsock_getifaddrs(void) { @@ -98,7 +97,7 @@ rsock_getifaddrs(void) int numifaddrs, i; struct ifaddrs *ifaddrs, *ifa; rb_ifaddr_root_t *root; - VALUE result; + VALUE result, addr; ret = getifaddrs(&ifaddrs); if (ret == -1) @@ -112,20 +111,26 @@ rsock_getifaddrs(void) for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) numifaddrs++; - root = xmalloc(sizeof(rb_ifaddr_root_t) + (numifaddrs-1) * sizeof(rb_ifaddr_t)); - root->refcount = root->numifaddrs = numifaddrs; + addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, 0); + root = xmalloc(offsetof(rb_ifaddr_root_t, ary) + numifaddrs * sizeof(rb_ifaddr_t)); + root->refcount = 0; + root->numifaddrs = numifaddrs; ifa = ifaddrs; for (i = 0; i < numifaddrs; i++) { root->ary[i].ord = i; root->ary[i].ifaddr = ifa; - root->ary[i].root = root; ifa = ifa->ifa_next; } + RTYPEDDATA_DATA(addr) = &root->ary[0]; + root->refcount++; result = rb_ary_new2(numifaddrs); - for (i = 0; i < numifaddrs; i++) { - rb_ary_push(result, TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i])); + 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); } return result; @@ -141,8 +146,7 @@ rsock_getifaddrs(void) static VALUE ifaddr_name(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); return rb_str_new_cstr(ifa->ifa_name); } @@ -157,8 +161,7 @@ ifaddr_name(VALUE self) static VALUE ifaddr_ifindex(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); unsigned int ifindex = if_nametoindex(ifa->ifa_name); if (ifindex == 0) { rb_raise(rb_eArgError, "invalid interface name: %s", ifa->ifa_name); @@ -179,8 +182,7 @@ ifaddr_ifindex(VALUE self) static VALUE ifaddr_flags(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); return IFAFLAGS2NUM(ifa->ifa_flags); } @@ -195,8 +197,7 @@ ifaddr_flags(VALUE self) static VALUE ifaddr_addr(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); if (ifa->ifa_addr) return rsock_sockaddr_obj(ifa->ifa_addr, rsock_sockaddr_len(ifa->ifa_addr)); return Qnil; @@ -213,8 +214,7 @@ ifaddr_addr(VALUE self) static VALUE ifaddr_netmask(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); if (ifa->ifa_netmask) return rsock_sockaddr_obj(ifa->ifa_netmask, rsock_sockaddr_len(ifa->ifa_netmask)); return Qnil; @@ -231,8 +231,7 @@ ifaddr_netmask(VALUE self) static VALUE ifaddr_broadaddr(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); if ((ifa->ifa_flags & IFF_BROADCAST) && ifa->ifa_broadaddr) return rsock_sockaddr_obj(ifa->ifa_broadaddr, rsock_sockaddr_len(ifa->ifa_broadaddr)); return Qnil; @@ -249,13 +248,32 @@ ifaddr_broadaddr(VALUE self) static VALUE ifaddr_dstaddr(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa = rifaddr->ifaddr; + struct ifaddrs *ifa = get_ifaddrs(self); if ((ifa->ifa_flags & IFF_POINTOPOINT) && ifa->ifa_dstaddr) return rsock_sockaddr_obj(ifa->ifa_dstaddr, rsock_sockaddr_len(ifa->ifa_dstaddr)); return Qnil; } +#ifdef HAVE_STRUCT_IF_DATA_IFI_VHID +/* + * call-seq: + * ifaddr.vhid => Integer + * + * Returns the vhid address of _ifaddr_. + * nil is returned if there is no vhid. + */ + +static VALUE +ifaddr_vhid(VALUE self) +{ + struct ifaddrs *ifa = get_ifaddrs(self); + if (ifa->ifa_data) + return (INT2FIX(((struct if_data*)ifa->ifa_data)->ifi_vhid)); + else + return Qnil; +} +#endif + static void ifaddr_inspect_flags(ifa_flags_t flags, VALUE result) { @@ -338,12 +356,9 @@ ifaddr_inspect_flags(ifa_flags_t flags, VALUE result) static VALUE ifaddr_inspect(VALUE self) { - rb_ifaddr_t *rifaddr = get_ifaddr(self); - struct ifaddrs *ifa; + struct ifaddrs *ifa = get_ifaddrs(self); VALUE result; - ifa = rifaddr->ifaddr; - result = rb_str_new_cstr("#<"); rb_str_append(result, rb_class_name(CLASS_OF(self))); @@ -444,7 +459,8 @@ rsock_init_sockifaddr(void) * * Socket::Ifaddr represents a result of getifaddrs() function. */ - rb_cSockIfaddr = rb_define_class_under(rb_cSocket, "Ifaddr", rb_cData); + rb_cSockIfaddr = rb_define_class_under(rb_cSocket, "Ifaddr", rb_cObject); + rb_undef_alloc_func(rb_cSockIfaddr); rb_define_method(rb_cSockIfaddr, "inspect", ifaddr_inspect, 0); rb_define_method(rb_cSockIfaddr, "name", ifaddr_name, 0); rb_define_method(rb_cSockIfaddr, "ifindex", ifaddr_ifindex, 0); @@ -453,6 +469,9 @@ rsock_init_sockifaddr(void) rb_define_method(rb_cSockIfaddr, "netmask", ifaddr_netmask, 0); rb_define_method(rb_cSockIfaddr, "broadaddr", ifaddr_broadaddr, 0); rb_define_method(rb_cSockIfaddr, "dstaddr", ifaddr_dstaddr, 0); +#ifdef HAVE_STRUCT_IF_DATA_IFI_VHID + rb_define_method(rb_cSockIfaddr, "vhid", ifaddr_vhid, 0); +#endif #endif rb_define_singleton_method(rb_cSocket, "getifaddrs", socket_s_getifaddrs, 0); diff --git a/ext/socket/init.c b/ext/socket/init.c index 4d7cf29ea3..359696e626 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -10,6 +10,10 @@ #include "rubysocket.h" +#ifdef _WIN32 +VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc); +#endif + VALUE rb_cBasicSocket; VALUE rb_cIPSocket; VALUE rb_cTCPSocket; @@ -29,28 +33,31 @@ VALUE rb_cSOCKSSocket; #endif int rsock_do_not_reverse_lookup = 1; +static VALUE sym_wait_readable; void rsock_raise_socket_error(const char *reason, int error) { #ifdef EAI_SYSTEM - if (error == EAI_SYSTEM) rb_sys_fail(reason); + int e; + if (error == EAI_SYSTEM && (e = errno) != 0) + 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)); +#endif } -#ifdef _WIN32 -#define is_socket(fd) rb_w32_is_socket(fd) +#if defined __APPLE__ +# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE) #else -static int -is_socket(int fd) -{ - struct stat sbuf; - - if (fstat(fd, &sbuf) < 0) - rb_sys_fail("fstat(2)"); - return S_ISSOCK(sbuf.st_mode); -} +# define do_write_retry(code) ret = code #endif VALUE @@ -58,11 +65,6 @@ rsock_init_sock(VALUE sock, int fd) { rb_io_t *fp; - if (!is_socket(fd) || rb_reserved_fd_p(fd)) { - errno = EBADF; - rb_sys_fail("not a socket file descriptor"); - } - rb_update_max_fd(fd); MakeOpenFile(sock, fp); fp->fd = fd; @@ -81,8 +83,10 @@ rsock_sendto_blocking(void *data) { struct rsock_send_arg *arg = data; VALUE mesg = arg->mesg; - return (VALUE)sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags, arg->to, arg->tolen); + ssize_t ret; + do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), + arg->flags, arg->to, arg->tolen)); + return (VALUE)ret; } VALUE @@ -90,13 +94,16 @@ rsock_send_blocking(void *data) { struct rsock_send_arg *arg = data; VALUE mesg = arg->mesg; - return (VALUE)send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), - arg->flags); + ssize_t ret; + do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg), + arg->flags)); + return (VALUE)ret; } struct recvfrom_arg { int fd, flags; VALUE str; + size_t length; socklen_t alen; union_sockaddr buf; }; @@ -107,56 +114,87 @@ recvfrom_blocking(void *data) struct recvfrom_arg *arg = data; socklen_t len0 = arg->alen; ssize_t ret; - ret = recvfrom(arg->fd, RSTRING_PTR(arg->str), RSTRING_LEN(arg->str), + 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; + return (VALUE)ret; } +static VALUE +rsock_strbuf(VALUE str, long buflen) +{ + long len; + + if (NIL_P(str)) return rb_str_new(0, buflen); + + StringValue(str); + len = RSTRING_LEN(str); + if (len >= buflen) { + rb_str_modify(str); + } else { + rb_str_modify_expand(str, buflen - len); + } + return str; +} + +static VALUE +recvfrom_locktmp(VALUE v) +{ + struct recvfrom_arg *arg = (struct recvfrom_arg *)v; + + return rb_thread_io_blocking_region(recvfrom_blocking, arg, arg->fd); +} + VALUE -rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from) +rsock_s_recvfrom(VALUE socket, int argc, VALUE *argv, enum sock_recv_type from) { rb_io_t *fptr; - VALUE str, klass; + VALUE str; struct recvfrom_arg arg; VALUE len, flg; long buflen; long slen; - rb_scan_args(argc, argv, "11", &len, &flg); + rb_scan_args(argc, argv, "12", &len, &flg, &str); + + if (flg == Qnil) + arg.flags = 0; + else + arg.flags = NUM2INT(flg); - if (flg == Qnil) arg.flags = 0; - else arg.flags = NUM2INT(flg); buflen = NUM2INT(len); + str = rsock_strbuf(str, buflen); + + RB_IO_POINTER(socket, fptr); - GetOpenFile(sock, fptr); if (rb_io_read_pending(fptr)) { - rb_raise(rb_eIOError, "recv for buffered IO"); + rb_raise(rb_eIOError, "recv for buffered IO"); } + arg.fd = fptr->fd; arg.alen = (socklen_t)sizeof(arg.buf); + arg.str = str; + arg.length = buflen; + + while (true) { + rb_io_check_closed(fptr); - arg.str = str = rb_tainted_str_new(0, buflen); - klass = RBASIC(str)->klass; - rb_obj_hide(str); +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); +#endif + + slen = (long)rb_str_locktmp_ensure(str, recvfrom_locktmp, (VALUE)&arg); + + if (slen >= 0) break; - while (rb_io_check_closed(fptr), - rsock_maybe_wait_fd(arg.fd), - (slen = BLOCKING_REGION_FD(recvfrom_blocking, &arg)) < 0) { - if (!rb_io_wait_readable(fptr->fd)) { + if (!rb_io_maybe_wait_readable(errno, socket, Qnil)) rb_sys_fail("recvfrom(2)"); - } - if (RBASIC(str)->klass || RSTRING_LEN(str) != buflen) { - rb_raise(rb_eRuntimeError, "buffer string modified"); - } } - rb_obj_reveal(str, klass); - if (slen < RSTRING_LEN(str)) { - rb_str_set_len(str, slen); - } - rb_obj_taint(str); + /* Resize the string to the amount of data received */ + rb_str_set_len(str, slen); switch (from) { case RECV_RECV: return str; @@ -176,31 +214,28 @@ rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from) 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(sock, &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"); } } VALUE -rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from) +rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, + VALUE ex, enum sock_recv_type from) { rb_io_t *fptr; - VALUE str; union_sockaddr buf; socklen_t alen = (socklen_t)sizeof buf; - VALUE len, flg; long buflen; long slen; int fd, flags; VALUE addr = Qnil; socklen_t len0; - rb_scan_args(argc, argv, "11", &len, &flg); - - if (flg == Qnil) flags = 0; - else flags = NUM2INT(flg); + flags = NUM2INT(flg); buflen = NUM2INT(len); + str = rsock_strbuf(str, buflen); #ifdef MSG_DONTWAIT /* MSG_DONTWAIT avoids the race condition between fcntl and recvfrom. @@ -214,29 +249,32 @@ rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type } fd = fptr->fd; - str = rb_tainted_str_new(0, buflen); - rb_io_check_closed(fptr); - rb_io_set_nonblock(fptr); + + if (!MSG_DONTWAIT_RELIABLE) + 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) { - switch (errno) { + int e = errno; + switch (e) { case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: #endif - rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvfrom(2) would block"); + if (ex == Qfalse) + return sym_wait_readable; + rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "recvfrom(2) would block"); } - rb_sys_fail("recvfrom(2)"); + rb_syserr_fail(e, "recvfrom(2)"); } - if (slen < RSTRING_LEN(str)) { + if (slen != RSTRING_LEN(str)) { rb_str_set_len(str, slen); } - rb_obj_taint(str); switch (from) { case RECV_RECV: return str; @@ -256,78 +294,137 @@ rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type return rb_assoc_new(str, addr); } -/* returns true if SOCK_CLOEXEC is supported */ -int rsock_detect_cloexec(int fd) +#if MSG_DONTWAIT_RELIABLE +static VALUE sym_wait_writable; + +/* copied from io.c :< */ +static long +read_buffered_data(char *ptr, long len, rb_io_t *fptr) { -#ifdef SOCK_CLOEXEC - int flags = fcntl(fd, F_GETFD); + int n = fptr->rbuf.len; + + if (n <= 0) return 0; + if (n > len) n = (int)len; + MEMMOVE(ptr, fptr->rbuf.ptr+fptr->rbuf.off, char, n); + fptr->rbuf.off += n; + fptr->rbuf.len -= n; + return n; +} - if (flags == -1) - rb_bug("rsock_detect_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno)); +/* :nodoc: */ +VALUE +rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex) +{ + rb_io_t *fptr; + long n; + long len = NUM2LONG(length); + VALUE str = rsock_strbuf(buf, len); + char *ptr; - if (flags & FD_CLOEXEC) - return 1; -#endif - return 0; + GetOpenFile(sock, fptr); + + if (len == 0) { + 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); + } + } + if (n != RSTRING_LEN(str)) { + rb_str_modify(str); + rb_str_set_len(str, n); + } + if (n == 0) { + if (ex == Qfalse) return Qnil; + rb_eof_error(); + } + + return str; } -#ifdef SOCK_CLOEXEC -static int -rsock_socket0(int domain, int type, int proto) +/* :nodoc: */ +VALUE +rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex) { - int ret; - static int cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */ - - if (cloexec_state > 0) { /* common path, if SOCK_CLOEXEC is defined */ - ret = socket(domain, type|SOCK_CLOEXEC, proto); - if (ret >= 0) { - if (ret <= 2) - goto fix_cloexec; - goto update_max_fd; - } - } - else if (cloexec_state < 0) { /* usually runs once only for detection */ - ret = socket(domain, type|SOCK_CLOEXEC, proto); - if (ret >= 0) { - cloexec_state = rsock_detect_cloexec(ret); - if (cloexec_state == 0 || ret <= 2) - goto fix_cloexec; - goto update_max_fd; - } - else if (ret == -1 && errno == EINVAL) { - /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */ - ret = socket(domain, type, proto); - if (ret != -1) { - cloexec_state = 0; - /* fall through to fix_cloexec */ - } - } + rb_io_t *fptr; + long n; + + if (!RB_TYPE_P(str, T_STRING)) + str = rb_obj_as_string(str); + + sock = rb_io_get_write_io(sock); + GetOpenFile(sock, fptr); + rb_io_check_writable(fptr); + + /* + * As with IO#write_nonblock, we may block if somebody is relying on + * buffered I/O; but nobody actually hits this because pipes and sockets + * are not userspace-buffered in Ruby by default. + */ + if (fptr->wbuf.len > 0) { + rb_io_flush(sock); } - else { /* cloexec_state == 0 */ - ret = socket(domain, type, proto); + +#ifdef __APPLE__ + again: +#endif + n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT); + if (n < 0) { + 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 (ret == -1) - return -1; -fix_cloexec: - rb_maygvl_fd_fix_cloexec(ret); -update_max_fd: - rb_update_max_fd(ret); - return ret; + return LONG2FIX(n); } -#else /* !SOCK_CLOEXEC */ +#endif /* MSG_DONTWAIT_RELIABLE */ + static int rsock_socket0(int domain, int type, int proto) { - int ret = socket(domain, type, proto); +#ifdef SOCK_CLOEXEC + type |= SOCK_CLOEXEC; +#endif - if (ret == -1) +#ifdef SOCK_NONBLOCK + type |= SOCK_NONBLOCK; +#endif + + int result = socket(domain, type, proto); + + if (result == -1) return -1; - rb_fd_fix_cloexec(ret); - return ret; + rb_fd_fix_cloexec(result); + +#ifndef SOCK_NONBLOCK + rsock_make_fd_nonblock(result); +#endif + + return result; } -#endif /* !SOCK_CLOEXEC */ int rsock_socket(int domain, int type, int proto) @@ -336,8 +433,7 @@ rsock_socket(int domain, int type, int proto) fd = rsock_socket0(domain, type, proto); if (fd < 0) { - if (errno == EMFILE || errno == ENFILE) { - rb_gc(); + if (rb_gc_for_fd(errno)) { fd = rsock_socket0(domain, type, proto); } } @@ -348,16 +444,35 @@ rsock_socket(int domain, int type, int proto) /* emulate blocking connect behavior on EINTR or non-blocking socket */ static int -wait_connectable(int fd) +wait_connectable(int fd, struct timeval *timeout) { int sockerr, revents; socklen_t sockerrlen; - /* only to clear pending error */ sockerrlen = (socklen_t)sizeof(sockerr); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0) return -1; + /* necessary for non-blocking sockets (at least ECONNREFUSED) */ + switch (sockerr) { + case 0: + break; +#ifdef EALREADY + case EALREADY: +#endif +#ifdef EISCONN + case EISCONN: +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: +#endif + errno = sockerr; + return -1; + } + /* * Stevens book says, successful finish turn on RB_WAITFD_OUT and * failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT. @@ -366,7 +481,7 @@ wait_connectable(int fd) * * Note: rb_wait_for_single_fd already retries on EINTR/ERESTART */ - revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, NULL); + revents = rb_wait_for_single_fd(fd, RB_WAITFD_IN|RB_WAITFD_OUT, timeout); if (revents < 0) return -1; @@ -381,6 +496,12 @@ wait_connectable(int fd) * 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: @@ -428,7 +549,7 @@ socks_connect_blocking(void *data) #endif int -rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks) +rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout) { int status; rb_blocking_function_t *func = connect_blocking; @@ -452,15 +573,19 @@ rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks) #ifdef EINPROGRESS case EINPROGRESS: #endif - return wait_connectable(fd); + return wait_connectable(fd, timeout); } } return status; } -static void -make_fd_nonblock(int fd) +void +rsock_make_fd_nonblock(int fd) { +#ifdef _WIN32 + return; +#endif + int flags; #ifdef F_GETFL flags = fcntl(fd, F_GETFL); @@ -479,50 +604,45 @@ make_fd_nonblock(int fd) static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { - int ret; socklen_t len0 = 0; -#ifdef HAVE_ACCEPT4 - static int try_accept4 = 1; -#endif if (address_len) len0 = *address_len; + #ifdef HAVE_ACCEPT4 - if (try_accept4) { - int flags = 0; -#ifdef SOCK_CLOEXEC - flags |= SOCK_CLOEXEC; -#endif - ret = accept4(socket, address, address_len, flags); - /* accept4 is available since Linux 2.6.28, glibc 2.10. */ - if (ret != -1) { - if (ret <= 2) - rb_maygvl_fd_fix_cloexec(ret); - if (address_len && len0 < *address_len) *address_len = len0; - return ret; - } - if (errno != ENOSYS) { - return -1; - } - try_accept4 = 0; - } + int flags = SOCK_CLOEXEC; + +#ifdef SOCK_NONBLOCK + flags |= SOCK_NONBLOCK; +#endif + + int result = accept4(socket, address, address_len, flags); + if (result == -1) return -1; + +#ifndef SOCK_NONBLOCK + rsock_make_fd_nonblock(result); +#endif +#else + int result = accept(socket, address, address_len); + if (result == -1) return -1; + + rb_maygvl_fd_fix_cloexec(result); + rsock_make_fd_nonblock(result); #endif - ret = accept(socket, address, address_len); - if (ret == -1) return -1; + if (address_len && len0 < *address_len) *address_len = len0; - rb_maygvl_fd_fix_cloexec(ret); - return ret; + return result; } - VALUE -rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len) +rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, + struct sockaddr *sockaddr, socklen_t *len) { int fd2; - rb_secure(3); rb_io_set_nonblock(fptr); fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len); if (fd2 < 0) { - switch (errno) { + int e = errno; + switch (e) { case EAGAIN: #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: @@ -531,12 +651,13 @@ rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, s #if defined EPROTO case EPROTO: #endif - rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block"); + if (ex == Qfalse) + return sym_wait_readable; + rb_readwrite_syserr_fail(RB_IO_WAIT_READABLE, e, "accept(2) would block"); } - rb_sys_fail("accept(2)"); + rb_syserr_fail(e, "accept(2)"); } rb_update_max_fd(fd2); - make_fd_nonblock(fd2); return rsock_init_sock(rb_obj_alloc(klass), fd2); } @@ -554,49 +675,80 @@ accept_blocking(void *data) } VALUE -rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len) +rsock_s_accept(VALUE klass, VALUE io, struct sockaddr *sockaddr, socklen_t *len) { - int fd2; - int retry = 0; - struct accept_arg arg; + rb_io_t *fptr = NULL; + RB_IO_POINTER(io, fptr); + + struct accept_arg accept_arg = { + .fd = fptr->fd, + .sockaddr = sockaddr, + .len = len + }; + + int retry = 0, peer; - rb_secure(3); - arg.fd = fd; - arg.sockaddr = sockaddr; - arg.len = len; retry: - rsock_maybe_wait_fd(fd); - fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg); - if (fd2 < 0) { - switch (errno) { - case EMFILE: - case ENFILE: - if (retry) break; - rb_gc(); - retry = 1; - goto retry; - default: - if (!rb_io_wait_readable(fd)) break; - retry = 0; - goto retry; - } - rb_sys_fail("accept(2)"); +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil); +#endif + peer = (int)BLOCKING_REGION_FD(accept_blocking, &accept_arg); + if (peer < 0) { + int error = errno; + + switch (error) { + case EMFILE: + case ENFILE: + case ENOMEM: + if (retry) break; + rb_gc(); + retry = 1; + goto retry; + default: + if (!rb_io_maybe_wait_readable(error, io, Qnil)) break; + retry = 0; + goto retry; + } + + rb_syserr_fail(error, "accept(2)"); } - rb_update_max_fd(fd2); - if (!klass) return INT2NUM(fd2); - return rsock_init_sock(rb_obj_alloc(klass), fd2); + + rb_update_max_fd(peer); + + if (!klass) return INT2NUM(peer); + + return rsock_init_sock(rb_obj_alloc(klass), peer); } int -rsock_getfamily(int sockfd) +rsock_getfamily(rb_io_t *fptr) { union_sockaddr ss; socklen_t sslen = (socklen_t)sizeof(ss); + int cached = fptr->mode & FMODE_SOCK; + + if (cached) { + switch (cached) { +#ifdef AF_UNIX + case FMODE_UNIX: return AF_UNIX; +#endif + case FMODE_INET: return AF_INET; + case FMODE_INET6: return AF_INET6; + } + } ss.addr.sa_family = AF_UNSPEC; - if (getsockname(sockfd, &ss.addr, &sslen) < 0) + if (getsockname(fptr->fd, &ss.addr, &sslen) < 0) return AF_UNSPEC; + switch (ss.addr.sa_family) { +#ifdef AF_UNIX + case AF_UNIX: fptr->mode |= FMODE_UNIX; break; +#endif + case AF_INET: fptr->mode |= FMODE_INET; break; + case AF_INET6: fptr->mode |= FMODE_INET6; break; + } + return ss.addr.sa_family; } @@ -619,4 +771,11 @@ rsock_init_socket_init(void) rsock_init_addrinfo(); rsock_init_sockifaddr(); rsock_init_socket_constants(); + +#undef rb_intern + sym_wait_readable = ID2SYM(rb_intern("wait_readable")); + +#if MSG_DONTWAIT_RELIABLE + sym_wait_writable = ID2SYM(rb_intern("wait_writable")); +#endif } diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index 16a83734bb..b5cdc60080 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -19,11 +19,14 @@ struct inetsock_arg } remote, local; int type; int fd; + VALUE resolv_timeout; + VALUE connect_timeout; }; static VALUE -inetsock_cleanup(struct inetsock_arg *arg) +inetsock_cleanup(VALUE v) { + struct inetsock_arg *arg = (void *)v; if (arg->remote.res) { rb_freeaddrinfo(arg->remote.res); arg->remote.res = 0; @@ -39,22 +42,36 @@ inetsock_cleanup(struct inetsock_arg *arg) } static VALUE -init_inetsock_internal(struct inetsock_arg *arg) +init_inetsock_internal(VALUE v) { + struct inetsock_arg *arg = (void *)v; int error = 0; int type = arg->type; struct addrinfo *res, *lres; int fd, status = 0, local = 0; + int family = AF_UNSPEC; const char *syscall = 0; + VALUE connect_timeout = arg->connect_timeout; + struct timeval tv_storage; + struct timeval *tv = NULL; + + if (!NIL_P(connect_timeout)) { + tv_storage = rb_time_interval(connect_timeout); + tv = &tv_storage; + } + + arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, + family, SOCK_STREAM, + (type == INET_SERVER) ? AI_PASSIVE : 0); + - arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM, - (type == INET_SERVER) ? AI_PASSIVE : 0); /* * Maybe also accept a local address */ 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, SOCK_STREAM, 0); + arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, + family, SOCK_STREAM, 0); } arg->fd = fd = -1; @@ -96,6 +113,11 @@ init_inetsock_internal(struct inetsock_arg *arg) } 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)"; @@ -103,7 +125,7 @@ init_inetsock_internal(struct inetsock_arg *arg) if (status >= 0) { status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, - (type == INET_SOCKS)); + (type == INET_SOCKS), tv); syscall = "connect(2)"; } } @@ -147,7 +169,8 @@ init_inetsock_internal(struct inetsock_arg *arg) VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, - VALUE local_host, VALUE local_serv, int type) + VALUE local_host, VALUE local_serv, int type, + VALUE resolv_timeout, VALUE connect_timeout) { struct inetsock_arg arg; arg.sock = sock; @@ -159,6 +182,8 @@ rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, arg.local.res = 0; arg.type = type; arg.fd = -1; + arg.resolv_timeout = resolv_timeout; + arg.connect_timeout = connect_timeout; return rb_ensure(init_inetsock_internal, (VALUE)&arg, inetsock_cleanup, (VALUE)&arg); } @@ -188,6 +213,43 @@ rsock_revlookup_flag(VALUE revlookup, int *norevlookup) /* * call-seq: + * ipsocket.inspect -> string + * + * Return a string describing this IPSocket object. + */ +static VALUE +ip_inspect(VALUE sock) +{ + VALUE str = rb_call_super(0, 0); + rb_io_t *fptr = RFILE(sock)->fptr; + union_sockaddr addr; + 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); + } + return str; +} + +/* + * call-seq: * ipsocket.addr([reverse_lookup]) => [address_family, port, hostname, numeric_address] * * Returns the local address as an array which contains @@ -196,8 +258,8 @@ rsock_revlookup_flag(VALUE revlookup, int *norevlookup) * If +reverse_lookup+ is +true+ or +:hostname+, * hostname is obtained from numeric_address using reverse lookup. * Or if it is +false+, or +:numeric+, - * hostname is same as numeric_address. - * Or if it is +nil+ or ommitted, obeys to +ipsocket.do_not_reverse_lookup+. + * hostname is the same as numeric_address. + * Or if it is +nil+ or omitted, obeys to +ipsocket.do_not_reverse_lookup+. * See +Socket.getaddrinfo+ also. * * TCPSocket.open("www.ruby-lang.org", 80) {|sock| @@ -237,8 +299,8 @@ ip_addr(int argc, VALUE *argv, VALUE sock) * If +reverse_lookup+ is +true+ or +:hostname+, * hostname is obtained from numeric_address using reverse lookup. * Or if it is +false+, or +:numeric+, - * hostname is same as numeric_address. - * Or if it is +nil+ or ommitted, obeys to +ipsocket.do_not_reverse_lookup+. + * hostname is the same as numeric_address. + * Or if it is +nil+ or omitted, obeys to +ipsocket.do_not_reverse_lookup+. * See +Socket.getaddrinfo+ also. * * TCPSocket.open("www.ruby-lang.org", 80) {|sock| @@ -279,7 +341,7 @@ ip_peeraddr(int argc, VALUE *argv, VALUE sock) * * _flags_ should be a bitwise OR of Socket::MSG_* constants. * - * ipaddr is same as IPSocket#{peeraddr,addr}. + * ipaddr is the same as IPSocket#{peeraddr,addr}. * * u1 = UDPSocket.new * u1.bind("127.0.0.1", 4913) @@ -300,6 +362,8 @@ ip_recvfrom(int argc, VALUE *argv, VALUE sock) * * Lookups the IP address of _host_. * + * require 'socket' + * * IPSocket.getaddress("localhost") #=> "127.0.0.1" * IPSocket.getaddress("ip6-localhost") #=> "::1" * @@ -308,7 +372,7 @@ static VALUE ip_s_getaddress(VALUE obj, VALUE host) { union_sockaddr addr; - struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, SOCK_STREAM, 0); + struct rb_addrinfo *res = rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, 0); socklen_t len = res->ai->ai_addrlen; /* just take the first one */ @@ -327,6 +391,7 @@ rsock_init_ipsocket(void) * IPSocket is the super class of TCPSocket and UDPSocket. */ rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket); + rb_define_method(rb_cIPSocket, "inspect", ip_inspect, 0); rb_define_method(rb_cIPSocket, "addr", ip_addr, -1); rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, -1); rb_define_method(rb_cIPSocket, "recvfrom", ip_recvfrom, -1); diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index 2cd7aeadf9..d756a32a5a 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -1,4 +1,7 @@ +# frozen_string_literal: true + require 'socket.so' +require 'io/wait' class Addrinfo # creates an Addrinfo object from the arguments. @@ -50,17 +53,13 @@ class Addrinfo sock.ipv6only! if self.ipv6? sock.bind local_addrinfo if local_addrinfo if timeout - begin - sock.connect_nonblock(self) - rescue IO::WaitWritable - if !IO.select(nil, [sock], nil, timeout) + case sock.connect_nonblock(self, exception: false) + when 0 # success or EISCONN, other errors raise + break + when :wait_writable + sock.wait_writable(timeout) or raise Errno::ETIMEDOUT, 'user specified timeout' - end - begin - sock.connect_nonblock(self) # check connection failure - rescue Errno::EISCONN - end - end + end while true else sock.connect(self) end @@ -72,13 +71,13 @@ class Addrinfo begin yield sock ensure - sock.close if !sock.closed? + sock.close end else sock end end - private :connect_internal + protected :connect_internal # :call-seq: # addrinfo.connect_from([local_addr_args], [opts]) {|socket| ... } @@ -111,10 +110,8 @@ class Addrinfo # puts s.read # } # - def connect_from(*args, &block) - opts = Hash === args.last ? args.pop : {} - local_addr_args = args - connect_internal(family_addrinfo(*local_addr_args), opts[:timeout], &block) + def connect_from(*args, timeout: nil, &block) + connect_internal(family_addrinfo(*args), timeout, &block) end # :call-seq: @@ -136,8 +133,8 @@ class Addrinfo # puts s.read # } # - def connect(opts={}, &block) - connect_internal(nil, opts[:timeout], &block) + def connect(timeout: nil, &block) + connect_internal(nil, timeout, &block) end # :call-seq: @@ -159,11 +156,9 @@ class Addrinfo # puts s.read # } # - def connect_to(*args, &block) - opts = Hash === args.last ? args.pop : {} - remote_addr_args = args - remote_addrinfo = family_addrinfo(*remote_addr_args) - remote_addrinfo.send(:connect_internal, self, opts[:timeout], &block) + def connect_to(*args, timeout: nil, &block) + remote_addrinfo = family_addrinfo(*args) + remote_addrinfo.connect_internal(self, timeout, &block) end # creates a socket bound to self. @@ -190,7 +185,7 @@ class Addrinfo begin yield sock ensure - sock.close if !sock.closed? + sock.close end else sock @@ -213,7 +208,7 @@ class Addrinfo begin yield sock ensure - sock.close if !sock.closed? + sock.close end else sock @@ -228,8 +223,8 @@ class Addrinfo # # #<Addrinfo: [::1]:80 TCP (:80)> # # #<Addrinfo: [::1]:80 UDP (:80)> # - def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, &block) - Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags).each(&block) + def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block) + Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags, timeout: timeout).each(&block) end end @@ -275,6 +270,192 @@ class BasicSocket < IO end addr end + + # call-seq: + # basicsocket.sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent + # + # sendmsg sends a message using sendmsg(2) system call in blocking manner. + # + # _mesg_ is a string to send. + # + # _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_OOB. + # + # _dest_sockaddr_ is a destination socket address for connection-less socket. + # It should be a sockaddr such as a result of Socket.sockaddr_in. + # An Addrinfo object can be used too. + # + # _controls_ is a list of ancillary data. + # The element of _controls_ should be Socket::AncillaryData or + # 3-elements array. + # The 3-element array should contains cmsg_level, cmsg_type and data. + # + # The return value, _numbytes_sent_ is an integer which is the number of bytes sent. + # + # sendmsg can be used to implement send_io as follows: + # + # # use Socket::AncillaryData. + # ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno) + # sock.sendmsg("a", 0, nil, ancdata) + # + # # use 3-element array. + # ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")] + # sock.sendmsg("\0", 0, nil, ancdata) + def sendmsg(mesg, flags = 0, dest_sockaddr = nil, *controls) + __sendmsg(mesg, flags, dest_sockaddr, controls) + end + + # call-seq: + # basicsocket.sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls, opts={}) => numbytes_sent + # + # sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner. + # + # It is similar to BasicSocket#sendmsg + # but the non-blocking flag is set before the system call + # and it doesn't retry the system call. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that sendmsg_nonblock should not raise an IO::WaitWritable exception, but + # return the symbol +:wait_writable+ instead. + def sendmsg_nonblock(mesg, flags = 0, dest_sockaddr = nil, *controls, + exception: true) + __sendmsg_nonblock(mesg, flags, dest_sockaddr, controls, exception) + end + + # call-seq: + # basicsocket.recv_nonblock(maxlen [, flags [, buf [, options ]]]) => mesg + # + # Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after + # O_NONBLOCK is set for the underlying file descriptor. + # _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. + # + # === Parameters + # * +maxlen+ - the number of bytes to receive from the socket + # * +flags+ - zero or more of the +MSG_+ options + # * +buf+ - destination String buffer + # * +options+ - keyword hash, supporting `exception: false` + # + # === Example + # serv = TCPServer.new("127.0.0.1", 0) + # af, port, host, addr = serv.addr + # c = TCPSocket.new(addr, port) + # s = serv.accept + # c.send "aaa", 0 + # begin # emulate blocking recv. + # p s.recv_nonblock(10) #=> "aaa" + # rescue IO::WaitReadable + # IO.select([s]) + # retry + # end + # + # Refer to Socket#recvfrom for the exceptions that may be thrown if the call + # to _recv_nonblock_ fails. + # + # BasicSocket#recv_nonblock may raise any error corresponding to recvfrom(2) failure, + # including Errno::EWOULDBLOCK. + # + # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, + # it is extended by IO::WaitReadable. + # So IO::WaitReadable can be used to rescue the exceptions for retrying recv_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that recv_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + # + # === See + # * Socket#recvfrom + def recv_nonblock(len, flag = 0, str = nil, exception: true) + __recv_nonblock(len, flag, str, exception) + end + + # call-seq: + # basicsocket.recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) => [mesg, sender_addrinfo, rflags, *controls] + # + # recvmsg receives a message using recvmsg(2) system call in blocking manner. + # + # _maxmesglen_ is the maximum length of mesg to receive. + # + # _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_PEEK. + # + # _maxcontrollen_ is the maximum length of controls (ancillary data) to receive. + # + # _opts_ is option hash. + # Currently :scm_rights=>bool is the only option. + # + # :scm_rights option specifies that application expects SCM_RIGHTS control message. + # If the value is nil or false, application don't expects SCM_RIGHTS control message. + # In this case, recvmsg closes the passed file descriptors immediately. + # This is the default behavior. + # + # If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message. + # In this case, recvmsg creates IO objects for each file descriptors for + # Socket::AncillaryData#unix_rights method. + # + # The return value is 4-elements array. + # + # _mesg_ is a string of the received message. + # + # _sender_addrinfo_ is a sender socket address for connection-less socket. + # It is an Addrinfo object. + # For connection-oriented socket such as TCP, sender_addrinfo is platform dependent. + # + # _rflags_ is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC. + # It will be nil if the system uses 4.3BSD style old recvmsg system call. + # + # _controls_ is ancillary data which is an array of Socket::AncillaryData objects such as: + # + # #<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7> + # + # _maxmesglen_ and _maxcontrollen_ can be nil. + # In that case, the buffer will be grown until the message is not truncated. + # Internally, MSG_PEEK is used. + # Buffer full and MSG_CTRUNC are checked for truncation. + # + # recvmsg can be used to implement recv_io as follows: + # + # mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true) + # controls.each {|ancdata| + # if ancdata.cmsg_is?(:SOCKET, :RIGHTS) + # return ancdata.unix_rights[0] + # end + # } + def recvmsg(dlen = nil, flags = 0, clen = nil, scm_rights: false) + __recvmsg(dlen, flags, clen, scm_rights) + end + + # call-seq: + # basicsocket.recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) => [data, sender_addrinfo, rflags, *controls] + # + # recvmsg receives a message using recvmsg(2) system call in non-blocking manner. + # + # It is similar to BasicSocket#recvmsg + # but non-blocking flag is set before the system call + # and it doesn't retry the system call. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that recvmsg_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + def recvmsg_nonblock(dlen = nil, flags = 0, clen = nil, + scm_rights: false, exception: true) + __recvmsg_nonblock(dlen, flags, clen, scm_rights, exception) + end + + # Linux-specific optimizations to avoid fcntl for IO#read_nonblock + # and IO#write_nonblock using MSG_DONTWAIT + # Do other platforms support MSG_DONTWAIT reliably? + if RUBY_PLATFORM =~ /linux/ && Socket.const_defined?(:MSG_DONTWAIT) + def read_nonblock(len, str = nil, exception: true) # :nodoc: + __read_nonblock(len, str, exception) + end + + def write_nonblock(buf, exception: true) # :nodoc: + __write_nonblock(buf, exception) + end + end end class Socket < BasicSocket @@ -285,6 +466,133 @@ class Socket < BasicSocket end end + # call-seq: + # socket.recvfrom_nonblock(maxlen[, flags[, outbuf[, opts]]]) => [mesg, sender_addrinfo] + # + # Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after + # O_NONBLOCK is set for the underlying file descriptor. + # _flags_ is zero or more of the +MSG_+ options. + # The first element of the results, _mesg_, is the data received. + # 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. + # + # === Parameters + # * +maxlen+ - the maximum number of bytes to receive from the socket + # * +flags+ - zero or more of the +MSG_+ options + # * +outbuf+ - destination String buffer + # * +opts+ - keyword hash, supporting `exception: false` + # + # === Example + # # In one file, start this first + # require 'socket' + # include Socket::Constants + # socket = Socket.new(AF_INET, SOCK_STREAM, 0) + # sockaddr = Socket.sockaddr_in(2200, 'localhost') + # socket.bind(sockaddr) + # socket.listen(5) + # client, client_addrinfo = socket.accept + # begin # emulate blocking recvfrom + # pair = client.recvfrom_nonblock(20) + # rescue IO::WaitReadable + # IO.select([client]) + # retry + # end + # data = pair[0].chomp + # puts "I only received 20 bytes '#{data}'" + # sleep 1 + # socket.close + # + # # In another file, start this second + # require 'socket' + # include Socket::Constants + # socket = Socket.new(AF_INET, SOCK_STREAM, 0) + # sockaddr = Socket.sockaddr_in(2200, 'localhost') + # socket.connect(sockaddr) + # socket.puts "Watch this get cut short!" + # socket.close + # + # Refer to Socket#recvfrom for the exceptions that may be thrown if the call + # to _recvfrom_nonblock_ fails. + # + # Socket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, + # including Errno::EWOULDBLOCK. + # + # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, + # it is extended by IO::WaitReadable. + # So IO::WaitReadable can be used to rescue the exceptions for retrying + # recvfrom_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that recvfrom_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + # + # === See + # * Socket#recvfrom + def recvfrom_nonblock(len, flag = 0, str = nil, exception: true) + __recvfrom_nonblock(len, flag, str, exception) + end + + # call-seq: + # socket.accept_nonblock([options]) => [client_socket, client_addrinfo] + # + # Accepts an incoming connection using accept(2) after + # O_NONBLOCK is set for the underlying file descriptor. + # It returns an array containing the accepted socket + # for the incoming connection, _client_socket_, + # and an Addrinfo, _client_addrinfo_. + # + # === Example + # # In one script, start this first + # require 'socket' + # include Socket::Constants + # socket = Socket.new(AF_INET, SOCK_STREAM, 0) + # sockaddr = Socket.sockaddr_in(2200, 'localhost') + # socket.bind(sockaddr) + # socket.listen(5) + # begin # emulate blocking accept + # client_socket, client_addrinfo = socket.accept_nonblock + # rescue IO::WaitReadable, Errno::EINTR + # IO.select([socket]) + # retry + # end + # puts "The client said, '#{client_socket.readline.chomp}'" + # client_socket.puts "Hello from script one!" + # socket.close + # + # # In another script, start this second + # require 'socket' + # include Socket::Constants + # socket = Socket.new(AF_INET, SOCK_STREAM, 0) + # sockaddr = Socket.sockaddr_in(2200, 'localhost') + # socket.connect(sockaddr) + # socket.puts "Hello from script 2." + # puts "The server said, '#{socket.readline.chomp}'" + # socket.close + # + # Refer to Socket#accept for the exceptions that may be thrown if the call + # to _accept_nonblock_ fails. + # + # Socket#accept_nonblock may raise any error corresponding to accept(2) failure, + # including Errno::EWOULDBLOCK. + # + # If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED or Errno::EPROTO, + # it is extended by IO::WaitReadable. + # So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that accept_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + # + # === See + # * Socket#accept + def accept_nonblock(exception: true) + __accept_nonblock(exception) + 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]) @@ -298,6 +606,7 @@ 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. @@ -311,31 +620,26 @@ class Socket < BasicSocket # puts sock.read # } # - def self.tcp(host, port, *rest) # :yield: socket - opts = Hash === rest.last ? rest.pop : {} - raise ArgumentError, "wrong number of arguments (#{rest.length} for 2)" if 2 < rest.length - local_host, local_port = rest + def self.tcp(host, port, local_host = nil, local_port = nil, connect_timeout: nil, resolv_timeout: nil) # :yield: socket last_error = nil ret = nil - connect_timeout = opts[:connect_timeout] - local_addr_list = nil if local_host != nil || local_port != nil local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil) end - Addrinfo.foreach(host, port, nil, :STREAM) {|ai| + Addrinfo.foreach(host, port, nil, :STREAM, timeout: resolv_timeout) {|ai| if local_addr_list local_addr = local_addr_list.find {|local_ai| local_ai.afamily == ai.afamily } - next if !local_addr + next unless local_addr else local_addr = nil end begin sock = local_addr ? - ai.connect_from(local_addr, :timeout => connect_timeout) : - ai.connect(:timeout => connect_timeout) + ai.connect_from(local_addr, timeout: connect_timeout) : + ai.connect(timeout: connect_timeout) rescue SystemCallError last_error = $! next @@ -343,7 +647,7 @@ class Socket < BasicSocket ret = sock break } - if !ret + unless ret if last_error raise last_error else @@ -354,7 +658,7 @@ class Socket < BasicSocket begin yield ret ensure - ret.close if !ret.closed? + ret.close end else ret @@ -378,7 +682,7 @@ class Socket < BasicSocket if reuseaddr s.setsockopt(:SOCKET, :REUSEADDR, 1) end - if !port + unless port s.bind(ai) port = s.local_address.ip_port else @@ -386,10 +690,10 @@ class Socket < BasicSocket end } rescue Errno::EADDRINUSE - sockets.each {|s| s.close } + sockets.each(&:close) retry rescue Exception - sockets.each {|s| s.close } + sockets.each(&:close) raise end sockets @@ -406,7 +710,7 @@ class Socket < BasicSocket s.listen(Socket::SOMAXCONN) } rescue Exception - sockets.each {|s| s.close } + sockets.each(&:close) raise end sockets @@ -469,7 +773,7 @@ class Socket < BasicSocket raise last_error end rescue Exception - sockets.each {|s| s.close } + sockets.each(&:close) raise end end @@ -477,7 +781,7 @@ class Socket < BasicSocket begin yield sockets ensure - sockets.each {|s| s.close if !s.closed? } + sockets.each(&:close) end else sockets @@ -501,11 +805,8 @@ class Socket < BasicSocket loop { readable, _, _ = IO.select(sockets) readable.each {|r| - begin - sock, addr = r.accept_nonblock - rescue IO::WaitReadable - next - end + sock, addr = r.accept_nonblock(exception: false) + next if sock == :wait_readable yield sock, addr } } @@ -599,18 +900,19 @@ class Socket < BasicSocket Addrinfo.foreach(host, port, nil, :DGRAM, nil, Socket::AI_PASSIVE) {|ai| if ai.ipv4? && ai.ip_address == "0.0.0.0" local_addrs.each {|a| - next if !a.ipv4? + next unless a.ipv4? ip_list << Addrinfo.new(a.to_sockaddr, :INET, :DGRAM, 0); } elsif ai.ipv6? && ai.ip_address == "::" && !ipv6_recvpktinfo local_addrs.each {|a| - next if !a.ipv6? + next unless a.ipv6? ip_list << Addrinfo.new(a.to_sockaddr, :INET6, :DGRAM, 0); } else ip_list << ai end } + ip_list.uniq!(&:to_sockaddr) if port == 0 sockets = ip_sockets_port0(ip_list, false) @@ -641,7 +943,7 @@ class Socket < BasicSocket begin yield sockets ensure - sockets.each {|s| s.close if !s.closed? } if sockets + sockets.each(&:close) if sockets end else sockets @@ -669,11 +971,8 @@ class Socket < BasicSocket # def self.udp_server_recv(sockets) sockets.each {|r| - begin - msg, sender_addrinfo, _, *controls = r.recvmsg_nonblock - rescue IO::WaitReadable - next - end + msg, sender_addrinfo, _, *controls = r.recvmsg_nonblock(exception: false) + next if msg == :wait_readable ai = r.local_address if ai.ipv6? and pktinfo = controls.find {|c| c.cmsg_is?(:IPV6, :PKTINFO) } ai = Addrinfo.udp(pktinfo.ipv6_pktinfo_addr.ip_address, ai.ip_port) @@ -750,7 +1049,7 @@ class Socket < BasicSocket attr_reader :local_address def inspect # :nodoc: - "\#<#{self.class}: #{@remote_address.inspect_sockaddr} to #{@local_address.inspect_sockaddr}>" + "\#<#{self.class}: #{@remote_address.inspect_sockaddr} to #{@local_address.inspect_sockaddr}>".dup end # Sends the String +msg+ to the source @@ -781,7 +1080,7 @@ class Socket < BasicSocket begin yield sock ensure - sock.close if !sock.closed? + sock.close end else sock @@ -805,12 +1104,12 @@ class Socket < BasicSocket # } # def self.unix_server_socket(path) - if !unix_socket_abstract_name?(path) + unless unix_socket_abstract_name?(path) begin st = File.lstat(path) rescue Errno::ENOENT end - if st && st.socket? && st.owned? + if st&.socket? && st.owned? File.unlink path end end @@ -819,8 +1118,8 @@ class Socket < BasicSocket begin yield s ensure - s.close if !s.closed? - if !unix_socket_abstract_name?(path) + s.close + unless unix_socket_abstract_name?(path) File.unlink path end end @@ -867,5 +1166,192 @@ class Socket < BasicSocket } end + # call-seq: + # socket.connect_nonblock(remote_sockaddr, [options]) => 0 + # + # Requests a connection to be made on the given +remote_sockaddr+ after + # O_NONBLOCK is set for the underlying file descriptor. + # Returns 0 if successful, otherwise an exception is raised. + # + # === Parameter + # # +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object + # + # === Example: + # # Pull down Google's web page + # require 'socket' + # include Socket::Constants + # socket = Socket.new(AF_INET, SOCK_STREAM, 0) + # sockaddr = Socket.sockaddr_in(80, 'www.google.com') + # begin # emulate blocking connect + # socket.connect_nonblock(sockaddr) + # rescue IO::WaitWritable + # IO.select(nil, [socket]) # wait 3-way handshake completion + # begin + # socket.connect_nonblock(sockaddr) # check connection failure + # rescue Errno::EISCONN + # end + # end + # socket.write("GET / HTTP/1.0\r\n\r\n") + # results = socket.read + # + # Refer to Socket#connect for the exceptions that may be thrown if the call + # to _connect_nonblock_ fails. + # + # Socket#connect_nonblock may raise any error corresponding to connect(2) failure, + # including Errno::EINPROGRESS. + # + # If the exception is Errno::EINPROGRESS, + # it is extended by IO::WaitWritable. + # So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that connect_nonblock should not raise an IO::WaitWritable exception, but + # return the symbol +:wait_writable+ instead. + # + # === See + # # Socket#connect + def connect_nonblock(addr, exception: true) + __connect_nonblock(addr, exception) + end +end + +class UDPSocket < IPSocket + + # call-seq: + # udpsocket.recvfrom_nonblock(maxlen [, flags[, outbuf [, options]]]) => [mesg, sender_inet_addr] + # + # Receives up to _maxlen_ bytes from +udpsocket+ using recvfrom(2) after + # O_NONBLOCK is set for the underlying file descriptor. + # _flags_ is zero or more of the +MSG_+ options. + # 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. + # + # === Parameters + # * +maxlen+ - the number of bytes to receive from the socket + # * +flags+ - zero or more of the +MSG_+ options + # * +outbuf+ - destination String buffer + # * +options+ - keyword hash, supporting `exception: false` + # + # === Example + # require 'socket' + # s1 = UDPSocket.new + # s1.bind("127.0.0.1", 0) + # s2 = UDPSocket.new + # s2.bind("127.0.0.1", 0) + # s2.connect(*s1.addr.values_at(3,1)) + # s1.connect(*s2.addr.values_at(3,1)) + # s1.send "aaa", 0 + # begin # emulate blocking recvfrom + # p s2.recvfrom_nonblock(10) #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]] + # rescue IO::WaitReadable + # IO.select([s2]) + # retry + # end + # + # Refer to Socket#recvfrom for the exceptions that may be thrown if the call + # to _recvfrom_nonblock_ fails. + # + # UDPSocket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, + # including Errno::EWOULDBLOCK. + # + # If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, + # it is extended by IO::WaitReadable. + # So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that recvfrom_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + # + # === See + # * Socket#recvfrom + def recvfrom_nonblock(len, flag = 0, outbuf = nil, exception: true) + __recvfrom_nonblock(len, flag, outbuf, exception) + end +end + +class TCPServer < TCPSocket + + # call-seq: + # tcpserver.accept_nonblock([options]) => tcpsocket + # + # Accepts an incoming connection using accept(2) after + # O_NONBLOCK is set for the underlying file descriptor. + # It returns an accepted TCPSocket for the incoming connection. + # + # === Example + # require 'socket' + # serv = TCPServer.new(2202) + # begin # emulate blocking accept + # sock = serv.accept_nonblock + # rescue IO::WaitReadable, Errno::EINTR + # IO.select([serv]) + # retry + # end + # # sock is an accepted socket. + # + # Refer to Socket#accept for the exceptions that may be thrown if the call + # to TCPServer#accept_nonblock fails. + # + # TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure, + # including Errno::EWOULDBLOCK. + # + # If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO, + # it is extended by IO::WaitReadable. + # So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that accept_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + # + # === See + # * TCPServer#accept + # * Socket#accept + def accept_nonblock(exception: true) + __accept_nonblock(exception) + end end +class UNIXServer < UNIXSocket + # call-seq: + # unixserver.accept_nonblock([options]) => unixsocket + # + # Accepts an incoming connection using accept(2) after + # O_NONBLOCK is set for the underlying file descriptor. + # It returns an accepted UNIXSocket for the incoming connection. + # + # === Example + # require 'socket' + # serv = UNIXServer.new("/tmp/sock") + # begin # emulate blocking accept + # sock = serv.accept_nonblock + # rescue IO::WaitReadable, Errno::EINTR + # IO.select([serv]) + # retry + # end + # # sock is an accepted socket. + # + # Refer to Socket#accept for the exceptions that may be thrown if the call + # to UNIXServer#accept_nonblock fails. + # + # UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure, + # including Errno::EWOULDBLOCK. + # + # If the exception is Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED or Errno::EPROTO, + # it is extended by IO::WaitReadable. + # So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. + # + # By specifying a keyword argument _exception_ to +false+, you can indicate + # that accept_nonblock should not raise an IO::WaitReadable exception, but + # return the symbol +:wait_readable+ instead. + # + # === See + # * UNIXServer#accept + # * Socket#accept + def accept_nonblock(exception: true) + __accept_nonblock(exception) + end +end if defined?(UNIXSocket) diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb index 59fcb17682..577958a358 100644 --- a/ext/socket/mkconstants.rb +++ b/ext/socket/mkconstants.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: false require 'optparse' require 'erb' @@ -72,7 +73,15 @@ def each_name(pat) } end -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") +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 +end + +erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") % each_const {|guard, name, default_value| #if !defined(<%=name%>) # if defined(HAVE_CONST_<%=name.upcase%>) @@ -86,7 +95,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") % } EOS -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, default_value)") +erb_new.call(<<'EOS', nil, '%').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%>)); @@ -95,7 +104,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(name, def #endif EOS -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") +erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") % each_const {|guard, name, default_value| % if guard #if <%=guard%> @@ -145,7 +154,7 @@ def each_names_with_len(pat, prefix_optional=nil) } end -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_decl(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', nil, '%').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); @@ -155,7 +164,7 @@ int <%=funcname%>(const char *str, long len, int *valp); %end EOS -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', nil, '%').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) { @@ -171,12 +180,13 @@ int % } default: + if (!str || !valp) {/* wrong argument */} return -1; } } EOS -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)") +erb_new.call(<<'EOS', nil, '%').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)%> @@ -205,7 +215,7 @@ def reverse_each_name_with_prefix_optional(pat, prefix_pat) end end -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)") +erb_new.call(<<'EOS', nil, '%').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%> @@ -214,7 +224,7 @@ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pa % } EOS -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)") +erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)") ID <%=func_name%>(int val) { @@ -225,7 +235,7 @@ ID } EOS -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)") +erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_decl(func_name, hash_var)") ID <%=func_name%>(int val); EOS @@ -274,7 +284,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(<<'EOS', nil, '%').result(binding) +result = erb_new.call(<<'EOS', nil, '%').result(binding) /* autogenerated file */ <%= INTERN_DEFS.map {|vardef, gen_hash, decl, func| vardef }.join("\n") %> @@ -317,7 +327,7 @@ init_constants(void) EOS -header_result = ERB.new(<<'EOS', nil, '%').result(binding) +header_result = erb_new.call(<<'EOS', nil, '%').result(binding) /* autogenerated file */ <%= gen_const_decls %> <%= NAME_TO_INT_DEFS.map {|decl, func| decl }.join("\n") %> @@ -348,6 +358,8 @@ SOCK_RAW nil A raw socket provides low-level access for direct access or impleme SOCK_RDM nil A reliable datagram socket provides reliable delivery of messages SOCK_SEQPACKET nil A sequential packet socket provides sequenced, reliable two-way connection for datagrams SOCK_PACKET nil Device-level packet access +SOCK_NONBLOCK nil Set the O_NONBLOCK file status flag on the open file description (see open(2)) referred to by the new file descriptor. +SOCK_CLOEXEC nil Set the close-on-exec (FD_CLOEXEC) flag on the new file descriptor. AF_UNSPEC nil Unspecified protocol, any supported address family PF_UNSPEC nil Unspecified protocol, any supported address family @@ -387,6 +399,8 @@ AF_SNA nil IBM SNA protocol PF_SNA nil IBM SNA protocol AF_DEC nil DECnet protocol PF_DEC nil DECnet protocol +AF_DECnet nil DECnet protocol +PF_DECnet nil DECnet protocol AF_DLI nil DEC Direct Data Link Interface protocol PF_DLI nil DEC Direct Data Link Interface protocol AF_LAT nil Local Area Transport protocol @@ -428,7 +442,34 @@ AF_E164 nil CCITT (ITU-T) E.164 recommendation PF_XTP nil eXpress Transfer Protocol PF_RTIP PF_PIP -PF_KEY +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 +PF_NETLINK nil Kernel user interface device +AF_RDS nil Reliable Datagram Sockets (RDS) protocol +PF_RDS nil Reliable Datagram Sockets (RDS) protocol +AF_PPPOX nil Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE) +PF_PPPOX nil Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE) +AF_LLC nil Logical link control (IEEE 802.2 LLC) protocol +PF_LLC nil Logical link control (IEEE 802.2 LLC) protocol +AF_IB nil InfiniBand native addressing +PF_IB nil InfiniBand native addressing +AF_MPLS nil Multiprotocol Label Switching +PF_MPLS nil Multiprotocol Label Switching +AF_CAN nil Controller Area Network automotive bus protocol +PF_CAN nil Controller Area Network automotive bus protocol +AF_TIPC nil TIPC, "cluster domain sockets" protocol +PF_TIPC nil TIPC, "cluster domain sockets" protocol +AF_BLUETOOTH nil Bluetooth low-level socket protocol +PF_BLUETOOTH nil Bluetooth low-level socket protocol +AF_ALG nil Interface to kernel crypto API +PF_ALG nil Interface to kernel crypto API +AF_VSOCK nil VSOCK (originally "VMWare VSockets") protocol for hypervisor-guest communication +PF_VSOCK nil VSOCK (originally "VMWare VSockets") protocol for hypervisor-guest communication +AF_KCM nil KCM (kernel connection multiplexor) interface +PF_KCM nil KCM (kernel connection multiplexor) interface +AF_XDP nil XDP (express data path) interface +PF_XDP nil XDP (express data path) interface MSG_OOB nil Process out-of-band data MSG_PEEK nil Peek at incoming message diff --git a/ext/socket/option.c b/ext/socket/option.c index ebec81ad13..4b33b3f1d3 100644 --- a/ext/socket/option.c +++ b/ext/socket/option.c @@ -27,6 +27,12 @@ VALUE rb_cSockOpt; # define USE_INSPECT_BYTE 1 #endif +#define check_size(len, size) \ + ((len) == (size) ? \ + (void)0 : \ + rb_raise(rb_eTypeError, "size differ. expected as "#size"=%d but %ld", \ + (int)size, (long)(len))) + static VALUE sockopt_pack_byte(VALUE value) { @@ -100,9 +106,9 @@ sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALU VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data) { - NEWOBJ_OF(obj, struct RObject, rb_cSockOpt, T_OBJECT); + VALUE obj = rb_obj_alloc(rb_cSockOpt); StringValue(data); - sockopt_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(optname), data); + sockopt_initialize(obj, INT2NUM(family), INT2NUM(level), INT2NUM(optname), data); return (VALUE)obj; } @@ -211,12 +217,9 @@ sockopt_s_byte(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE v static VALUE sockopt_byte(VALUE self) { - unsigned char i; VALUE data = sockopt_data(self); StringValue(data); - if (RSTRING_LEN(data) != sizeof(i)) - rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld", - (int)sizeof(i), (long)RSTRING_LEN(data)); + check_size(RSTRING_LEN(data), sizeof(char)); return CHR2FIX(*RSTRING_PTR(data)); } @@ -257,9 +260,7 @@ sockopt_int(VALUE self) int i; VALUE data = sockopt_data(self); StringValue(data); - if (RSTRING_LEN(data) != sizeof(int)) - rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld", - (int)sizeof(int), (long)RSTRING_LEN(data)); + check_size(RSTRING_LEN(data), sizeof(int)); memcpy((char*)&i, RSTRING_PTR(data), sizeof(int)); return INT2NUM(i); } @@ -271,6 +272,8 @@ sockopt_int(VALUE self) * Creates a new Socket::Option object which contains boolean as data. * Actually 0 or 1 as int is used. * + * require 'socket' + * * p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true) * #=> #<Socket::Option: INET SOCKET KEEPALIVE 1> * @@ -306,12 +309,10 @@ 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; } - if (len != sizeof(int)) - rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld", - (int)sizeof(int), (long)len); - memcpy((char*)&i, RSTRING_PTR(data), sizeof(int)); + check_size(len, sizeof(int)); + memcpy((char*)&i, RSTRING_PTR(data), len); return i == 0 ? Qfalse : Qtrue; } @@ -363,9 +364,7 @@ sockopt_linger(VALUE self) if (level != SOL_SOCKET || optname != SO_LINGER) rb_raise(rb_eTypeError, "linger socket option expected"); - if (RSTRING_LEN(data) != sizeof(l)) - rb_raise(rb_eTypeError, "size differ. expected as sizeof(struct linger)=%d but %ld", - (int)sizeof(struct linger), (long)RSTRING_LEN(data)); + check_size(RSTRING_LEN(data), sizeof(struct linger)); memcpy((char*)&l, RSTRING_PTR(data), sizeof(struct linger)); switch (l.l_onoff) { case 0: vonoff = Qfalse; break; @@ -407,7 +406,7 @@ sockopt_s_ipv4_multicast_loop(VALUE klass, VALUE value) * call-seq: * sockopt.ipv4_multicast_loop => integer * - * Returns the ipv4_multicast_loop data in _sockopt_ as a integer. + * Returns the ipv4_multicast_loop data in _sockopt_ as an integer. * * sockopt = Socket::Option.ipv4_multicast_loop(10) * p sockopt.ipv4_multicast_loop => 10 @@ -425,7 +424,7 @@ sockopt_ipv4_multicast_loop(VALUE self) } #endif rb_raise(rb_eTypeError, "ipv4_multicast_loop socket option expected"); - UNREACHABLE; + UNREACHABLE_RETURN(Qnil); } #define inspect_ipv4_multicast_loop(a,b,c,d) \ @@ -458,7 +457,7 @@ sockopt_s_ipv4_multicast_ttl(VALUE klass, VALUE value) * call-seq: * sockopt.ipv4_multicast_ttl => integer * - * Returns the ipv4_multicast_ttl data in _sockopt_ as a integer. + * Returns the ipv4_multicast_ttl data in _sockopt_ as an integer. * * sockopt = Socket::Option.ipv4_multicast_ttl(10) * p sockopt.ipv4_multicast_ttl => 10 @@ -476,7 +475,7 @@ sockopt_ipv4_multicast_ttl(VALUE self) } #endif rb_raise(rb_eTypeError, "ipv4_multicast_ttl socket option expected"); - UNREACHABLE; + UNREACHABLE_RETURN(Qnil); } #define inspect_ipv4_multicast_ttl(a,b,c,d) \ @@ -1250,7 +1249,7 @@ sockopt_inspect(VALUE self) v = optname_to_sym(level, optname); if (SYMBOL_P(v)) - rb_str_catf(ret, " %s", rb_id2name(SYM2ID(v))); + rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(v)); else rb_str_catf(ret, " optname:%d", optname); } @@ -1476,4 +1475,3 @@ rsock_init_sockopt(void) rb_define_method(rb_cSockOpt, "to_s", sockopt_data, 0); /* compatibility for ruby before 1.9.2 */ } - diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index caa08fea47..d94e96a2bc 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -145,6 +145,34 @@ ruby_getaddrinfo__darwin(const char *nodename, const char *servname, #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__darwin((node),(serv),(hints),(res)) #endif +#ifdef HAVE_INET_PTON +static int +parse_numeric_port(const char *service, int *portp) +{ + unsigned long u; + + if (!service) { + *portp = 0; + return 1; + } + + if (strspn(service, "0123456789") != strlen(service)) + return 0; + + errno = 0; + u = STRTOUL(service, NULL, 10); + if (errno) + return 0; + + if (0x10000 <= u) + return 0; + + *portp = (int)u; + + return 1; +} +#endif + #ifndef GETADDRINFO_EMU struct getaddrinfo_arg { @@ -181,7 +209,9 @@ numeric_getaddrinfo(const char *node, const char *service, # define inet_pton(f,s,d) rb_w32_inet_pton(f,s,d) # endif - if (node && (!service || strspn(service, "0123456789") == strlen(service))) { + int port; + + if (node && parse_numeric_port(service, &port)) { static const struct { int socktype; int protocol; @@ -191,7 +221,6 @@ numeric_getaddrinfo(const char *node, const char *service, { SOCK_RAW, 0 } }; struct addrinfo *ai = NULL; - int port = service ? (unsigned short)atoi(service): 0; 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; @@ -255,40 +284,6 @@ numeric_getaddrinfo(const char *node, const char *service, return EAI_FAIL; } -int -rb_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, - struct rb_addrinfo **res) -{ - struct addrinfo *ai; - int ret; - int allocated_by_malloc = 0; - - ret = numeric_getaddrinfo(node, service, hints, &ai); - if (ret == 0) - allocated_by_malloc = 1; - else { -#ifdef GETADDRINFO_EMU - ret = getaddrinfo(node, service, hints, &ai); -#else - struct getaddrinfo_arg arg; - MEMZERO(&arg, struct getaddrinfo_arg, 1); - arg.node = node; - arg.service = service; - arg.hints = hints; - arg.res = &ai; - ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0); -#endif - } - - if (ret == 0) { - *res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); - (*res)->allocated_by_malloc = allocated_by_malloc; - (*res)->ai = ai; - } - return ret; -} - void rb_freeaddrinfo(struct rb_addrinfo *ai) { @@ -388,15 +383,19 @@ str_is_number(const char *p) char *ep; if (!p || *p == '\0') - return 0; + return 0; ep = NULL; (void)STRTOUL(p, &ep, 10); if (ep && *ep == '\0') - return 1; + return 1; else - return 0; + return 0; } +#define str_equal(ptr, len, name) \ + ((ptr)[0] == name[0] && \ + rb_strlen_lit(name) == (len) && memcmp(ptr, name, len) == 0) + static char* host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) { @@ -411,24 +410,26 @@ host_str(VALUE host, char *hbuf, size_t hbuflen, int *flags_ptr) return hbuf; } else { - char *name; + const char *name; + size_t len; - SafeStringValue(host); - name = RSTRING_PTR(host); - if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "<any>") == 0)) { + StringValueCStr(host); + RSTRING_GETMEM(host, name, len); + if (!len || str_equal(name, len, "<any>")) { make_inetaddr(INADDR_ANY, hbuf, hbuflen); if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; } - else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) { + else if (str_equal(name, len, "<broadcast>")) { make_inetaddr(INADDR_BROADCAST, hbuf, hbuflen); if (flags_ptr) *flags_ptr |= AI_NUMERICHOST; } - else if (strlen(name) >= hbuflen) { + else if (len >= hbuflen) { rb_raise(rb_eArgError, "hostname too long (%"PRIuSIZE")", - strlen(name)); + len); } else { - strcpy(hbuf, name); + memcpy(hbuf, name, len); + hbuf[len] = '\0'; } return hbuf; } @@ -448,25 +449,78 @@ port_str(VALUE port, char *pbuf, size_t pbuflen, int *flags_ptr) return pbuf; } else { - char *serv; + const char *serv; + size_t len; - SafeStringValue(port); - serv = RSTRING_PTR(port); - if (strlen(serv) >= pbuflen) { + StringValueCStr(port); + RSTRING_GETMEM(port, serv, len); + if (len >= pbuflen) { rb_raise(rb_eArgError, "service name too long (%"PRIuSIZE")", - strlen(serv)); + len); } - strcpy(pbuf, serv); + memcpy(pbuf, serv, len); + pbuf[len] = '\0'; return pbuf; } } +static int +rb_scheduler_getaddrinfo(VALUE scheduler, VALUE host, const char *service, + const struct addrinfo *hints, struct rb_addrinfo **res) +{ + int error, res_allocated = 0, _additional_flags = 0; + long i, len; + struct addrinfo *ai, *ai_tail = NULL; + char *hostp; + char _hbuf[NI_MAXHOST]; + VALUE ip_addresses_array, ip_address; + + ip_addresses_array = rb_fiber_scheduler_address_resolve(scheduler, host); + + if (ip_addresses_array == Qundef) { + // Returns EAI_FAIL if the scheduler hook is not implemented: + return EAI_FAIL; + } else if (ip_addresses_array == Qnil) { + len = 0; + } else { + len = RARRAY_LEN(ip_addresses_array); + } + + for(i=0; i<len; i++) { + ip_address = rb_ary_entry(ip_addresses_array, i); + hostp = host_str(ip_address, _hbuf, sizeof(_hbuf), &_additional_flags); + error = numeric_getaddrinfo(hostp, service, hints, &ai); + if (error == 0) { + if (!res_allocated) { + res_allocated = 1; + *res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); + (*res)->allocated_by_malloc = 1; + (*res)->ai = ai; + ai_tail = ai; + } else { + while (ai_tail->ai_next) { + ai_tail = ai_tail->ai_next; + } + ai_tail->ai_next = ai; + ai_tail = ai; + } + } + } + + if (res_allocated) { // At least one valid result. + return 0; + } else { + return EAI_NONAME; + } +} + struct rb_addrinfo* rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack) { struct rb_addrinfo* res = NULL; + struct addrinfo *ai; char *hostp, *portp; - int error; + int error = 0; char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; int additional_flags = 0; @@ -474,11 +528,47 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h portp = port_str(port, pbuf, sizeof(pbuf), &additional_flags); if (socktype_hack && hints->ai_socktype == 0 && str_is_number(portp)) { - hints->ai_socktype = SOCK_DGRAM; + hints->ai_socktype = SOCK_DGRAM; } hints->ai_flags |= additional_flags; - error = rb_getaddrinfo(hostp, portp, hints, &res); + error = numeric_getaddrinfo(hostp, portp, hints, &ai); + if (error == 0) { + res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); + res->allocated_by_malloc = 1; + res->ai = ai; + } else { + VALUE scheduler = rb_fiber_scheduler_current(); + int resolved = 0; + + if (scheduler != Qnil && hostp && !(hints->ai_flags & AI_NUMERICHOST)) { + error = rb_scheduler_getaddrinfo(scheduler, host, portp, hints, &res); + + if (error != EAI_FAIL) { + resolved = 1; + } + } + + 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 + if (error == 0) { + res = (struct rb_addrinfo *)xmalloc(sizeof(struct rb_addrinfo)); + res->allocated_by_malloc = 0; + res->ai = ai; + } + } + } + if (error) { if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); @@ -489,13 +579,26 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h return res; } +int +rsock_fd_family(int fd) +{ + struct sockaddr sa = { 0 }; + socklen_t sa_len = sizeof(sa); + + 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 sa.sa_family; +} + struct rb_addrinfo* -rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags) +rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags) { struct addrinfo hints; MEMZERO(&hints, struct addrinfo, 1); - hints.ai_family = AF_UNSPEC; + hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_flags = flags; return rsock_getaddrinfo(host, port, &hints, 1); @@ -543,16 +646,21 @@ rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup) } #ifdef HAVE_SYS_UN_H -VALUE -rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len) +static long +unixsocket_len(const struct sockaddr_un *su, socklen_t socklen) { - char *s, *e; - s = sockaddr->sun_path; - e = (char *)sockaddr + len; + const char *s = su->sun_path, *e = (const char*)su + socklen; while (s < e && *(e-1) == '\0') e--; - if (s <= e) - return rb_str_new(s, e-s); + return e - s; +} + +VALUE +rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len) +{ + long n = unixsocket_len(sockaddr, len); + if (n >= 0) + return rb_str_new(sockaddr->sun_path, n); else return rb_str_new2(""); } @@ -595,8 +703,9 @@ struct hostent_arg { }; static VALUE -make_hostent_internal(struct hostent_arg *arg) +make_hostent_internal(VALUE v) { + struct hostent_arg *arg = (void *)v; VALUE host = arg->host; struct addrinfo* addr = arg->addr->ai; VALUE (*ipaddr)(struct sockaddr*, socklen_t) = arg->ipaddr; @@ -672,10 +781,8 @@ static void addrinfo_mark(void *ptr) { rb_addrinfo_t *rai = ptr; - if (rai) { - rb_gc_mark(rai->inspectname); - rb_gc_mark(rai->canonname); - } + rb_gc_mark(rai->inspectname); + rb_gc_mark(rai->canonname); } #define addrinfo_free RUBY_TYPED_DEFAULT_FREE @@ -683,7 +790,7 @@ addrinfo_mark(void *ptr) static size_t addrinfo_memsize(const void *ptr) { - return ptr ? sizeof(rb_addrinfo_t) : 0; + return sizeof(rb_addrinfo_t); } static const rb_data_type_t addrinfo_type = { @@ -759,7 +866,7 @@ rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, static struct rb_addrinfo * call_getaddrinfo(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, - int socktype_hack) + int socktype_hack, VALUE timeout) { struct addrinfo hints; struct rb_addrinfo *res; @@ -776,6 +883,7 @@ call_getaddrinfo(VALUE node, VALUE service, if (!NIL_P(flags)) { hints.ai_flags = NUM2INT(flags); } + res = rsock_getaddrinfo(node, service, &hints, socktype_hack); if (res == NULL) @@ -790,13 +898,13 @@ init_addrinfo_getaddrinfo(rb_addrinfo_t *rai, VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, VALUE inspectnode, VALUE inspectservice) { - struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1); + struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 1, Qnil); VALUE canonname; VALUE inspectname = rb_str_equal(node, inspectnode) ? Qnil : make_inspectname(inspectnode, inspectservice, res->ai); canonname = Qnil; if (res->ai->ai_canonname) { - canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname); + canonname = rb_str_new_cstr(res->ai->ai_canonname); OBJ_FREEZE(canonname); } @@ -846,8 +954,6 @@ make_inspectname(VALUE node, VALUE service, struct addrinfo *res) rb_str_catf(inspectname, ":%d", FIX2INT(service)); } if (!NIL_P(inspectname)) { - OBJ_INFECT(inspectname, node); - OBJ_INFECT(inspectname, service); OBJ_FREEZE(inspectname); } return inspectname; @@ -860,13 +966,13 @@ addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE canonname; VALUE inspectname; - struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0); + struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0, Qnil); inspectname = make_inspectname(node, service, res->ai); canonname = Qnil; if (res->ai->ai_canonname) { - canonname = rb_tainted_str_new_cstr(res->ai->ai_canonname); + canonname = rb_str_new_cstr(res->ai->ai_canonname); OBJ_FREEZE(canonname); } @@ -880,13 +986,13 @@ addrinfo_firstonly_new(VALUE node, VALUE service, VALUE family, VALUE socktype, } static VALUE -addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags) +addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE protocol, VALUE flags, VALUE timeout) { VALUE ret; struct addrinfo *r; VALUE inspectname; - struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0); + struct rb_addrinfo *res = call_getaddrinfo(node, service, family, socktype, protocol, flags, 0, timeout); inspectname = make_inspectname(node, service, res->ai); @@ -896,7 +1002,7 @@ addrinfo_list_new(VALUE node, VALUE service, VALUE family, VALUE socktype, VALUE VALUE canonname = Qnil; if (r->ai_canonname) { - canonname = rb_tainted_str_new_cstr(r->ai_canonname); + canonname = rb_str_new_cstr(r->ai_canonname); OBJ_FREEZE(canonname); } @@ -933,6 +1039,12 @@ init_unix_addrinfo(rb_addrinfo_t *rai, VALUE path, int socktype) init_addrinfo(rai, (struct sockaddr *)&un, len, PF_UNIX, socktype, 0, Qnil, Qnil); } + +static long +rai_unixsocket_len(const rb_addrinfo_t *rai) +{ + return unixsocket_len(&rai->addr.un, rai->sockaddr_len); +} #endif /* @@ -1062,16 +1174,16 @@ addrinfo_initialize(int argc, VALUE *argv, VALUE self) } static int -get_afamily(struct sockaddr *addr, socklen_t len) +get_afamily(const struct sockaddr *addr, socklen_t len) { - if ((socklen_t)((char*)&addr->sa_family + sizeof(addr->sa_family) - (char*)addr) <= len) + if ((socklen_t)((const char*)&addr->sa_family + sizeof(addr->sa_family) - (char*)addr) <= len) return addr->sa_family; else return AF_UNSPEC; } static int -ai_get_afamily(rb_addrinfo_t *rai) +ai_get_afamily(const rb_addrinfo_t *rai) { return get_afamily(&rai->addr.addr, rai->sockaddr_len); } @@ -1180,16 +1292,15 @@ rsock_inspect_sockaddr(struct sockaddr *sockaddr_arg, socklen_t socklen, VALUE r { struct sockaddr_un *addr = &sockaddr->un; char *p, *s, *e; + long len = unixsocket_len(addr, socklen); s = addr->sun_path; - e = (char*)addr + socklen; - while (s < e && *(e-1) == '\0') - e--; - if (e < s) + if (len < 0) rb_str_cat2(ret, "too-short-AF_UNIX-sockaddr"); - else if (s == e) + else if (len == 0) rb_str_cat2(ret, "empty-path-AF_UNIX-sockaddr"); else { int printable_only = 1; + e = s + len; p = s; while (p < e) { printable_only = printable_only && ISPRINT(*p) && !ISSPACE(*p); @@ -1515,13 +1626,7 @@ addrinfo_mdump(VALUE self) #ifdef HAVE_SYS_UN_H case AF_UNIX: { - struct sockaddr_un *su = &rai->addr.un; - char *s, *e; - s = su->sun_path; - e = (char*)su + rai->sockaddr_len; - while (s < e && *(e-1) == '\0') - e--; - sockaddr = rb_str_new(s, e-s); + sockaddr = rb_str_new(rai->addr.un.sun_path, rai_unixsocket_len(rai)); break; } #endif @@ -1639,7 +1744,7 @@ addrinfo_mload(VALUE self, VALUE ary) #endif res = call_getaddrinfo(rb_ary_entry(pair, 0), rb_ary_entry(pair, 1), INT2NUM(pfamily), INT2NUM(socktype), INT2NUM(protocol), - INT2NUM(flags), 1); + INT2NUM(flags), 1, Qnil); len = res->ai->ai_addrlen; memcpy(&ss, res->ai->ai_addr, res->ai->ai_addrlen); @@ -1736,7 +1841,6 @@ addrinfo_to_sockaddr(VALUE self) rb_addrinfo_t *rai = get_addrinfo(self); VALUE ret; ret = rb_str_new((char*)&rai->addr, rai->sockaddr_len); - OBJ_INFECT(ret, self); return ret; } @@ -1744,7 +1848,7 @@ addrinfo_to_sockaddr(VALUE self) * call-seq: * addrinfo.canonname => string or nil * - * returns the canonical name as an string. + * returns the canonical name as a string. * * nil is returned if no canonical name. * @@ -2255,28 +2359,27 @@ addrinfo_unix_path(VALUE self) rb_addrinfo_t *rai = get_addrinfo(self); int family = ai_get_afamily(rai); struct sockaddr_un *addr; - char *s, *e; + long n; if (family != AF_UNIX) rb_raise(rb_eSocket, "need AF_UNIX address"); addr = &rai->addr.un; - s = addr->sun_path; - e = (char*)addr + rai->sockaddr_len; - if (e < s) + n = rai_unixsocket_len(rai); + if (n < 0) rb_raise(rb_eSocket, "too short AF_UNIX address: %"PRIuSIZE" bytes given for minimum %"PRIuSIZE" bytes.", - (size_t)rai->sockaddr_len, (size_t)(s - (char *)addr)); - if (addr->sun_path + sizeof(addr->sun_path) < e) + (size_t)rai->sockaddr_len, offsetof(struct sockaddr_un, sun_path)); + if ((long)sizeof(addr->sun_path) < n) rb_raise(rb_eSocket, "too long AF_UNIX path (%"PRIuSIZE" bytes given but %"PRIuSIZE" bytes max)", - (size_t)(e - addr->sun_path), sizeof(addr->sun_path)); - while (s < e && *(e-1) == '\0') - e--; - return rb_str_new(s, e-s); + (size_t)n, sizeof(addr->sun_path)); + return rb_str_new(addr->sun_path, n); } #endif +static ID id_timeout; + /* * call-seq: * Addrinfo.getaddrinfo(nodename, service, family, socktype, protocol, flags) => [addrinfo, ...] @@ -2323,10 +2426,16 @@ addrinfo_unix_path(VALUE self) static VALUE addrinfo_s_getaddrinfo(int argc, VALUE *argv, VALUE self) { - VALUE node, service, family, socktype, protocol, flags; + VALUE node, service, family, socktype, protocol, flags, opts, timeout; - rb_scan_args(argc, argv, "24", &node, &service, &family, &socktype, &protocol, &flags); - return addrinfo_list_new(node, service, family, socktype, protocol, flags); + rb_scan_args(argc, argv, "24:", &node, &service, &family, &socktype, + &protocol, &flags, &opts); + rb_get_kwargs(opts, &id_timeout, 0, 1, &timeout); + if (timeout == Qundef) { + timeout = Qnil; + } + + return addrinfo_list_new(node, service, family, socktype, protocol, flags, timeout); } /* @@ -2414,7 +2523,6 @@ addrinfo_s_unix(int argc, VALUE *argv, VALUE self) addr = addrinfo_s_allocate(rb_cAddrinfo); DATA_PTR(addr) = rai = alloc_addrinfo(); init_unix_addrinfo(rai, path, socktype); - OBJ_INFECT(addr, path); return addr; } @@ -2498,7 +2606,7 @@ rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len) rb_raise(rb_eTypeError, "neither IO nor file descriptor"); } - UNREACHABLE; + UNREACHABLE_RETURN(Qnil); } /* @@ -2511,7 +2619,9 @@ rsock_init_addrinfo(void) * The Addrinfo class maps <tt>struct addrinfo</tt> to ruby. This * structure identifies an Internet host and a service. */ - rb_cAddrinfo = rb_define_class("Addrinfo", rb_cData); + 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); rb_define_method(rb_cAddrinfo, "inspect", addrinfo_inspect, 0); diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h index 84b971c04e..c0d40addca 100644 --- a/ext/socket/rubysocket.h +++ b/ext/socket/rubysocket.h @@ -1,12 +1,22 @@ #ifndef RUBY_SOCKET_H #define RUBY_SOCKET_H 1 -#include "ruby/ruby.h" -#include "ruby/io.h" -#include "ruby/thread.h" -#include "ruby/util.h" -#include "internal.h" +#include "ruby/config.h" +#include RUBY_EXTCONF_H + +#if defined(__sun) || defined(_AIX) +/* (Recent?) Solaris' <nfs/nfs.h> have conflicting definition of T_DATA. Let + * us honour system definition by undefining ours. + * + * See also [ruby-core:4261] + */ +# include "ruby/ruby.h" +# undef T_DATA +#endif + +#include <errno.h> #include <stdio.h> + #include <sys/types.h> #include <sys/stat.h> @@ -27,11 +37,7 @@ # undef HAVE_TYPE_STRUCT_SOCKADDR_DL # endif #else -# if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE) -# include <net/socket.h> -# else -# include <sys/socket.h> -# endif +# include <sys/socket.h> # include <netinet/in.h> # ifdef HAVE_NETINET_IN_SYSTM_H # include <netinet/in_systm.h> @@ -54,12 +60,11 @@ #ifdef HAVE_NETPACKET_PACKET_H # include <netpacket/packet.h> #endif + #ifdef HAVE_NET_ETHERNET_H # include <net/ethernet.h> #endif -#include <errno.h> - #ifdef HAVE_SYS_UN_H # include <sys/un.h> #endif @@ -80,14 +85,20 @@ #endif #ifdef HAVE_IFADDRS_H +# ifdef __HAIKU__ +# define _BSD_SOURCE +# endif # include <ifaddrs.h> #endif + #ifdef HAVE_SYS_IOCTL_H # include <sys/ioctl.h> #endif + #ifdef HAVE_SYS_SOCKIO_H # include <sys/sockio.h> #endif + #ifdef HAVE_NET_IF_H # include <net/if.h> #endif @@ -95,16 +106,41 @@ #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> #endif + #ifdef HAVE_SYS_UCRED_H # include <sys/ucred.h> #endif + #ifdef HAVE_UCRED_H # include <ucred.h> #endif + #ifdef HAVE_NET_IF_DL_H # include <net/if_dl.h> #endif +#ifdef SOCKS5 +# include <socks.h> +#endif + +#ifndef HAVE_GETADDRINFO +# include "addrinfo.h" +#endif + +#include "internal.h" +#include "internal/array.h" +#include "internal/error.h" +#include "internal/gc.h" +#include "internal/io.h" +#include "internal/thread.h" +#include "internal/vm.h" +#include "ruby/io.h" +#include "ruby/ruby.h" +#include "ruby/thread.h" +#include "ruby/util.h" +#include "sockport.h" +#include "ruby/fiber/scheduler.h" + #ifndef HAVE_TYPE_SOCKLEN_T typedef int socklen_t; #endif @@ -138,11 +174,6 @@ unsigned int if_nametoindex(const char *); */ #define pseudo_AF_FTIP pseudo_AF_RTIP -#ifndef HAVE_GETADDRINFO -# include "addrinfo.h" -#endif - -#include "sockport.h" #ifndef NI_MAXHOST # define NI_MAXHOST 1025 @@ -219,19 +250,19 @@ typedef union { # endif #endif -#ifdef __BEOS__ -# undef close -# define close closesocket -#endif - #define INET_CLIENT 0 #define INET_SERVER 1 #define INET_SOCKS 2 extern int rsock_do_not_reverse_lookup; -extern int rsock_cmsg_cloexec_state; #define FMODE_NOREVLOOKUP 0x100 +/* common socket families only */ +#define FMODE_UNIX 0x00200000 +#define FMODE_INET 0x00400000 +#define FMODE_INET6 0x00800000 +#define FMODE_SOCK (FMODE_UNIX|FMODE_INET|FMODE_INET6) + extern VALUE rb_cBasicSocket; extern VALUE rb_cIPSocket; extern VALUE rb_cTCPSocket; @@ -249,9 +280,7 @@ extern VALUE rb_eSocket; #ifdef SOCKS extern VALUE rb_cSOCKSSocket; -# ifdef SOCKS5 -# include <socks.h> -# else +# ifndef SOCKS5 void SOCKSinit(); int Rconnect(); # endif @@ -279,18 +308,19 @@ int rsock_optname_arg(int family, int level, VALUE optname); int rsock_cmsg_type_arg(int family, int level, VALUE type); int rsock_shutdown_how_arg(VALUE how); -int rsock_getfamily(int sockfd); +int rsock_getfamily(rb_io_t *fptr); struct rb_addrinfo { struct addrinfo *ai; int allocated_by_malloc; }; -int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct rb_addrinfo **res); void rb_freeaddrinfo(struct rb_addrinfo *ai); VALUE rsock_freeaddrinfo(VALUE arg); int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); -struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags); +int rsock_fd_family(int fd); +struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags); struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack); + VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len); VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len); @@ -316,7 +346,7 @@ int rsock_socket(int domain, int type, int proto); int rsock_detect_cloexec(int fd); VALUE rsock_init_sock(VALUE sock, int fd); VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass); -VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type); +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 rsock_init_unixsock(VALUE sock, VALUE path, int server); struct rsock_send_arg { @@ -337,28 +367,34 @@ enum sock_recv_type { RECV_SOCKET /* Socket#recvfrom */ }; -VALUE rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from); +VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, + 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); +int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout); -VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len); -VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len); +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); 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(int argc, VALUE *argv, VALUE sock); -VALUE rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock); +VALUE rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags, + VALUE dest_sockaddr, VALUE controls); +VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags, + VALUE dest_sockaddr, VALUE controls, VALUE ex); #else #define rsock_bsock_sendmsg rb_f_notimplement #define rsock_bsock_sendmsg_nonblock rb_f_notimplement #endif #if defined(HAVE_RECVMSG) -VALUE rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock); -VALUE rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock); +VALUE rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE clen, VALUE flags, + VALUE scm_rights); +VALUE rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE clen, + 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 @@ -396,22 +432,25 @@ NORETURN(void rsock_sys_fail_sockaddr(const char *, struct sockaddr *addr, sockl NORETURN(void rsock_sys_fail_raddrinfo(const char *, VALUE rai)); NORETURN(void rsock_sys_fail_raddrinfo_or_sockaddr(const char *, VALUE addr, VALUE rai)); +#if defined(__MINGW32__) || defined(_WIN32) +#define RSOCK_WAIT_BEFORE_BLOCKING +#endif + /* - * It is safe on Linux to attempt using a socket without waiting on it in - * all cases. For some syscalls (e.g. accept/accept4), blocking on the - * syscall instead of relying on select/poll allows the kernel to use - * "wake-one" behavior and avoid the thundering herd problem. - * This is likely safe on all other *nix-like systems, so this whitelist - * can be expanded by interested parties. + * some OSes may support MSG_DONTWAIT inconsistently depending on socket + * type, we only expect Linux to support it consistently for all socket types. */ -#if defined(__linux__) -static inline int rsock_maybe_fd_writable(int fd) { return 1; } -static inline void rsock_maybe_wait_fd(int fd) { } -#else /* some systems (mswin/mingw) need these. ref: r36946 */ -# define rsock_maybe_fd_writable(fd) rb_thread_fd_writable((fd)) -# define rsock_maybe_wait_fd(fd) rb_thread_wait_fd((fd)) +#if defined(MSG_DONTWAIT) && defined(__linux__) +# define MSG_DONTWAIT_RELIABLE 1 +#else +# define MSG_DONTWAIT_RELIABLE 0 #endif +VALUE rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex); +VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex); + +void rsock_make_fd_nonblock(int fd); + #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 7a5eab55cf..ccf990d11f 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -10,6 +10,8 @@ #include "rubysocket.h" +static VALUE sym_wait_writable; + static VALUE sock_s_unpack_sockaddr_in(VALUE, VALUE); void @@ -138,7 +140,6 @@ sock_initialize(int argc, VALUE *argv, VALUE sock) if (NIL_P(protocol)) protocol = INT2FIX(0); - rb_secure(3); setup_domain_and_type(domain, &d, type, &t); fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); @@ -150,7 +151,7 @@ sock_initialize(int argc, VALUE *argv, VALUE sock) static VALUE io_call_close(VALUE io) { - return rb_funcall(io, rb_intern("close"), 0, 0); + return rb_funcallv(io, rb_intern("close"), 0, 0); } static VALUE @@ -167,85 +168,47 @@ pair_yield(VALUE pair) #endif #if defined HAVE_SOCKETPAIR - -#ifdef SOCK_CLOEXEC static int -rsock_socketpair0(int domain, int type, int protocol, int sv[2]) +rsock_socketpair0(int domain, int type, int protocol, int descriptors[2]) { - int ret; - static int cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */ +#ifdef SOCK_CLOEXEC + type |= SOCK_CLOEXEC; +#endif - if (cloexec_state > 0) { /* common path, if SOCK_CLOEXEC is defined */ - ret = socketpair(domain, type|SOCK_CLOEXEC, protocol, sv); - if (ret == 0 && (sv[0] <= 2 || sv[1] <= 2)) { - goto fix_cloexec; /* highly unlikely */ - } - goto update_max_fd; - } - else if (cloexec_state < 0) { /* usually runs once only for detection */ - ret = socketpair(domain, type|SOCK_CLOEXEC, protocol, sv); - if (ret == 0) { - cloexec_state = rsock_detect_cloexec(sv[0]); - if ((cloexec_state == 0) || (sv[0] <= 2 || sv[1] <= 2)) - goto fix_cloexec; - goto update_max_fd; - } - else if (ret == -1 && errno == EINVAL) { - /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */ - ret = socketpair(domain, type, protocol, sv); - if (ret != -1) { - /* The reason of EINVAL may be other than SOCK_CLOEXEC. - * So disable SOCK_CLOEXEC only if socketpair() succeeds without SOCK_CLOEXEC. - * Ex. Socket.pair(:UNIX, 0xff) fails with EINVAL. - */ - cloexec_state = 0; - } - } - } - else { /* cloexec_state == 0 */ - ret = socketpair(domain, type, protocol, sv); - } - if (ret == -1) { - return -1; - } +#ifdef SOCK_NONBLOCK + type |= SOCK_NONBLOCK; +#endif -fix_cloexec: - rb_maygvl_fd_fix_cloexec(sv[0]); - rb_maygvl_fd_fix_cloexec(sv[1]); + int result = socketpair(domain, type, protocol, descriptors); -update_max_fd: - rb_update_max_fd(sv[0]); - rb_update_max_fd(sv[1]); + if (result == -1) + return -1; - return ret; -} -#else /* !SOCK_CLOEXEC */ -static int -rsock_socketpair0(int domain, int type, int protocol, int sv[2]) -{ - int ret = socketpair(domain, type, protocol, sv); +#ifndef SOCK_CLOEXEC + rb_fd_fix_cloexec(descriptors[0]); + rb_fd_fix_cloexec(descriptors[1]); +#endif - if (ret == -1) - return -1; +#ifndef SOCK_NONBLOCK + rsock_make_fd_nonblock(descriptors[0]); + rsock_make_fd_nonblock(descriptors[1]); +#endif - rb_fd_fix_cloexec(sv[0]); - rb_fd_fix_cloexec(sv[1]); - return ret; + return result; } -#endif /* !SOCK_CLOEXEC */ static int -rsock_socketpair(int domain, int type, int protocol, int sv[2]) +rsock_socketpair(int domain, int type, int protocol, int descriptors[2]) { - int ret; + int result; - ret = rsock_socketpair0(domain, type, protocol, sv); - if (ret < 0 && (errno == EMFILE || errno == ENFILE)) { - rb_gc(); - ret = rsock_socketpair0(domain, type, protocol, sv); + result = rsock_socketpair0(domain, type, protocol, descriptors); + + if (result < 0 && rb_gc_for_fd(errno)) { + result = rsock_socketpair0(domain, type, protocol, descriptors); } - return ret; + return result; } /* @@ -319,14 +282,14 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass) * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object * * === Example: - * # Pull down Google's web page - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' ) - * socket.connect( sockaddr ) - * socket.write( "GET / HTTP/1.0\r\n\r\n" ) - * results = socket.read + * # Pull down Google's web page + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' ) + * socket.connect( sockaddr ) + * socket.write( "GET / HTTP/1.0\r\n\r\n" ) + * results = socket.read * * === Unix-based Exceptions * On unix-based systems the following system exceptions may be raised if @@ -367,7 +330,7 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass) * * Errno::EOPNOTSUPP - the calling +socket+ is listening and cannot be connected * * Errno::EPROTOTYPE - the _sockaddr_ has a different type than the socket * bound to the specified peer address - * * Errno::ETIMEDOUT - the attempt to connect time out before a connection + * * Errno::ETIMEDOUT - the attempt to connect timed out before a connection * was made. * * On unix-based systems if the address family of the calling +socket+ is @@ -408,7 +371,7 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass) * * Errno::EHOSTUNREACH - no route to the network is present * * Errno::ENOBUFS - no buffer space is available * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket - * * Errno::ETIMEDOUT - the attempt to connect time out before a connection + * * Errno::ETIMEDOUT - the attempt to connect timed out before a connection * was made. * * Errno::EWOULDBLOCK - the socket is marked as nonblocking and the * connection cannot be completed immediately @@ -430,7 +393,7 @@ sock_connect(VALUE sock, VALUE addr) addr = rb_str_new4(addr); GetOpenFile(sock, fptr); fd = fptr->fd; - n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0); + 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); } @@ -438,50 +401,9 @@ sock_connect(VALUE sock, VALUE addr) return INT2FIX(n); } -/* - * call-seq: - * socket.connect_nonblock(remote_sockaddr) => 0 - * - * Requests a connection to be made on the given +remote_sockaddr+ after - * O_NONBLOCK is set for the underlying file descriptor. - * Returns 0 if successful, otherwise an exception is raised. - * - * === Parameter - * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object - * - * === Example: - * # Pull down Google's web page - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(80, 'www.google.com') - * begin # emulate blocking connect - * socket.connect_nonblock(sockaddr) - * rescue IO::WaitWritable - * IO.select(nil, [socket]) # wait 3-way handshake completion - * begin - * socket.connect_nonblock(sockaddr) # check connection failure - * rescue Errno::EISCONN - * end - * end - * socket.write("GET / HTTP/1.0\r\n\r\n") - * results = socket.read - * - * Refer to Socket#connect for the exceptions that may be thrown if the call - * to _connect_nonblock_ fails. - * - * Socket#connect_nonblock may raise any error corresponding to connect(2) failure, - * including Errno::EINPROGRESS. - * - * If the exception is Errno::EINPROGRESS, - * it is extended by IO::WaitWritable. - * So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock. - * - * === See - * * Socket#connect - */ +/* :nodoc: */ static VALUE -sock_connect_nonblock(VALUE sock, VALUE addr) +sock_connect_nonblock(VALUE sock, VALUE addr, VALUE ex) { VALUE rai; rb_io_t *fptr; @@ -493,9 +415,19 @@ sock_connect_nonblock(VALUE sock, VALUE addr) rb_io_set_nonblock(fptr); n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)); if (n < 0) { - if (errno == EINPROGRESS) - rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "connect(2) would block"); - rsock_sys_fail_raddrinfo_or_sockaddr("connect(2)", addr, rai); + 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 (ex == Qfalse) { + return INT2FIX(0); + } + } + rsock_syserr_fail_raddrinfo_or_sockaddr(e, "connect(2)", addr, rai); } return INT2FIX(n); @@ -511,18 +443,18 @@ sock_connect_nonblock(VALUE sock, VALUE addr) * * +local_sockaddr+ - the +struct+ sockaddr contained in a string or an Addrinfo object * * === Example - * require 'socket' + * require 'socket' * - * # use Addrinfo - * socket = Socket.new(:INET, :STREAM, 0) - * socket.bind(Addrinfo.tcp("127.0.0.1", 2222)) - * p socket.local_address #=> #<Addrinfo: 127.0.0.1:2222 TCP> + * # use Addrinfo + * socket = Socket.new(:INET, :STREAM, 0) + * socket.bind(Addrinfo.tcp("127.0.0.1", 2222)) + * p socket.local_address #=> #<Addrinfo: 127.0.0.1:2222 TCP> * - * # use struct sockaddr - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) - * socket.bind( sockaddr ) + * # use struct sockaddr + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) + * socket.bind( sockaddr ) * * === Unix-based Exceptions * On unix-based based systems the following system exceptions may be raised if @@ -613,18 +545,18 @@ sock_bind(VALUE sock, VALUE addr) * * +backlog+ - the maximum length of the queue for pending connections. * * === Example 1 - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) - * socket.bind( sockaddr ) - * socket.listen( 5 ) + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) + * socket.bind( sockaddr ) + * socket.listen( 5 ) * * === Example 2 (listening on an arbitrary port, unix-based systems only): - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * socket.listen( 1 ) + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * socket.listen( 1 ) * * === Unix-based Exceptions * On unix based systems the above will work because a new +sockaddr+ struct @@ -700,27 +632,27 @@ rsock_sock_listen(VALUE sock, VALUE log) * * +flags+ - zero or more of the +MSG_+ options * * === Example - * # In one file, start this first - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) - * socket.bind( sockaddr ) - * socket.listen( 5 ) - * client, client_addrinfo = socket.accept - * data = client.recvfrom( 20 )[0].chomp - * puts "I only received 20 bytes '#{data}'" - * sleep 1 - * socket.close - * - * # In another file, start this second - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) - * socket.connect( sockaddr ) - * socket.puts "Watch this get cut short!" - * socket.close + * # In one file, start this first + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) + * socket.bind( sockaddr ) + * socket.listen( 5 ) + * client, client_addrinfo = socket.accept + * data = client.recvfrom( 20 )[0].chomp + * puts "I only received 20 bytes '#{data}'" + * sleep 1 + * socket.close + * + * # In another file, start this second + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) + * socket.connect( sockaddr ) + * socket.puts "Watch this get cut short!" + * socket.close * * === Unix-based Exceptions * On unix-based based systems the following system exceptions may be raised if the @@ -796,72 +728,11 @@ sock_recvfrom(int argc, VALUE *argv, VALUE sock) return rsock_s_recvfrom(sock, argc, argv, RECV_SOCKET); } -/* - * call-seq: - * socket.recvfrom_nonblock(maxlen) => [mesg, sender_addrinfo] - * socket.recvfrom_nonblock(maxlen, flags) => [mesg, sender_addrinfo] - * - * Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * _flags_ is zero or more of the +MSG_+ options. - * The first element of the results, _mesg_, is the data received. - * 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. - * - * === Parameters - * * +maxlen+ - the maximum number of bytes to receive from the socket - * * +flags+ - zero or more of the +MSG_+ options - * - * === Example - * # In one file, start this first - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(2200, 'localhost') - * socket.bind(sockaddr) - * socket.listen(5) - * client, client_addrinfo = socket.accept - * begin # emulate blocking recvfrom - * pair = client.recvfrom_nonblock(20) - * rescue IO::WaitReadable - * IO.select([client]) - * retry - * end - * data = pair[0].chomp - * puts "I only received 20 bytes '#{data}'" - * sleep 1 - * socket.close - * - * # In another file, start this second - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(2200, 'localhost') - * socket.connect(sockaddr) - * socket.puts "Watch this get cut short!" - * socket.close - * - * Refer to Socket#recvfrom for the exceptions that may be thrown if the call - * to _recvfrom_nonblock_ fails. - * - * Socket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock. - * - * === See - * * Socket#recvfrom - */ +/* :nodoc: */ static VALUE -sock_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock) +sock_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex) { - return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_SOCKET); + return rsock_s_recvfrom_nonblock(sock, len, flg, str, ex, RECV_SOCKET); } /* @@ -879,80 +750,31 @@ sock_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock) * */ static VALUE -sock_accept(VALUE sock) +sock_accept(VALUE server) { - rb_io_t *fptr; - VALUE sock2; - union_sockaddr buf; - socklen_t len = (socklen_t)sizeof buf; + union_sockaddr buffer; + socklen_t length = (socklen_t)sizeof(buffer); - GetOpenFile(sock, fptr); - sock2 = rsock_s_accept(rb_cSocket,fptr->fd,&buf.addr,&len); + VALUE peer = rsock_s_accept(rb_cSocket, server, &buffer.addr, &length); - return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); + return rb_assoc_new(peer, rsock_io_socket_addrinfo(peer, &buffer.addr, length)); } -/* - * call-seq: - * socket.accept_nonblock => [client_socket, client_addrinfo] - * - * Accepts an incoming connection using accept(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * It returns an array containing the accepted socket - * for the incoming connection, _client_socket_, - * and an Addrinfo, _client_addrinfo_. - * - * === Example - * # In one script, start this first - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(2200, 'localhost') - * socket.bind(sockaddr) - * socket.listen(5) - * begin # emulate blocking accept - * client_socket, client_addrinfo = socket.accept_nonblock - * rescue IO::WaitReadable, Errno::EINTR - * IO.select([socket]) - * retry - * end - * puts "The client said, '#{client_socket.readline.chomp}'" - * client_socket.puts "Hello from script one!" - * socket.close - * - * # In another script, start this second - * require 'socket' - * include Socket::Constants - * socket = Socket.new(AF_INET, SOCK_STREAM, 0) - * sockaddr = Socket.sockaddr_in(2200, 'localhost') - * socket.connect(sockaddr) - * socket.puts "Hello from script 2." - * puts "The server said, '#{socket.readline.chomp}'" - * socket.close - * - * Refer to Socket#accept for the exceptions that may be thrown if the call - * to _accept_nonblock_ fails. - * - * Socket#accept_nonblock may raise any error corresponding to accept(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. - * - * === See - * * Socket#accept - */ +/* :nodoc: */ static VALUE -sock_accept_nonblock(VALUE sock) +sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; + struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); - sock2 = rsock_s_accept_nonblock(rb_cSocket, fptr, &buf.addr, &len); + sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); + + if (SYMBOL_P(sock2)) /* :wait_readable */ + return sock2; return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } @@ -965,28 +787,28 @@ sock_accept_nonblock(VALUE sock) * and an Addrinfo, _client_addrinfo_. * * === Example - * # In one script, start this first - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) - * socket.bind( sockaddr ) - * socket.listen( 5 ) - * client_fd, client_addrinfo = socket.sysaccept - * client_socket = Socket.for_fd( client_fd ) - * puts "The client said, '#{client_socket.readline.chomp}'" - * client_socket.puts "Hello from script one!" - * socket.close - * - * # In another script, start this second - * require 'socket' - * include Socket::Constants - * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) - * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) - * socket.connect( sockaddr ) - * socket.puts "Hello from script 2." - * puts "The server said, '#{socket.readline.chomp}'" - * socket.close + * # In one script, start this first + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) + * socket.bind( sockaddr ) + * socket.listen( 5 ) + * client_fd, client_addrinfo = socket.sysaccept + * client_socket = Socket.for_fd( client_fd ) + * puts "The client said, '#{client_socket.readline.chomp}'" + * client_socket.puts "Hello from script one!" + * socket.close + * + * # In another script, start this second + * require 'socket' + * include Socket::Constants + * socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) + * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) + * socket.connect( sockaddr ) + * socket.puts "Hello from script 2." + * puts "The server said, '#{socket.readline.chomp}'" + * socket.close * * Refer to Socket#accept for the exceptions that may be thrown if the call * to _sysaccept_ fails. @@ -995,17 +817,14 @@ sock_accept_nonblock(VALUE sock) * * Socket#accept */ static VALUE -sock_sysaccept(VALUE sock) +sock_sysaccept(VALUE server) { - rb_io_t *fptr; - VALUE sock2; - union_sockaddr buf; - socklen_t len = (socklen_t)sizeof buf; + union_sockaddr buffer; + socklen_t length = (socklen_t)sizeof(buffer); - GetOpenFile(sock, fptr); - sock2 = rsock_s_accept(0,fptr->fd,&buf.addr,&len); + VALUE peer = rsock_s_accept(0, server, &buffer.addr, &length); - return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); + return rb_assoc_new(peer, rsock_io_socket_addrinfo(peer, &buffer.addr, length)); } #ifdef HAVE_GETHOSTNAME @@ -1034,7 +853,6 @@ sock_gethostname(VALUE obj) long len = RUBY_MAX_HOST_NAME_LEN; VALUE name; - rb_secure(3); name = rb_str_new(0, len); while (gethostname(RSTRING_PTR(name), len) < 0) { int e = errno; @@ -1064,7 +882,6 @@ sock_gethostname(VALUE obj) { struct utsname un; - rb_secure(3); uname(&un); return rb_str_new2(un.nodename); } @@ -1086,7 +903,7 @@ make_addrinfo(struct rb_addrinfo *res0, int norevlookup) for (res = res0->ai; res; res = res->ai_next) { ary = rsock_ipaddr(res->ai_addr, res->ai_addrlen, norevlookup); if (res->ai_canonname) { - RARRAY_PTR(ary)[2] = rb_str_new2(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)); @@ -1123,7 +940,18 @@ sock_sockaddr(struct sockaddr *addr, socklen_t len) * call-seq: * Socket.gethostbyname(hostname) => [official_hostname, alias_hostnames, address_family, *address_list] * - * Obtains the host information for _hostname_. + * Use Addrinfo.getaddrinfo instead. + * This method is deprecated for the following reasons: + * + * - The 3rd element of the result is the address family of the first address. + * The address families of the rest of the addresses are not returned. + * - Uncommon address representation: + * 4/16-bytes binary string to represent IPv4/IPv6 address. + * - gethostbyname() may take a long time and it may block other threads. + * (GVL cannot be released since gethostbyname() is not thread safe.) + * - This method uses gethostbyname() function already removed from POSIX. + * + * This method obtains the host information for _hostname_. * * p Socket.gethostbyname("hal") #=> ["localhost", ["hal"], 2, "\x7F\x00\x00\x01"] * @@ -1131,21 +959,39 @@ sock_sockaddr(struct sockaddr *addr, socklen_t len) static VALUE sock_s_gethostbyname(VALUE obj, VALUE host) { - rb_secure(3); - return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr); + rb_warn("Socket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead."); + struct rb_addrinfo *res = + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + return rsock_make_hostent(host, res, sock_sockaddr); } /* * call-seq: * Socket.gethostbyaddr(address_string [, address_family]) => hostent * - * Obtains the host information for _address_. + * Use Addrinfo#getnameinfo instead. + * This method is deprecated for the following reasons: + * + * - Uncommon address representation: + * 4/16-bytes binary string to represent IPv4/IPv6 address. + * - gethostbyaddr() may take a long time and it may block other threads. + * (GVL cannot be released since gethostbyname() is not thread safe.) + * - This method uses gethostbyname() function already removed from POSIX. + * + * This method obtains the host information for _address_. * * p Socket.gethostbyaddr([221,186,184,68].pack("CCCC")) * #=> ["carbon.ruby-lang.org", [], 2, "\xDD\xBA\xB8D"] + * + * p Socket.gethostbyaddr([127,0,0,1].pack("CCCC")) + * ["localhost", [], 2, "\x7F\x00\x00\x01"] + * p Socket.gethostbyaddr(([0]*15+[1]).pack("C"*16)) + * #=> ["localhost", ["ip6-localhost", "ip6-loopback"], 10, + * "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"] + * */ static VALUE -sock_s_gethostbyaddr(int argc, VALUE *argv) +sock_s_gethostbyaddr(int argc, VALUE *argv, VALUE _) { VALUE addr, family; struct hostent *h; @@ -1153,6 +999,8 @@ sock_s_gethostbyaddr(int argc, VALUE *argv) VALUE ary, names; int t = AF_INET; + rb_warn("Socket.gethostbyaddr is deprecated; use Addrinfo#getnameinfo instead."); + rb_scan_args(argc, argv, "11", &addr, &family); StringValue(addr); if (!NIL_P(family)) { @@ -1207,7 +1055,7 @@ sock_s_gethostbyaddr(int argc, VALUE *argv) * Socket.getservbyname("syslog", "udp") #=> 514 */ static VALUE -sock_s_getservbyname(int argc, VALUE *argv) +sock_s_getservbyname(int argc, VALUE *argv, VALUE _) { VALUE service, proto; struct servent *sp; @@ -1248,7 +1096,7 @@ sock_s_getservbyname(int argc, VALUE *argv) * */ static VALUE -sock_s_getservbyport(int argc, VALUE *argv) +sock_s_getservbyport(int argc, VALUE *argv, VALUE _) { VALUE port, proto; struct servent *sp; @@ -1267,7 +1115,7 @@ sock_s_getservbyport(int argc, VALUE *argv) if (!sp) { rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname); } - return rb_tainted_str_new2(sp->s_name); + return rb_str_new2(sp->s_name); } /* @@ -1276,7 +1124,10 @@ sock_s_getservbyport(int argc, VALUE *argv) * * Obtains address information for _nodename_:_servname_. * - * _family_ should be an address family such as: :INET, :INET6, :UNIX, etc. + * Note that Addrinfo.getaddrinfo provides the same functionality in + * an object oriented style. + * + * _family_ should be an address family such as: :INET, :INET6, etc. * * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc. * @@ -1297,13 +1148,13 @@ sock_s_getservbyport(int argc, VALUE *argv) * be one of below. If _reverse_lookup_ is omitted, the default value is +nil+. * * +true+, +:hostname+: hostname is obtained from numeric address using reverse lookup, which may take a time. - * +false+, +:numeric+: hostname is same as numeric address. + * +false+, +:numeric+: hostname is the same as numeric address. * +nil+: obey to the current +do_not_reverse_lookup+ flag. * * If Addrinfo object is preferred, use Addrinfo.getaddrinfo. */ static VALUE -sock_s_getaddrinfo(int argc, VALUE *argv) +sock_s_getaddrinfo(int argc, VALUE *argv, VALUE _) { VALUE host, port, family, socktype, protocol, flags, ret, revlookup; struct addrinfo hints; @@ -1327,6 +1178,7 @@ sock_s_getaddrinfo(int argc, VALUE *argv) if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) { norevlookup = rsock_do_not_reverse_lookup; } + res = rsock_getaddrinfo(host, port, &hints, 0); ret = make_addrinfo(res, norevlookup); @@ -1357,10 +1209,9 @@ sock_s_getaddrinfo(int argc, VALUE *argv) * If Addrinfo object is preferred, use Addrinfo#getnameinfo. */ static VALUE -sock_s_getnameinfo(int argc, VALUE *argv) +sock_s_getnameinfo(int argc, VALUE *argv, VALUE _) { VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags, tmp; - char *hptr, *pptr; char hbuf[1024], pbuf[1024]; int fl; struct rb_addrinfo *res = NULL; @@ -1396,16 +1247,16 @@ sock_s_getnameinfo(int argc, VALUE *argv) sa = tmp; MEMZERO(&hints, struct addrinfo, 1); if (RARRAY_LEN(sa) == 3) { - af = RARRAY_PTR(sa)[0]; - port = RARRAY_PTR(sa)[1]; - host = RARRAY_PTR(sa)[2]; + af = RARRAY_AREF(sa, 0); + port = RARRAY_AREF(sa, 1); + host = RARRAY_AREF(sa, 2); } else if (RARRAY_LEN(sa) >= 4) { - af = RARRAY_PTR(sa)[0]; - port = RARRAY_PTR(sa)[1]; - host = RARRAY_PTR(sa)[3]; + af = RARRAY_AREF(sa, 0); + port = RARRAY_AREF(sa, 1); + host = RARRAY_AREF(sa, 3); if (NIL_P(host)) { - host = RARRAY_PTR(sa)[2]; + host = RARRAY_AREF(sa, 2); } else { /* @@ -1421,34 +1272,10 @@ sock_s_getnameinfo(int argc, VALUE *argv) rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given", RARRAY_LEN(sa)); } - /* host */ - if (NIL_P(host)) { - hptr = NULL; - } - else { - strncpy(hbuf, StringValuePtr(host), sizeof(hbuf)); - hbuf[sizeof(hbuf) - 1] = '\0'; - hptr = hbuf; - } - /* port */ - if (NIL_P(port)) { - strcpy(pbuf, "0"); - pptr = NULL; - } - else if (FIXNUM_P(port)) { - snprintf(pbuf, sizeof(pbuf), "%ld", NUM2LONG(port)); - pptr = pbuf; - } - else { - strncpy(pbuf, StringValuePtr(port), sizeof(pbuf)); - pbuf[sizeof(pbuf) - 1] = '\0'; - pptr = pbuf; - } hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM; /* af */ hints.ai_family = NIL_P(af) ? PF_UNSPEC : rsock_family_arg(af); - error = rb_getaddrinfo(hptr, pptr, &hints, &res); - if (error) goto error_exit_addr; + res = rsock_getaddrinfo(host, port, &hints, 0); sap = res->ai->ai_addr; salen = res->ai->ai_addrlen; } @@ -1478,19 +1305,13 @@ sock_s_getnameinfo(int argc, VALUE *argv) } return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf)); - error_exit_addr: - saved_errno = errno; - if (res) rb_freeaddrinfo(res); - errno = saved_errno; - rsock_raise_socket_error("getaddrinfo", error); - error_exit_name: saved_errno = errno; if (res) rb_freeaddrinfo(res); errno = saved_errno; rsock_raise_socket_error("getnameinfo", error); - UNREACHABLE; + UNREACHABLE_RETURN(Qnil); } /* @@ -1510,12 +1331,10 @@ sock_s_getnameinfo(int argc, VALUE *argv) static VALUE sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host) { - struct rb_addrinfo *res = rsock_addrinfo(host, port, 0, 0); + struct rb_addrinfo *res = rsock_addrinfo(host, port, AF_UNSPEC, 0, 0); VALUE addr = rb_str_new((char*)res->ai->ai_addr, res->ai->ai_addrlen); rb_freeaddrinfo(res); - OBJ_INFECT(addr, port); - OBJ_INFECT(addr, host); return addr; } @@ -1557,7 +1376,6 @@ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr) #endif } host = rsock_make_ipaddr((struct sockaddr*)sockaddr, RSTRING_SOCKLEN(addr)); - OBJ_INFECT(host, addr); return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host); } @@ -1587,7 +1405,6 @@ sock_s_pack_sockaddr_un(VALUE self, VALUE path) } memcpy(sockaddr.sun_path, RSTRING_PTR(path), RSTRING_LEN(path)); addr = rb_str_new((char*)&sockaddr, rsock_unix_sockaddr_len(path)); - OBJ_INFECT(addr, path); return addr; } @@ -1624,7 +1441,6 @@ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr) RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un)); } path = rsock_unixpath_str(sockaddr, RSTRING_SOCKLEN(addr)); - OBJ_INFECT(path, addr); return path; } #endif @@ -1781,7 +1597,7 @@ socket_s_ip_address_list(VALUE self) int ret; struct lifnum ln; struct lifconf lc; - char *reason = NULL; + const char *reason = NULL; int save_errno; int i; VALUE list = Qnil; @@ -1842,7 +1658,7 @@ socket_s_ip_address_list(VALUE self) errno = save_errno; if (reason) - rb_sys_fail(reason); + rb_syserr_fail(save_errno, reason); return list; #elif defined(SIOCGIFCONF) @@ -1927,7 +1743,7 @@ socket_s_ip_address_list(VALUE self) errno = save_errno; if (reason) - rb_sys_fail(reason); + rb_syserr_fail(save_errno, reason); return list; #undef EXTRA_SPACE @@ -2041,6 +1857,8 @@ socket_s_ip_address_list(VALUE self) void Init_socket(void) { + rb_ext_ractor_safe(true); + rsock_init_basicsocket(); /* @@ -2094,6 +1912,8 @@ Init_socket(void) * * Let's create an internet socket using the IPv4 protocol in a C-like manner: * + * require 'socket' + * * s = Socket.new Socket::AF_INET, Socket::SOCK_STREAM * s.connect Socket.pack_sockaddr_in(80, 'example.com') * @@ -2164,15 +1984,26 @@ Init_socket(void) rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); rb_define_method(rb_cSocket, "connect", sock_connect, 1); - rb_define_method(rb_cSocket, "connect_nonblock", sock_connect_nonblock, 1); + + /* for ext/socket/lib/socket.rb use only: */ + rb_define_private_method(rb_cSocket, + "__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); rb_define_method(rb_cSocket, "accept", sock_accept, 0); - rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, 0); + + /* for ext/socket/lib/socket.rb use only: */ + rb_define_private_method(rb_cSocket, + "__accept_nonblock", sock_accept_nonblock, 1); + rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0); rb_define_method(rb_cSocket, "recvfrom", sock_recvfrom, -1); - rb_define_method(rb_cSocket, "recvfrom_nonblock", sock_recvfrom_nonblock, -1); + + /* for ext/socket/lib/socket.rb use only: */ + rb_define_private_method(rb_cSocket, + "__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); @@ -2193,4 +2024,7 @@ Init_socket(void) #endif rb_define_singleton_method(rb_cSocket, "ip_address_list", socket_s_ip_address_list, 0); + +#undef rb_intern + sym_wait_writable = ID2SYM(rb_intern("wait_writable")); } diff --git a/ext/socket/sockssocket.c b/ext/socket/sockssocket.c index 81f77a67c5..b8b7e12998 100644 --- a/ext/socket/sockssocket.c +++ b/ext/socket/sockssocket.c @@ -13,13 +13,19 @@ #ifdef SOCKS /* * call-seq: - * SOCKSSocket.new(host, serv) => socket + * SOCKSSocket.new(host, port) => socket * - * Opens a SOCKS connection to +host+ via the SOCKS server +serv+. + * Opens a SOCKS connection to +host+ via the SOCKS server. + * + * The SOCKS server configuration varies by implementation + * + * When using the Dante libsocks/libsocksd implementation it is configured as SOCKS_SERVER env var. + * + * See: https://manpages.debian.org/testing/dante-client/socksify.1.en.html for full env variable support. * */ static VALUE -socks_init(VALUE sock, VALUE host, VALUE serv) +socks_init(VALUE sock, VALUE host, VALUE port) { static int init = 0; @@ -28,7 +34,7 @@ socks_init(VALUE sock, VALUE host, VALUE serv) init = 1; } - return rsock_init_inetsock(sock, host, serv, Qnil, Qnil, INET_SOCKS); + return rsock_init_inetsock(sock, host, port, Qnil, Qnil, INET_SOCKS, Qnil, Qnil); } #ifdef SOCKS5 diff --git a/ext/socket/tcpserver.c b/ext/socket/tcpserver.c index 2245a0600d..675733c6f9 100644 --- a/ext/socket/tcpserver.c +++ b/ext/socket/tcpserver.c @@ -36,7 +36,7 @@ tcp_svr_init(int argc, VALUE *argv, VALUE sock) VALUE hostname, port; rb_scan_args(argc, argv, "011", &hostname, &port); - return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER); + return rsock_init_inetsock(sock, hostname, port, Qnil, Qnil, INET_SERVER, Qnil, Qnil); } /* @@ -53,60 +53,24 @@ tcp_svr_init(int argc, VALUE *argv, VALUE sock) * */ static VALUE -tcp_accept(VALUE sock) +tcp_accept(VALUE server) { - rb_io_t *fptr; - union_sockaddr from; - socklen_t fromlen; + union_sockaddr buffer; + socklen_t length = sizeof(buffer); - GetOpenFile(sock, fptr); - fromlen = (socklen_t)sizeof(from); - return rsock_s_accept(rb_cTCPSocket, fptr->fd, &from.addr, &fromlen); + return rsock_s_accept(rb_cTCPSocket, server, &buffer.addr, &length); } -/* - * call-seq: - * tcpserver.accept_nonblock => tcpsocket - * - * Accepts an incoming connection using accept(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * It returns an accepted TCPSocket for the incoming connection. - * - * === Example - * require 'socket' - * serv = TCPServer.new(2202) - * begin # emulate blocking accept - * sock = serv.accept_nonblock - * rescue IO::WaitReadable, Errno::EINTR - * IO.select([serv]) - * retry - * end - * # sock is an accepted socket. - * - * Refer to Socket#accept for the exceptions that may be thrown if the call - * to TCPServer#accept_nonblock fails. - * - * TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED, Errno::EPROTO, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. - * - * === See - * * TCPServer#accept - * * Socket#accept - */ +/* :nodoc: */ static VALUE -tcp_accept_nonblock(VALUE sock) +tcp_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; union_sockaddr from; - socklen_t fromlen; + socklen_t len = (socklen_t)sizeof(from); GetOpenFile(sock, fptr); - fromlen = (socklen_t)sizeof(from); - return rsock_s_accept_nonblock(rb_cTCPSocket, fptr, &from.addr, &fromlen); + return rsock_s_accept_nonblock(rb_cTCPSocket, ex, fptr, &from.addr, &len); } /* @@ -124,15 +88,12 @@ tcp_accept_nonblock(VALUE sock) * */ static VALUE -tcp_sysaccept(VALUE sock) +tcp_sysaccept(VALUE server) { - rb_io_t *fptr; - union_sockaddr from; - socklen_t fromlen; + union_sockaddr buffer; + socklen_t length = sizeof(buffer); - GetOpenFile(sock, fptr); - fromlen = (socklen_t)sizeof(from); - return rsock_s_accept(0, fptr->fd, &from.addr, &fromlen); + return rsock_s_accept(0, server, &buffer.addr, &length); } void @@ -171,7 +132,8 @@ rsock_init_tcpserver(void) */ rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket); rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0); - rb_define_method(rb_cTCPServer, "accept_nonblock", tcp_accept_nonblock, 0); + rb_define_private_method(rb_cTCPServer, + "__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 6217e424d9..51e77a0de9 100644 --- a/ext/socket/tcpsocket.c +++ b/ext/socket/tcpsocket.c @@ -12,23 +12,42 @@ /* * call-seq: - * TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil) + * TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil, connect_timeout: nil) * * Opens a TCP connection to +remote_host+ on +remote_port+. If +local_host+ * and +local_port+ are specified, then those parameters are used on the local * end to establish the connection. + * + * [:connect_timeout] specify the timeout in seconds. */ static VALUE tcp_init(int argc, VALUE *argv, VALUE sock) { VALUE remote_host, remote_serv; VALUE local_host, local_serv; + VALUE opt; + static ID keyword_ids[2]; + VALUE kwargs[2]; + VALUE resolv_timeout = Qnil; + VALUE connect_timeout = Qnil; + + if (!keyword_ids[0]) { + 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); - rb_scan_args(argc, argv, "22", &remote_host, &remote_serv, - &local_host, &local_serv); + 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]; } + } return rsock_init_inetsock(sock, remote_host, remote_serv, - local_host, local_serv, INET_CLIENT); + local_host, local_serv, INET_CLIENT, + resolv_timeout, connect_timeout); } static VALUE @@ -41,7 +60,16 @@ tcp_sockaddr(struct sockaddr *addr, socklen_t len) * call-seq: * TCPSocket.gethostbyname(hostname) => [official_hostname, alias_hostnames, address_family, *address_list] * - * Lookups host information by _hostname_. + * Use Addrinfo.getaddrinfo instead. + * This method is deprecated for the following reasons: + * + * - The 3rd element of the result is the address family of the first address. + * The address families of the rest of the addresses are not returned. + * - gethostbyname() may take a long time and it may block other threads. + * (GVL cannot be released since gethostbyname() is not thread safe.) + * - This method uses gethostbyname() function already removed from POSIX. + * + * This method lookups host information by _hostname_. * * TCPSocket.gethostbyname("localhost") * #=> ["localhost", ["hal"], 2, "127.0.0.1"] @@ -50,9 +78,10 @@ tcp_sockaddr(struct sockaddr *addr, socklen_t len) static VALUE tcp_s_gethostbyname(VALUE obj, VALUE host) { - rb_secure(3); - return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), - tcp_sockaddr); + rb_warn("TCPSocket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead."); + struct rb_addrinfo *res = + rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME); + return rsock_make_hostent(host, res, tcp_sockaddr); } void diff --git a/ext/socket/udpsocket.c b/ext/socket/udpsocket.c index eb605cafc1..2bfd7c8560 100644 --- a/ext/socket/udpsocket.c +++ b/ext/socket/udpsocket.c @@ -19,6 +19,8 @@ * _address_family_ should be an integer, a string or a symbol: * Socket::AF_INET, "AF_INET", :INET, etc. * + * require 'socket' + * * UDPSocket.new #=> #<UDPSocket:fd 3> * UDPSocket.new(Socket::AF_INET6) #=> #<UDPSocket:fd 4> * @@ -30,7 +32,6 @@ udp_init(int argc, VALUE *argv, VALUE sock) int family = AF_INET; int fd; - rb_secure(3); if (rb_scan_args(argc, argv, "01", &arg) == 1) { family = rsock_family_arg(arg); } @@ -45,17 +46,21 @@ udp_init(int argc, VALUE *argv, VALUE sock) struct udp_arg { struct rb_addrinfo *res; - int fd; + rb_io_t *fptr; }; static VALUE -udp_connect_internal(struct udp_arg *arg) +udp_connect_internal(VALUE v) { - int fd = arg->fd; + struct udp_arg *arg = (void *)v; + rb_io_t *fptr; + int fd; struct addrinfo *res; + 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) >= 0) { + if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0, NULL) >= 0) { return Qtrue; } } @@ -81,20 +86,36 @@ udp_connect_internal(struct udp_arg *arg) static VALUE udp_connect(VALUE sock, VALUE host, VALUE port) { - rb_io_t *fptr; struct udp_arg arg; VALUE ret; - rb_secure(3); - arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0); - GetOpenFile(sock, fptr); - arg.fd = fptr->fd; + 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); if (!ret) rsock_sys_fail_host_port("connect(2)", host, port); return INT2FIX(0); } +static VALUE +udp_bind_internal(VALUE v) +{ + struct udp_arg *arg = (void *)v; + rb_io_t *fptr; + int fd; + struct addrinfo *res; + + 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; + } + return Qfalse; +} + /* * call-seq: * udpsocket.bind(host, port) #=> 0 @@ -110,25 +131,50 @@ udp_connect(VALUE sock, VALUE host, VALUE port) static VALUE udp_bind(VALUE sock, VALUE host, VALUE port) { + struct udp_arg arg; + VALUE ret; + + 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); + if (!ret) rsock_sys_fail_host_port("bind(2)", host, port); + return INT2FIX(0); +} + +struct udp_send_arg { + struct rb_addrinfo *res; + rb_io_t *fptr; + struct rsock_send_arg sarg; +}; + +static VALUE +udp_send_internal(VALUE v) +{ + struct udp_send_arg *arg = (void *)v; rb_io_t *fptr; - struct rb_addrinfo *res0; struct addrinfo *res; - rb_secure(3); - res0 = rsock_addrinfo(host, port, SOCK_DGRAM, 0); - GetOpenFile(sock, fptr); - for (res = res0->ai; res; res = res->ai_next) { - if (bind(fptr->fd, res->ai_addr, res->ai_addrlen) < 0) { - continue; - } - rb_freeaddrinfo(res0); - return INT2FIX(0); - } - rb_freeaddrinfo(res0); + rb_io_check_closed(fptr = arg->fptr); + for (res = arg->res->ai; res; res = res->ai_next) { + retry: + arg->sarg.fd = fptr->fd; + arg->sarg.to = res->ai_addr; + arg->sarg.tolen = res->ai_addrlen; - rsock_sys_fail_host_port("bind(2)", host, port); +#ifdef RSOCK_WAIT_BEFORE_BLOCKING + rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_WRITABLE), Qnil); +#endif - return INT2FIX(0); + ssize_t n = (ssize_t)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg->sarg); + + if (n >= 0) return RB_SSIZE2NUM(n); + + if (rb_io_maybe_wait_writable(errno, fptr->self, Qnil)) { + goto retry; + } + } + return Qfalse; } /* @@ -157,94 +203,30 @@ static VALUE udp_send(int argc, VALUE *argv, VALUE sock) { VALUE flags, host, port; - rb_io_t *fptr; - int n; - struct rb_addrinfo *res0; - struct addrinfo *res; - struct rsock_send_arg arg; + struct udp_send_arg arg; + VALUE ret; if (argc == 2 || argc == 3) { return rsock_bsock_send(argc, argv, sock); } - rb_scan_args(argc, argv, "4", &arg.mesg, &flags, &host, &port); - - StringValue(arg.mesg); - res0 = rsock_addrinfo(host, port, SOCK_DGRAM, 0); - GetOpenFile(sock, fptr); - arg.fd = fptr->fd; - arg.flags = NUM2INT(flags); - for (res = res0->ai; res; res = res->ai_next) { - retry: - arg.to = res->ai_addr; - arg.tolen = res->ai_addrlen; - rsock_maybe_fd_writable(arg.fd); - n = (int)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg); - if (n >= 0) { - rb_freeaddrinfo(res0); - return INT2FIX(n); - } - if (rb_io_wait_writable(fptr->fd)) { - goto retry; - } - } - rb_freeaddrinfo(res0); - rsock_sys_fail_host_port("sendto(2)", host, port); - return INT2FIX(n); + rb_scan_args(argc, argv, "4", &arg.sarg.mesg, &flags, &host, &port); + + StringValue(arg.sarg.mesg); + GetOpenFile(sock, arg.fptr); + arg.sarg.fd = arg.fptr->fd; + 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); + if (!ret) rsock_sys_fail_host_port("sendto(2)", host, port); + return ret; } -/* - * call-seq: - * udpsocket.recvfrom_nonblock(maxlen) => [mesg, sender_inet_addr] - * udpsocket.recvfrom_nonblock(maxlen, flags) => [mesg, sender_inet_addr] - * - * Receives up to _maxlen_ bytes from +udpsocket+ using recvfrom(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * If _maxlen_ is omitted, its default value is 65536. - * _flags_ is zero or more of the +MSG_+ options. - * 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. - * - * === Parameters - * * +maxlen+ - the number of bytes to receive from the socket - * * +flags+ - zero or more of the +MSG_+ options - * - * === Example - * require 'socket' - * s1 = UDPSocket.new - * s1.bind("127.0.0.1", 0) - * s2 = UDPSocket.new - * s2.bind("127.0.0.1", 0) - * s2.connect(*s1.addr.values_at(3,1)) - * s1.connect(*s2.addr.values_at(3,1)) - * s1.send "aaa", 0 - * begin # emulate blocking recvfrom - * p s2.recvfrom_nonblock(10) #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]] - * rescue IO::WaitReadable - * IO.select([s2]) - * retry - * end - * - * Refer to Socket#recvfrom for the exceptions that may be thrown if the call - * to _recvfrom_nonblock_ fails. - * - * UDPSocket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock. - * - * === See - * * Socket#recvfrom - */ +/* :nodoc: */ static VALUE -udp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock) +udp_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex) { - return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_IP); + return rsock_s_recvfrom_nonblock(sock, len, flg, str, ex, RECV_IP); } void @@ -261,6 +243,8 @@ rsock_init_udpsocket(void) rb_define_method(rb_cUDPSocket, "connect", udp_connect, 2); rb_define_method(rb_cUDPSocket, "bind", udp_bind, 2); rb_define_method(rb_cUDPSocket, "send", udp_send, -1); - rb_define_method(rb_cUDPSocket, "recvfrom_nonblock", udp_recvfrom_nonblock, -1); -} + /* for ext/socket/lib/socket.rb use only: */ + rb_define_private_method(rb_cUDPSocket, + "__recvfrom_nonblock", udp_recvfrom_nonblock, 4); +} diff --git a/ext/socket/unixserver.c b/ext/socket/unixserver.c index df9849703b..890f9d3fae 100644 --- a/ext/socket/unixserver.c +++ b/ext/socket/unixserver.c @@ -17,6 +17,8 @@ * * Creates a new UNIX server socket bound to _path_. * + * require 'socket' + * * serv = UNIXServer.new("/tmp/sock") * s = serv.accept * p s.read @@ -45,53 +47,17 @@ unix_svr_init(VALUE sock, VALUE path) * */ static VALUE -unix_accept(VALUE sock) +unix_accept(VALUE server) { - rb_io_t *fptr; - struct sockaddr_un from; - socklen_t fromlen; + struct sockaddr_un buffer; + socklen_t length = sizeof(buffer); - GetOpenFile(sock, fptr); - fromlen = (socklen_t)sizeof(struct sockaddr_un); - return rsock_s_accept(rb_cUNIXSocket, fptr->fd, - (struct sockaddr*)&from, &fromlen); + return rsock_s_accept(rb_cUNIXSocket, server, (struct sockaddr*)&buffer, &length); } -/* - * call-seq: - * unixserver.accept_nonblock => unixsocket - * - * Accepts an incoming connection using accept(2) after - * O_NONBLOCK is set for the underlying file descriptor. - * It returns an accepted UNIXSocket for the incoming connection. - * - * === Example - * require 'socket' - * serv = UNIXServer.new("/tmp/sock") - * begin # emulate blocking accept - * sock = serv.accept_nonblock - * rescue IO::WaitReadable, Errno::EINTR - * IO.select([serv]) - * retry - * end - * # sock is an accepted socket. - * - * Refer to Socket#accept for the exceptions that may be thrown if the call - * to UNIXServer#accept_nonblock fails. - * - * UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure, - * including Errno::EWOULDBLOCK. - * - * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO, - * it is extended by IO::WaitReadable. - * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock. - * - * === See - * * UNIXServer#accept - * * Socket#accept - */ +/* :nodoc: */ static VALUE -unix_accept_nonblock(VALUE sock) +unix_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; struct sockaddr_un from; @@ -99,7 +65,7 @@ unix_accept_nonblock(VALUE sock) GetOpenFile(sock, fptr); fromlen = (socklen_t)sizeof(from); - return rsock_s_accept_nonblock(rb_cUNIXSocket, fptr, + return rsock_s_accept_nonblock(rb_cUNIXSocket, ex, fptr, (struct sockaddr *)&from, &fromlen); } @@ -122,15 +88,12 @@ unix_accept_nonblock(VALUE sock) * */ static VALUE -unix_sysaccept(VALUE sock) +unix_sysaccept(VALUE server) { - rb_io_t *fptr; - struct sockaddr_un from; - socklen_t fromlen; + struct sockaddr_un buffer; + socklen_t length = sizeof(buffer); - GetOpenFile(sock, fptr); - fromlen = (socklen_t)sizeof(struct sockaddr_un); - return rsock_s_accept(0, fptr->fd, (struct sockaddr*)&from, &fromlen); + return rsock_s_accept(0, server, (struct sockaddr*)&buffer, &length); } #endif @@ -148,7 +111,10 @@ rsock_init_unixserver(void) rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1); rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); - rb_define_method(rb_cUNIXServer, "accept_nonblock", unix_accept_nonblock, 0); + + rb_define_private_method(rb_cUNIXServer, + "__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 */ #endif diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c index 9a4c2cfc01..857cfa6002 100644 --- a/ext/socket/unixsocket.c +++ b/ext/socket/unixsocket.c @@ -22,7 +22,28 @@ 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); + arg->sockaddrlen, 0, NULL); +} + +static VALUE +unixsock_path_value(VALUE path) +{ +#ifdef __linux__ +#define TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE 0 + + VALUE name = path; +#if TO_STR_FOR_LINUX_ABSTRACT_NAMESPACE + const int isstr = !NIL_P(name = rb_check_string_type(name)); +#else + const int isstr = RB_TYPE_P(name, T_STRING); +#endif + if (isstr) { + if (RSTRING_LEN(name) == 0 || RSTRING_PTR(name)[0] == '\0') { + return name; /* ignore encoding */ + } + } +#endif + return rb_get_path(path); } VALUE @@ -33,7 +54,7 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) int fd, status; rb_io_t *fptr; - SafeStringValue(path); + path = unixsock_path_value(path); INIT_SOCKADDR_UN(&sockaddr, sizeof(struct sockaddr_un)); if (sizeof(sockaddr.sun_path) < (size_t)RSTRING_LEN(path)) { @@ -65,14 +86,16 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) } if (status < 0) { + int e = errno; close(fd); - rsock_sys_fail_path("connect(2)", path); + rsock_syserr_fail_path(e, "connect(2)", path); } if (server) { if (listen(fd, SOMAXCONN) < 0) { + int e = errno; close(fd); - rsock_sys_fail_path("listen(2)", path); + rsock_syserr_fail_path(e, "listen(2)", path); } } @@ -91,6 +114,8 @@ rsock_init_unixsock(VALUE sock, VALUE path, int server) * * Creates a new UNIX client socket connected to _path_. * + * require 'socket' + * * s = UNIXSocket.new("/tmp/sock") * s.send "hello", 0 * @@ -131,7 +156,7 @@ unix_path(VALUE sock) /* * call-seq: - * unixsocket.recvfrom(maxlen [, flags]) => [mesg, unixaddress] + * unixsocket.recvfrom(maxlen [, flags[, outbuf]]) => [mesg, unixaddress] * * Receives a message via _unixsocket_. * @@ -139,6 +164,9 @@ unix_path(VALUE sock) * * _flags_ should be a bitwise OR of Socket::MSG_* constants. * + * _outbuf_ will contain only the received data after the method call + * even if it is not empty at the beginning. + * * s1 = Socket.new(:UNIX, :DGRAM, 0) * s1_ai = Addrinfo.unix("/tmp/sock1") * s1.bind(s1_ai) @@ -198,6 +226,8 @@ sendmsg_blocking(void *data) * p stdout.fileno #=> 6 * * stdout.puts "hello" # outputs "hello\n" to standard output. + * + * _io_ may be any kind of IO object or integer file descriptor. */ static VALUE unix_send_io(VALUE sock, VALUE val) @@ -294,6 +324,11 @@ recvmsg_blocking(void *data) * } * } * + * _klass_ will determine the class of _io_ returned (using the + * IO.for_fd singleton method or similar). + * If _klass_ is +nil+, an integer file descriptor is returned. + * + * _mode_ is the same as the argument passed to IO.for_fd */ static VALUE unix_recv_io(int argc, VALUE *argv, VALUE sock) @@ -303,6 +338,12 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) struct iomsg_arg arg; struct iovec vec[2]; char buf[1]; + unsigned int gc_reason = 0; + enum { + GC_REASON_EMSGSIZE = 0x1, + GC_REASON_TRUNCATE = 0x2, + GC_REASON_ENOMEM = 0x4 + }; int fd; #if FD_PASSING_BY_MSG_CONTROL @@ -318,6 +359,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) if (argc <= 1) mode = Qnil; +retry: GetOpenFile(sock, fptr); arg.msg.msg_name = NULL; @@ -345,12 +387,31 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) arg.fd = fptr->fd; while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) { + int e = errno; + if (e == EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) { + /* FreeBSD gets here when we're out of FDs */ + gc_reason |= GC_REASON_EMSGSIZE; + rb_gc_for_fd(EMFILE); + goto retry; + } + else if (e == ENOMEM && !(gc_reason & GC_REASON_ENOMEM)) { + /* ENOMEM is documented in recvmsg manpages */ + gc_reason |= GC_REASON_ENOMEM; + rb_gc_for_fd(e); + goto retry; + } if (!rb_io_wait_readable(arg.fd)) - rsock_sys_fail_path("recvmsg(2)", fptr->pathv); + rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv); } #if FD_PASSING_BY_MSG_CONTROL if (arg.msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr)) { + /* FreeBSD and Linux both get here when we're out of FDs */ + if (!(gc_reason & GC_REASON_TRUNCATE)) { + gc_reason |= GC_REASON_TRUNCATE; + 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)); @@ -394,11 +455,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) #endif rb_update_max_fd(fd); - - if (rsock_cmsg_cloexec_state < 0) - rsock_cmsg_cloexec_state = rsock_detect_cloexec(fd); - if (rsock_cmsg_cloexec_state == 0 || fd <= 2) - rb_maygvl_fd_fix_cloexec(fd); + rb_maygvl_fd_fix_cloexec(fd); if (klass == Qnil) return INT2FIX(fd); @@ -410,7 +467,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock) ff_argc = mode == Qnil ? 1 : 2; ff_argv[0] = INT2FIX(fd); ff_argv[1] = mode; - return rb_funcall2(klass, for_fd, ff_argc, ff_argv); + return rb_funcallv(klass, for_fd, ff_argc, ff_argv); } } #else |
