5static VALUE sym_wait_readable, sym_wait_writable;
7#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
8static VALUE rb_cAncillaryData;
11constant_to_sym(
int constant,
ID (*intern_const)(
int))
13 ID name = intern_const(constant);
22ip_cmsg_type_to_sym(
int level,
int cmsg_type)
89ancdata_new(
int family,
int level,
int type,
VALUE data)
98ancillary_family(
VALUE self)
114ancillary_family_m(
VALUE self)
116 return INT2NUM(ancillary_family(self));
120ancillary_level(
VALUE self)
136ancillary_level_m(
VALUE self)
138 return INT2NUM(ancillary_level(self));
142ancillary_type(
VALUE self)
158ancillary_type_m(
VALUE self)
160 return INT2NUM(ancillary_type(self));
173ancillary_data(
VALUE self)
198 for (i = 0 ; i <
argc; i++) {
200 if (!RB_TYPE_P(obj,
T_FILE)) {
208 for (i = 0 ; i <
argc; i++) {
217 result = ancdata_new(AF_UNIX, SOL_SOCKET, SCM_RIGHTS,
str);
222#define ancillary_s_unix_rights rb_f_notimplement
257ancillary_unix_rights(
VALUE self)
261 level = ancillary_level(self);
262 type = ancillary_type(self);
264 if (level != SOL_SOCKET ||
type != SCM_RIGHTS)
270#define ancillary_unix_rights rb_f_notimplement
273#if defined(SCM_TIMESTAMP) || defined(SCM_TIMESTAMPNS) || defined(SCM_BINTIME)
300ancillary_timestamp(
VALUE self)
306 level = ancillary_level(self);
307 type = ancillary_type(self);
308 data = ancillary_data(self);
311 if (level == SOL_SOCKET &&
type == SCM_TIMESTAMP &&
319# ifdef SCM_TIMESTAMPNS
320 if (level == SOL_SOCKET &&
type == SCM_TIMESTAMPNS &&
328#define add(x,y) (rb_funcall((x), '+', 1, (y)))
329#define mul(x,y) (rb_funcall((x), '*', 1, (y)))
330#define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y)))
333 if (level == SOL_SOCKET &&
type == SCM_BINTIME &&
351#define ancillary_timestamp rb_f_notimplement
374 return ancdata_new(family, level,
type,
rb_str_new((
char*)&i,
sizeof(i)));
389ancillary_int(
VALUE self)
393 data = ancillary_data(self);
400#if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
424 VALUE v_addr, v_ifindex, v_spec_dst;
425 unsigned int ifindex;
426 struct sockaddr_in sa;
427 struct in_pktinfo pktinfo;
433 if (
NIL_P(v_spec_dst))
438 memset(&pktinfo, 0,
sizeof(pktinfo));
440 memset(&sa, 0,
sizeof(sa));
444 if (sa.sin_family != AF_INET)
446 memcpy(&pktinfo.ipi_addr, &sa.sin_addr,
sizeof(pktinfo.ipi_addr));
448 pktinfo.ipi_ifindex = ifindex;
450 memset(&sa, 0,
sizeof(sa));
454 if (sa.sin_family != AF_INET)
456 memcpy(&pktinfo.ipi_spec_dst, &sa.sin_addr,
sizeof(pktinfo.ipi_spec_dst));
458 return ancdata_new(AF_INET,
IPPROTO_IP, IP_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
461#define ancillary_s_ip_pktinfo rb_f_notimplement
464#if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
485ancillary_ip_pktinfo(
VALUE self)
489 struct in_pktinfo pktinfo;
490 struct sockaddr_in sa;
491 VALUE v_spec_dst, v_addr;
493 level = ancillary_level(self);
494 type = ancillary_type(self);
495 data = ancillary_data(self);
503 memset(&sa, 0,
sizeof(sa));
505 sa.sin_family = AF_INET;
506 memcpy(&sa.sin_addr, &pktinfo.ipi_addr,
sizeof(sa.sin_addr));
509 sa.sin_family = AF_INET;
510 memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst,
sizeof(sa.sin_addr));
516#define ancillary_ip_pktinfo rb_f_notimplement
519#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
537 unsigned int ifindex;
538 struct sockaddr_in6 sa;
539 struct in6_pktinfo pktinfo;
544 memset(&pktinfo, 0,
sizeof(pktinfo));
546 memset(&sa, 0,
sizeof(sa));
550 if (sa.sin6_family != AF_INET6)
552 memcpy(&pktinfo.ipi6_addr, &sa.sin6_addr,
sizeof(pktinfo.ipi6_addr));
554 pktinfo.ipi6_ifindex = ifindex;
556 return ancdata_new(AF_INET6, IPPROTO_IPV6, IPV6_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
559#define ancillary_s_ipv6_pktinfo rb_f_notimplement
562#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
564extract_ipv6_pktinfo(
VALUE self,
struct in6_pktinfo *pktinfo_ptr,
struct sockaddr_in6 *sa_ptr)
569 level = ancillary_level(self);
570 type = ancillary_type(self);
571 data = ancillary_data(self);
573 if (level != IPPROTO_IPV6 ||
type != IPV6_PKTINFO ||
580 INIT_SOCKADDR((
struct sockaddr *)sa_ptr, AF_INET6,
sizeof(*sa_ptr));
581 memcpy(&sa_ptr->sin6_addr, &pktinfo_ptr->ipi6_addr,
sizeof(sa_ptr->sin6_addr));
582 if (IN6_IS_ADDR_LINKLOCAL(&sa_ptr->sin6_addr))
583 sa_ptr->sin6_scope_id = pktinfo_ptr->ipi6_ifindex;
587#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
603ancillary_ipv6_pktinfo(
VALUE self)
605 struct in6_pktinfo pktinfo;
606 struct sockaddr_in6 sa;
609 extract_ipv6_pktinfo(self, &pktinfo, &sa);
614#define ancillary_ipv6_pktinfo rb_f_notimplement
617#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
633ancillary_ipv6_pktinfo_addr(
VALUE self)
635 struct in6_pktinfo pktinfo;
636 struct sockaddr_in6 sa;
637 extract_ipv6_pktinfo(self, &pktinfo, &sa);
641#define ancillary_ipv6_pktinfo_addr rb_f_notimplement
644#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
660ancillary_ipv6_pktinfo_ifindex(
VALUE self)
662 struct in6_pktinfo pktinfo;
663 struct sockaddr_in6 sa;
664 extract_ipv6_pktinfo(self, &pktinfo, &sa);
665 return UINT2NUM(pktinfo.ipi6_ifindex);
668#define ancillary_ipv6_pktinfo_ifindex rb_f_notimplement
671#if defined(SOL_SOCKET) && defined(SCM_RIGHTS)
673anc_inspect_socket_rights(
int level,
int type,
VALUE data,
VALUE ret)
675 if (level == SOL_SOCKET &&
type == SCM_RIGHTS &&
691#if defined(SCM_CREDENTIALS)
693anc_inspect_passcred_credentials(
int level,
int type,
VALUE data,
VALUE ret)
695 if (level == SOL_SOCKET &&
type == SCM_CREDENTIALS &&
699 rb_str_catf(ret,
" pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
709#if defined(SCM_CREDS)
710#define INSPECT_SCM_CREDS
712anc_inspect_socket_creds(
int level,
int type,
VALUE data,
VALUE ret)
714 if (level != SOL_SOCKET &&
type != SCM_CREDS)
728#if defined(HAVE_TYPE_STRUCT_CMSGCRED)
729 if (
RSTRING_LEN(data) ==
sizeof(
struct cmsgcred)) {
730 struct cmsgcred cred;
736 if (cred.cmcred_ngroups) {
738 const char *sep =
" groups=";
739 for (i = 0; i < cred.cmcred_ngroups; i++) {
740 rb_str_catf(ret,
"%s%u", sep, cred.cmcred_groups[i]);
748#if defined(HAVE_TYPE_STRUCT_SOCKCRED)
749 if ((
size_t)
RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
750 struct sockcred cred0, *cred;
752 if ((
size_t)
RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
753 cred = (
struct sockcred *)
ALLOCA_N(
char, SOCKCREDSIZE(cred0.sc_ngroups));
759 if (cred0.sc_ngroups) {
761 const char *sep =
" groups=";
762 for (i = 0; i < cred0.sc_ngroups; i++) {
776#if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR)
778anc_inspect_ip_recvdstaddr(
int level,
int type,
VALUE data,
VALUE ret)
797#if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
803 struct in_pktinfo pktinfo;
810 if (if_indextoname(pktinfo.ipi_ifindex,
buf) ==
NULL)
811 rb_str_catf(ret,
" ifindex:%d", pktinfo.ipi_ifindex);
826#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO)
828anc_inspect_ipv6_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
830 if (level == IPPROTO_IPV6 &&
type == IPV6_PKTINFO &&
832 struct in6_pktinfo *pktinfo = (
struct in6_pktinfo *)
RSTRING_PTR(data);
833 struct in6_addr addr;
834 unsigned int ifindex;
836 memcpy(&addr, &pktinfo->ipi6_addr,
sizeof(addr));
837 memcpy(&ifindex, &pktinfo->ipi6_ifindex,
sizeof(ifindex));
842 if (if_indextoname(ifindex, ifbuf) ==
NULL)
854#if defined(SCM_TIMESTAMP)
856inspect_timeval_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
865 tm = *localtime(&time);
866 strftime(
buf,
sizeof(
buf),
"%Y-%m-%d %H:%M:%S", &tm);
876#if defined(SCM_TIMESTAMPNS)
878inspect_timespec_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
885 tm = *localtime(&ts.tv_sec);
886 strftime(
buf,
sizeof(
buf),
"%Y-%m-%d %H:%M:%S", &tm);
896#if defined(SCM_BINTIME)
898inspect_bintime_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
909 tm = *localtime(&bt.sec);
910 strftime(
buf,
sizeof(
buf),
"%Y-%m-%d %H:%M:%S", &tm);
914 frac_h = bt.frac >> 32;
915 frac_l = bt.frac & 0xffffffff;
917 scale_h = 0x8ac72304;
918 scale_l = 0x89e80000;
920 res_h = frac_h * scale_h;
921 res_l = frac_l * scale_l;
923 tmp1 = frac_h * scale_l;
926 res_l += tmp1 & 0xffffffff;
927 if (res_l < tmp2) res_h++;
929 tmp1 = frac_l * scale_h;
932 res_l += tmp1 & 0xffffffff;
933 if (res_l < tmp2) res_h++;
954ancillary_inspect(
VALUE self)
957 int family, level,
type;
959 ID family_id, level_id, type_id;
963 family = ancillary_family(self);
964 level = ancillary_level(self);
965 type = ancillary_type(self);
966 data = ancillary_data(self);
976 if (level == SOL_SOCKET) {
992 vtype = ip_cmsg_type_to_sym(level,
type);
1005 if (level == SOL_SOCKET)
1011# if defined(SOL_SOCKET)
1014# if defined(SCM_TIMESTAMP)
1015 case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level,
type, data, ret);
break;
1017# if defined(SCM_TIMESTAMPNS)
1018 case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level,
type, data, ret);
break;
1020# if defined(SCM_BINTIME)
1021 case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level,
type, data, ret);
break;
1023# if defined(SCM_RIGHTS)
1024 case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level,
type, data, ret);
break;
1026# if defined(SCM_CREDENTIALS)
1027 case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level,
type, data, ret);
break;
1029# if defined(INSPECT_SCM_CREDS)
1030 case SCM_CREDS: inspected = anc_inspect_socket_creds(level,
type, data, ret);
break;
1043# if defined(IPPROTO_IP)
1046# if defined(IP_RECVDSTADDR)
1047 case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level,
type, data, ret);
break;
1049# if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
1050 case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level,
type, data, ret);
break;
1056# if defined(IPPROTO_IPV6)
1059# if defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO)
1060 case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level,
type, data, ret);
break;
1094 int family = ancillary_family(self);
1098 if (ancillary_level(self) == level &&
1099 ancillary_type(self) ==
type)
1107#if defined(HAVE_SENDMSG)
1108struct sendmsg_args_struct {
1111 const struct msghdr *msg;
1115nogvl_sendmsg_func(
void *
ptr)
1117 struct sendmsg_args_struct *args =
ptr;
1118 return (
void *)(
VALUE)
sendmsg(args->fd, args->msg, args->flags);
1122rb_sendmsg(
int fd,
const struct msghdr *msg,
int flags)
1124 struct sendmsg_args_struct args;
1141#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1142 VALUE controls_str = 0;
1149#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1156 if (!RB_TYPE_P(controls,
T_ARRAY)) {
1159 controls_num = RARRAY_LENINT(controls);
1162#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1164 size_t last_pad = 0;
1166#if defined(__NetBSD__)
1171 for (i = 0; i < controls_num; i++) {
1172 VALUE elt = controls_ptr[i], v;
1173 VALUE vlevel, vtype;
1201 memset((
char *)cmsg, 0, cspace);
1202 memset((
char *)&cmh, 0,
sizeof(cmh));
1203 cmh.cmsg_level = level;
1204 cmh.cmsg_type =
type;
1206 MEMCPY(cmsg, &cmh,
char,
sizeof(cmh));
1208#if defined(__NetBSD__)
1209 last_level = cmh.cmsg_level;
1210 last_type = cmh.cmsg_type;
1212 last_pad = cspace - cmh.cmsg_len;
1235#if defined(__NetBSD__)
1236 if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS)
1249 flags |= MSG_DONTWAIT;
1252 if (!
NIL_P(dest_sockaddr))
1258 memset(&mh, 0,
sizeof(mh));
1259 if (!
NIL_P(dest_sockaddr)) {
1267#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1278 ss = rb_sendmsg(fptr->
fd, &mh, flags);
1287 if (nonblock && (e ==
EWOULDBLOCK || e == EAGAIN)) {
1289 return sym_wait_writable;
1292 "sendmsg(2) would block");
1296#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1305#if defined(HAVE_SENDMSG)
1310 return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, controls,
1315#if defined(HAVE_SENDMSG)
1320 return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr,
1325#if defined(HAVE_RECVMSG)
1326struct recvmsg_args_struct {
1333rsock_recvmsg(
int socket,
struct msghdr *message,
int flags)
1337#ifdef MSG_CMSG_CLOEXEC
1339 flags |= MSG_CMSG_CLOEXEC;
1342 ret =
recvmsg(socket, message, flags);
1349nogvl_recvmsg_func(
void *
ptr)
1351 struct recvmsg_args_struct *args =
ptr;
1352 int flags = args->flags;
1353 return (
void *)rsock_recvmsg(args->fd, args->msg, flags);
1357rb_recvmsg(
int fd,
struct msghdr *msg,
int flags)
1359 struct recvmsg_args_struct args;
1366#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1368discard_cmsg(
struct cmsghdr *cmh,
char *msg_end,
int msg_peek_p)
1370# if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
1382 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1383 int *fdp = (
int *)CMSG_DATA(cmh);
1384 int *end = (
int *)((
char *)cmh + cmh->cmsg_len);
1385 while ((
char *)fdp +
sizeof(
int) <= (
char *)end &&
1386 (
char *)fdp +
sizeof(
int) <= msg_end) {
1396rsock_discard_cmsg_resource(
struct msghdr *mh,
int msg_peek_p)
1398#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1399 struct cmsghdr *cmh;
1407 for (cmh = CMSG_FIRSTHDR(mh); cmh !=
NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1408 discard_cmsg(cmh, msg_end, msg_peek_p);
1413#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1415make_io_for_unix_rights(
VALUE ctl,
struct cmsghdr *cmh,
char *msg_end)
1417 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1421 fdp = (
int *)CMSG_DATA(cmh);
1422 end = (
int *)((
char *)cmh + cmh->cmsg_len);
1423 while ((
char *)fdp +
sizeof(
int) <= (
char *)end &&
1424 (
char *)fdp +
sizeof(
int) <= msg_end) {
1428 if (
fstat(fd, &stbuf) == -1)
1432 if (S_ISSOCK(stbuf.st_mode))
1446bsock_recvmsg_internal(
VALUE sock,
1453 int flags, orig_flags;
1461 int request_scm_rights;
1462#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1463 struct cmsghdr *cmh;
1472#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1475 if (!
NIL_P(vmaxctllen))
1481 flags |= MSG_DONTWAIT;
1485 grow_buffer =
NIL_P(vmaxdatlen) ||
NIL_P(vmaxctllen);
1487 request_scm_rights = 0;
1488 if (
RTEST(scm_rights))
1489 request_scm_rights = 1;
1490#if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1491 if (request_scm_rights)
1500#if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1504 if (getsockopt(fptr->
fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen) == -1) {
1507 if (socktype == SOCK_STREAM)
1519#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1527 memset(&mh, 0,
sizeof(mh));
1529 memset(&namebuf, 0,
sizeof(namebuf));
1535 iov.iov_base = datbuf;
1536 iov.iov_len = maxdatlen;
1538#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1550 ss = rb_recvmsg(fptr->
fd, &mh, flags);
1559 if (nonblock && (e ==
EWOULDBLOCK || e == EAGAIN)) {
1561 return sym_wait_readable;
1565#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1566 if (!gc_done && (e == EMFILE || e ==
EMSGSIZE)) {
1580 ss = (ssize_t)iov.iov_len;
1588 if (
NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) {
1594#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1596#define BIG_ENOUGH_SPACE 65536
1597 if (BIG_ENOUGH_SPACE < maxctllen &&
1602 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1612#undef BIG_ENOUGH_SPACE
1616 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1621 if (flags != orig_flags) {
1622 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1638#
if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1645#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1649 for (cmh = CMSG_FIRSTHDR(&mh); cmh !=
NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
1653 if (cmh->cmsg_len == 0) {
1656 ctl_end = (
char*)cmh + cmh->cmsg_len;
1657 clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (
char*)CMSG_DATA(cmh);
1658 ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type,
rb_str_new((
char*)CMSG_DATA(cmh), clen));
1659 if (request_scm_rights)
1660 make_io_for_unix_rights(ctl, cmh, msg_end);
1662 discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
1673#if defined(HAVE_RECVMSG)
1679 return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 0);
1683#if defined(HAVE_RECVMSG)
1688 return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 1);
1695#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1704 rb_define_method(rb_cAncillaryData,
"initialize", ancillary_initialize, 4);
1717 rb_define_method(rb_cAncillaryData,
"unix_rights", ancillary_unix_rights, 0);
1722 rb_define_method(rb_cAncillaryData,
"ip_pktinfo", ancillary_ip_pktinfo, 0);
1725 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo", ancillary_ipv6_pktinfo, 0);
1726 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
1727 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
void rsock_init_ancdata(void)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_entry(VALUE ary, long offset)
int rsock_family_arg(VALUE domain)
int rsock_cmsg_type_arg(int family, int level, VALUE type)
int rsock_level_arg(int family, VALUE level)
ID rsock_intern_ipv6_optname(int val)
ID rsock_intern_tcp_optname(int val)
ID rsock_intern_scm_optname(int val)
ID rsock_intern_udp_optname(int val)
ID rsock_intern_iplevel(int val)
ID rsock_intern_ip_optname(int val)
ID rsock_intern_family_noprefix(int val)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
char str[HTML_ESCAPE_MAX_LEN+1]
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_syserr_fail(int e, const char *mesg)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_sys_fail(const char *mesg)
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
Make a hidden object visible again.
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Tries to convert an object into another type.
VALUE rb_cObject
Object class.
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite, int, const char *)
#define RB_IO_WAIT_WRITABLE
#define RB_IO_WAIT_READABLE
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_io_fdopen(int, int, const char *)
void rb_update_max_fd(int fd)
VALUE rb_str_resize(VALUE, long)
#define rb_str_new(str, len)
void rb_str_set_len(VALUE, long)
VALUE rb_str_buf_new(long)
VALUE rb_str_tmp_new(long)
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_time_num_new(VALUE, VALUE)
VALUE rb_time_new(time_t, long)
VALUE rb_time_nano_new(time_t, long)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
const char * rb_id2name(ID)
ID rb_intern(const char *)
void rb_io_check_closed(rb_io_t *)
int rb_io_read_pending(rb_io_t *)
void rb_io_set_nonblock(rb_io_t *fptr)
int rb_io_wait_writable(int fd)
int rb_io_wait_readable(int fd)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
int rsock_getfamily(rb_io_t *fptr)
VALUE rsock_init_sock(VALUE sock, int fd)
void rb_maygvl_fd_fix_cloexec(int fd)
VALUE rb_str_tmp_frozen_acquire(VALUE str)
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define MEMCPY(p1, p2, type, n)
#define ALLOCA_N(type, n)
VALUE type(ANYARGS)
ANYARGS-ed function type.
const char * inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
#define RARRAY_CONST_PTR(s)
#define RARRAY_AREF(a, i)
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
const char * rb_obj_classname(VALUE)
#define SockAddrStringValue(v)
#define rsock_bsock_recvmsg
#define rsock_bsock_sendmsg_nonblock
#define rsock_bsock_recvmsg_nonblock
#define rsock_bsock_sendmsg
#define MSG_DONTWAIT_RELIABLE
unsigned long long uint64_t
#define INIT_SOCKADDR(addr, family, len)
VALUE rb_str_catf(VALUE, const char *,...)
VALUE rb_sprintf(const char *,...)
int recvmsg(int, struct msghdr *, int)
int sendmsg(int, const struct msghdr *, int)