6 static VALUE sym_wait_readable, sym_wait_writable;
8 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 9 static VALUE rb_cAncillaryData;
12 constant_to_sym(
int constant,
ID (*intern_const)(
int))
14 ID name = intern_const(constant);
23 ip_cmsg_type_to_sym(
int level,
int cmsg_type)
90 ancdata_new(
int family,
int level,
int type,
VALUE data)
99 ancillary_family(
VALUE self)
115 ancillary_family_m(
VALUE self)
117 return INT2NUM(ancillary_family(
self));
121 ancillary_level(
VALUE self)
137 ancillary_level_m(
VALUE self)
139 return INT2NUM(ancillary_level(
self));
143 ancillary_type(
VALUE self)
159 ancillary_type_m(
VALUE self)
161 return INT2NUM(ancillary_type(
self));
174 ancillary_data(
VALUE self)
194 VALUE result, str, ary;
199 for (i = 0 ; i <
argc; i++) {
209 for (i = 0 ; i <
argc; i++) {
218 result = ancdata_new(AF_UNIX, SOL_SOCKET, SCM_RIGHTS, str);
223 #define ancillary_s_unix_rights rb_f_notimplement 258 ancillary_unix_rights(
VALUE self)
262 level = ancillary_level(
self);
263 type = ancillary_type(
self);
265 if (level != SOL_SOCKET || type != SCM_RIGHTS)
271 #define ancillary_unix_rights rb_f_notimplement 274 #if defined(SCM_TIMESTAMP) || defined(SCM_TIMESTAMPNS) || defined(SCM_BINTIME) 301 ancillary_timestamp(
VALUE self)
307 level = ancillary_level(
self);
308 type = ancillary_type(
self);
309 data = ancillary_data(
self);
311 # ifdef SCM_TIMESTAMP 312 if (level == SOL_SOCKET && type == SCM_TIMESTAMP &&
320 # ifdef SCM_TIMESTAMPNS 321 if (level == SOL_SOCKET && type == SCM_TIMESTAMPNS &&
329 #define add(x,y) (rb_funcall((x), '+', 1, (y))) 330 #define mul(x,y) (rb_funcall((x), '*', 1, (y))) 331 #define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y))) 334 if (level == SOL_SOCKET && type == SCM_BINTIME &&
339 d = ULL2NUM(0x100000000ULL);
341 timev =
add(TIMET2NUM(bt.sec),
quo(ULL2NUM(bt.frac), d));
352 #define ancillary_timestamp rb_f_notimplement 375 return ancdata_new(family, level, type,
rb_str_new((
char*)&i,
sizeof(i)));
390 ancillary_int(
VALUE self)
394 data = ancillary_data(
self);
401 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) 423 ancillary_s_ip_pktinfo(
int argc,
VALUE *argv,
VALUE self)
425 VALUE v_addr, v_ifindex, v_spec_dst;
426 unsigned int ifindex;
427 struct sockaddr_in sa;
428 struct in_pktinfo pktinfo;
430 rb_scan_args(argc, argv,
"21", &v_addr, &v_ifindex, &v_spec_dst);
434 if (
NIL_P(v_spec_dst))
439 memset(&pktinfo, 0,
sizeof(pktinfo));
441 memset(&sa, 0,
sizeof(sa));
445 if (sa.sin_family != AF_INET)
447 memcpy(&pktinfo.ipi_addr, &sa.sin_addr,
sizeof(pktinfo.ipi_addr));
449 pktinfo.ipi_ifindex = ifindex;
451 memset(&sa, 0,
sizeof(sa));
455 if (sa.sin_family != AF_INET)
457 memcpy(&pktinfo.ipi_spec_dst, &sa.sin_addr,
sizeof(pktinfo.ipi_spec_dst));
459 return ancdata_new(AF_INET,
IPPROTO_IP, IP_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
462 #define ancillary_s_ip_pktinfo rb_f_notimplement 465 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) 486 ancillary_ip_pktinfo(
VALUE self)
490 struct in_pktinfo pktinfo;
491 struct sockaddr_in sa;
492 VALUE v_spec_dst, v_addr;
494 level = ancillary_level(
self);
495 type = ancillary_type(
self);
496 data = ancillary_data(
self);
498 if (level !=
IPPROTO_IP || type != IP_PKTINFO ||
503 memcpy(&pktinfo,
RSTRING_PTR(data),
sizeof(
struct in_pktinfo));
504 memset(&sa, 0,
sizeof(sa));
506 sa.sin_family = AF_INET;
507 memcpy(&sa.sin_addr, &pktinfo.ipi_addr,
sizeof(sa.sin_addr));
510 sa.sin_family = AF_INET;
511 memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst,
sizeof(sa.sin_addr));
517 #define ancillary_ip_pktinfo rb_f_notimplement 520 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) 538 unsigned int ifindex;
539 struct sockaddr_in6 sa;
540 struct in6_pktinfo pktinfo;
545 memset(&pktinfo, 0,
sizeof(pktinfo));
547 memset(&sa, 0,
sizeof(sa));
551 if (sa.sin6_family != AF_INET6)
553 memcpy(&pktinfo.ipi6_addr, &sa.sin6_addr,
sizeof(pktinfo.ipi6_addr));
555 pktinfo.ipi6_ifindex = ifindex;
557 return ancdata_new(AF_INET6, IPPROTO_IPV6, IPV6_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
560 #define ancillary_s_ipv6_pktinfo rb_f_notimplement 563 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) 565 extract_ipv6_pktinfo(
VALUE self,
struct in6_pktinfo *pktinfo_ptr,
struct sockaddr_in6 *sa_ptr)
570 level = ancillary_level(
self);
571 type = ancillary_type(
self);
572 data = ancillary_data(
self);
574 if (level != IPPROTO_IPV6 || type != IPV6_PKTINFO ||
579 memcpy(pktinfo_ptr,
RSTRING_PTR(data),
sizeof(*pktinfo_ptr));
581 INIT_SOCKADDR((
struct sockaddr *)sa_ptr, AF_INET6,
sizeof(*sa_ptr));
582 memcpy(&sa_ptr->sin6_addr, &pktinfo_ptr->ipi6_addr,
sizeof(sa_ptr->sin6_addr));
583 if (IN6_IS_ADDR_LINKLOCAL(&sa_ptr->sin6_addr))
584 sa_ptr->sin6_scope_id = pktinfo_ptr->ipi6_ifindex;
588 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) 604 ancillary_ipv6_pktinfo(
VALUE self)
606 struct in6_pktinfo pktinfo;
607 struct sockaddr_in6 sa;
610 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
615 #define ancillary_ipv6_pktinfo rb_f_notimplement 618 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) 634 ancillary_ipv6_pktinfo_addr(
VALUE self)
636 struct in6_pktinfo pktinfo;
637 struct sockaddr_in6 sa;
638 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
642 #define ancillary_ipv6_pktinfo_addr rb_f_notimplement 645 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) 661 ancillary_ipv6_pktinfo_ifindex(
VALUE self)
663 struct in6_pktinfo pktinfo;
664 struct sockaddr_in6 sa;
665 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
666 return UINT2NUM(pktinfo.ipi6_ifindex);
669 #define ancillary_ipv6_pktinfo_ifindex rb_f_notimplement 672 #if defined(SOL_SOCKET) && defined(SCM_RIGHTS) 674 anc_inspect_socket_rights(
int level,
int type,
VALUE data,
VALUE ret)
676 if (level == SOL_SOCKET && type == SCM_RIGHTS &&
679 for (off = 0; off <
RSTRING_LEN(data); off +=
sizeof(int)) {
681 memcpy((
char*)&fd,
RSTRING_PTR(data)+off,
sizeof(
int));
692 #if defined(SCM_CREDENTIALS) 694 anc_inspect_passcred_credentials(
int level,
int type,
VALUE data,
VALUE ret)
696 if (level == SOL_SOCKET && type == SCM_CREDENTIALS &&
699 memcpy(&cred,
RSTRING_PTR(data),
sizeof(
struct ucred));
700 rb_str_catf(ret,
" pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
710 #if defined(SCM_CREDS) 711 #define INSPECT_SCM_CREDS 713 anc_inspect_socket_creds(
int level,
int type,
VALUE data,
VALUE ret)
715 if (level != SOL_SOCKET && type != SCM_CREDS)
729 #if defined(HAVE_TYPE_STRUCT_CMSGCRED) 730 if (
RSTRING_LEN(data) ==
sizeof(
struct cmsgcred)) {
731 struct cmsgcred cred;
732 memcpy(&cred,
RSTRING_PTR(data),
sizeof(
struct cmsgcred));
737 if (cred.cmcred_ngroups) {
739 const char *sep =
" groups=";
740 for (i = 0; i < cred.cmcred_ngroups; i++) {
741 rb_str_catf(ret,
"%s%u", sep, cred.cmcred_groups[i]);
749 #if defined(HAVE_TYPE_STRUCT_SOCKCRED) 750 if ((
size_t)
RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
751 struct sockcred cred0, *cred;
752 memcpy(&cred0,
RSTRING_PTR(data), SOCKCREDSIZE(0));
753 if ((
size_t)
RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
754 cred = (
struct sockcred *)
ALLOCA_N(
char, SOCKCREDSIZE(cred0.sc_ngroups));
755 memcpy(cred,
RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
760 if (cred0.sc_ngroups) {
762 const char *sep =
" groups=";
763 for (i = 0; i < cred0.sc_ngroups; i++) {
777 #if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR) 779 anc_inspect_ip_recvdstaddr(
int level,
int type,
VALUE data,
VALUE ret)
781 if (level ==
IPPROTO_IP && type == IP_RECVDSTADDR &&
798 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) 800 anc_inspect_ip_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
802 if (level ==
IPPROTO_IP && type == IP_PKTINFO &&
804 struct in_pktinfo pktinfo;
806 memcpy(&pktinfo,
RSTRING_PTR(data),
sizeof(pktinfo));
807 if (
inet_ntop(AF_INET, &pktinfo.ipi_addr, buf,
sizeof(buf)) ==
NULL)
811 if (if_indextoname(pktinfo.ipi_ifindex, buf) ==
NULL)
812 rb_str_catf(ret,
" ifindex:%d", pktinfo.ipi_ifindex);
815 if (
inet_ntop(AF_INET, &pktinfo.ipi_spec_dst, buf,
sizeof(buf)) ==
NULL)
827 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO) 829 anc_inspect_ipv6_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
831 if (level == IPPROTO_IPV6 && type == IPV6_PKTINFO &&
833 struct in6_pktinfo *pktinfo = (
struct in6_pktinfo *)
RSTRING_PTR(data);
834 struct in6_addr addr;
835 unsigned int ifindex;
837 memcpy(&addr, &pktinfo->ipi6_addr,
sizeof(addr));
838 memcpy(&ifindex, &pktinfo->ipi6_ifindex,
sizeof(ifindex));
843 if (if_indextoname(ifindex, ifbuf) ==
NULL)
855 #if defined(SCM_TIMESTAMP) 857 inspect_timeval_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
866 tm = *localtime(&time);
867 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
868 rb_str_catf(ret,
" %s.%06ld", buf, (
long)tv.tv_usec);
877 #if defined(SCM_TIMESTAMPNS) 879 inspect_timespec_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
886 tm = *localtime(&ts.tv_sec);
887 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
888 rb_str_catf(ret,
" %s.%09ld", buf, (
long)ts.tv_nsec);
897 #if defined(SCM_BINTIME) 899 inspect_bintime_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
910 tm = *localtime(&bt.sec);
911 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
915 frac_h = bt.frac >> 32;
916 frac_l = bt.frac & 0xffffffff;
918 scale_h = 0x8ac72304;
919 scale_l = 0x89e80000;
921 res_h = frac_h * scale_h;
922 res_l = frac_l * scale_l;
924 tmp1 = frac_h * scale_l;
927 res_l += tmp1 & 0xffffffff;
928 if (res_l < tmp2) res_h++;
930 tmp1 = frac_l * scale_h;
933 res_l += tmp1 & 0xffffffff;
934 if (res_l < tmp2) res_h++;
955 ancillary_inspect(
VALUE self)
958 int family,
level, type;
960 ID family_id, level_id, type_id;
964 family = ancillary_family(
self);
965 level = ancillary_level(
self);
966 type = ancillary_type(
self);
967 data = ancillary_data(
self);
977 if (level == SOL_SOCKET) {
993 vtype = ip_cmsg_type_to_sym(level, type);
1006 if (level == SOL_SOCKET)
1012 # if defined(SOL_SOCKET) 1015 # if defined(SCM_TIMESTAMP) 1016 case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret);
break;
1018 # if defined(SCM_TIMESTAMPNS) 1019 case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret);
break;
1021 # if defined(SCM_BINTIME) 1022 case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret);
break;
1024 # if defined(SCM_RIGHTS) 1025 case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret);
break;
1027 # if defined(SCM_CREDENTIALS) 1028 case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret);
break;
1030 # if defined(INSPECT_SCM_CREDS) 1031 case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret);
break;
1044 # if defined(IPPROTO_IP) 1047 # if defined(IP_RECVDSTADDR) 1048 case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret);
break;
1050 # if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) 1051 case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret);
break;
1057 # if defined(IPPROTO_IPV6) 1060 # if defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO) 1061 case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret);
break;
1095 int family = ancillary_family(
self);
1099 if (ancillary_level(
self) == level &&
1100 ancillary_type(
self) == type)
1108 #if defined(HAVE_SENDMSG) 1109 struct sendmsg_args_struct {
1112 const struct msghdr *msg;
1116 nogvl_sendmsg_func(
void *ptr)
1118 struct sendmsg_args_struct *args = ptr;
1119 return (
void *)(
VALUE)
sendmsg(args->fd, args->msg, args->flags);
1123 rb_sendmsg(
int fd,
const struct msghdr *msg,
int flags)
1125 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) 1161 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1163 size_t last_pad = 0;
1165 #if defined(__NetBSD__) 1170 for (i = 0; i < controls_num; i++) {
1171 VALUE elt = controls_ptr[i], v;
1172 VALUE vlevel, vtype;
1200 memset((
char *)cmsg, 0, cspace);
1201 memset((
char *)&cmh, 0,
sizeof(cmh));
1202 cmh.cmsg_level =
level;
1203 cmh.cmsg_type = type;
1205 MEMCPY(cmsg, &cmh,
char,
sizeof(cmh));
1207 #if defined(__NetBSD__) 1208 last_level = cmh.cmsg_level;
1209 last_type = cmh.cmsg_type;
1211 last_pad = cspace - cmh.cmsg_len;
1234 #if defined(__NetBSD__) 1235 if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS)
1248 flags |= MSG_DONTWAIT;
1251 if (!
NIL_P(dest_sockaddr))
1257 memset(&mh, 0,
sizeof(mh));
1258 if (!
NIL_P(dest_sockaddr)) {
1266 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1277 ss = rb_sendmsg(fptr->
fd, &mh, flags);
1286 if (nonblock && (e ==
EWOULDBLOCK || e == EAGAIN)) {
1288 return sym_wait_writable;
1291 "sendmsg(2) would block");
1295 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1303 #if defined(HAVE_SENDMSG) 1308 return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr, controls,
1313 #if defined(HAVE_SENDMSG) 1318 return bsock_sendmsg_internal(sock, data, flags, dest_sockaddr,
1323 #if defined(HAVE_RECVMSG) 1324 struct recvmsg_args_struct {
1331 rsock_recvmsg(
int socket,
struct msghdr *message,
int flags)
1335 #ifdef MSG_CMSG_CLOEXEC 1337 flags |= MSG_CMSG_CLOEXEC;
1340 ret =
recvmsg(socket, message, flags);
1347 nogvl_recvmsg_func(
void *ptr)
1349 struct recvmsg_args_struct *args = ptr;
1350 int flags = args->flags;
1351 return (
void *)rsock_recvmsg(args->fd, args->msg, flags);
1355 rb_recvmsg(
int fd,
struct msghdr *msg,
int flags)
1357 struct recvmsg_args_struct args;
1364 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1366 discard_cmsg(
struct cmsghdr *cmh,
char *msg_end,
int msg_peek_p)
1368 # if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK) 1380 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1381 int *fdp = (
int *)CMSG_DATA(cmh);
1382 int *end = (
int *)((
char *)cmh + cmh->cmsg_len);
1383 while ((
char *)fdp +
sizeof(int) <= (
char *)end &&
1384 (
char *)fdp +
sizeof(
int) <= msg_end) {
1394 rsock_discard_cmsg_resource(
struct msghdr *mh,
int msg_peek_p)
1396 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1397 struct cmsghdr *cmh;
1405 for (cmh = CMSG_FIRSTHDR(mh); cmh !=
NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1406 discard_cmsg(cmh, msg_end, msg_peek_p);
1411 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1413 make_io_for_unix_rights(
VALUE ctl,
struct cmsghdr *cmh,
char *msg_end)
1415 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1419 fdp = (
int *)CMSG_DATA(cmh);
1420 end = (
int *)((
char *)cmh + cmh->cmsg_len);
1421 while ((
char *)fdp +
sizeof(int) <= (
char *)end &&
1422 (
char *)fdp +
sizeof(
int) <= msg_end) {
1426 if (
fstat(fd, &stbuf) == -1)
1433 if (S_ISSOCK(stbuf.st_mode))
1447 bsock_recvmsg_internal(
VALUE sock,
1454 int flags, orig_flags;
1462 int request_scm_rights;
1463 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1464 struct cmsghdr *cmh;
1473 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1476 if (!
NIL_P(vmaxctllen))
1482 flags |= MSG_DONTWAIT;
1486 grow_buffer =
NIL_P(vmaxdatlen) ||
NIL_P(vmaxctllen);
1488 request_scm_rights = 0;
1489 if (
RTEST(scm_rights))
1490 request_scm_rights = 1;
1491 #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1492 if (request_scm_rights)
1501 #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1505 if (getsockopt(fptr->
fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen) == -1) {
1508 if (socktype == SOCK_STREAM)
1520 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1528 memset(&mh, 0,
sizeof(mh));
1530 memset(&namebuf, 0,
sizeof(namebuf));
1539 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1551 ss = rb_recvmsg(fptr->
fd, &mh, flags);
1560 if (nonblock && (e ==
EWOULDBLOCK || e == EAGAIN)) {
1562 return sym_wait_readable;
1566 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1567 if (!gc_done && (e == EMFILE || e ==
EMSGSIZE)) {
1589 if (
NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.
iov_len) {
1595 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1597 #define BIG_ENOUGH_SPACE 65536 1598 if (BIG_ENOUGH_SPACE < maxctllen &&
1603 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1613 #undef BIG_ENOUGH_SPACE 1617 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1622 if (flags != orig_flags) {
1623 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1640 #
if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1647 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1651 for (cmh = CMSG_FIRSTHDR(&mh); cmh !=
NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
1655 if (cmh->cmsg_len == 0) {
1658 ctl_end = (
char*)cmh + cmh->cmsg_len;
1659 clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (
char*)CMSG_DATA(cmh);
1660 ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type,
rb_tainted_str_new((
char*)CMSG_DATA(cmh), clen));
1661 if (request_scm_rights)
1662 make_io_for_unix_rights(ctl, cmh, msg_end);
1664 discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
1675 #if defined(HAVE_RECVMSG) 1681 return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 0);
1685 #if defined(HAVE_RECVMSG) 1690 return bsock_recvmsg_internal(sock, dlen, flags, clen, scm_rights, ex, 1);
1697 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) 1706 rb_define_method(rb_cAncillaryData,
"initialize", ancillary_initialize, 4);
1719 rb_define_method(rb_cAncillaryData,
"unix_rights", ancillary_unix_rights, 0);
1724 rb_define_method(rb_cAncillaryData,
"ip_pktinfo", ancillary_ip_pktinfo, 0);
1727 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo", ancillary_ipv6_pktinfo, 0);
1728 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
1729 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
RUBY_EXTERN VALUE rb_cString
ID rsock_intern_family_noprefix(int val)
VALUE rb_ary_entry(VALUE ary, long offset)
void rb_syserr_fail(int e, const char *mesg)
void rb_update_max_fd(int fd)
void rb_io_set_nonblock(rb_io_t *fptr)
VALUE rb_time_nano_new(time_t, long)
ID rsock_intern_scm_optname(int val)
#define SockAddrStringValue(v)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
int rsock_cmsg_cloexec_state
int sendmsg(int, const struct msghdr *, int)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rsock_init_sock(VALUE sock, int fd)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void rb_str_set_len(VALUE, long)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
#define rsock_bsock_sendmsg
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Tries to convert an object into another type.
const char * inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
int recvmsg(int, struct msghdr *, int)
VALUE rb_str_tmp_new(long)
#define GetOpenFile(obj, fp)
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
const char * rb_obj_classname(VALUE)
VALUE rb_str_buf_cat(VALUE, const char *, long)
#define NEWOBJ_OF(obj, type, klass, flags)
#define RB_TYPE_P(obj, type)
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
unsigned long long uint64_t
int rsock_family_arg(VALUE domain)
#define rsock_bsock_sendmsg_nonblock
RUBY_EXTERN VALUE rb_cObject
VALUE rb_str_cat2(VALUE, const char *)
int rsock_getfamily(rb_io_t *fptr)
int rsock_level_arg(int family, VALUE level)
int rb_io_wait_writable(int)
void rsock_init_ancdata(void)
#define ALLOCA_N(type, n)
#define MEMCPY(p1, p2, type, n)
#define rsock_bsock_recvmsg_nonblock
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
VALUE rb_time_new(time_t, long)
#define INIT_SOCKADDR(addr, family, len)
VALUE rb_str_resize(VALUE, long)
void rb_sys_fail(const char *mesg)
VALUE rb_io_fdopen(int, int, const char *)
#define RARRAY_CONST_PTR(a)
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
Make a hidden object visible again.
ID rsock_intern_iplevel(int val)
VALUE rb_sprintf(const char *format,...)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
unsigned char buf[MIME_BUF_SIZE]
ID rsock_intern_tcp_optname(int val)
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite writable, int n, const char *mesg)
int rsock_detect_cloexec(int fd)
const char * rb_id2name(ID)
#define RARRAY_LENINT(ary)
int rb_io_read_pending(rb_io_t *)
#define RARRAY_AREF(a, i)
VALUE rb_str_catf(VALUE str, const char *format,...)
ID rsock_intern_udp_optname(int val)
#define MSG_DONTWAIT_RELIABLE
RUBY_EXTERN VALUE rb_eIOError
#define rsock_bsock_recvmsg
VALUE rb_tainted_str_new(const char *, long)
ID rsock_intern_ipv6_optname(int val)
VALUE rb_str_buf_new(long)
int rb_io_wait_readable(int)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_append(VALUE, VALUE)
void rb_io_check_closed(rb_io_t *)
VALUE rb_time_num_new(VALUE, VALUE)
int rsock_cmsg_type_arg(int family, int level, VALUE type)
void rb_maygvl_fd_fix_cloexec(int fd)
VALUE rb_attr_get(VALUE, ID)
ID rsock_intern_ip_optname(int val)
VALUE rb_str_new(const char *, long)