static VALUE unix_init(VALUE sock, VALUE path) { return init_unixsock(sock, path, 0); }
static VALUE unix_s_socketpair(int argc, VALUE *argv, VALUE klass) { VALUE domain, type, protocol; domain = INT2FIX(PF_UNIX); rb_scan_args(argc, argv, "02", &type, &protocol); if (argc == 0) type = INT2FIX(SOCK_STREAM); if (argc <= 1) protocol = INT2FIX(0); return sock_s_socketpair(klass, domain, type, protocol); }
static VALUE unix_s_socketpair(int argc, VALUE *argv, VALUE klass) { VALUE domain, type, protocol; domain = INT2FIX(PF_UNIX); rb_scan_args(argc, argv, "02", &type, &protocol); if (argc == 0) type = INT2FIX(SOCK_STREAM); if (argc <= 1) protocol = INT2FIX(0); return sock_s_socketpair(klass, domain, type, protocol); }
static VALUE unix_addr(VALUE sock) { rb_io_t *fptr; struct sockaddr_un addr; socklen_t len = sizeof addr; GetOpenFile(sock, fptr); if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getsockname(2)"); return unixaddr(&addr, len); }
static VALUE unix_path(VALUE sock) { rb_io_t *fptr; GetOpenFile(sock, fptr); if (NIL_P(fptr->pathv)) { struct sockaddr_un addr; socklen_t len = sizeof(addr); if (getsockname(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rb_sys_fail(0); fptr->pathv = rb_obj_freeze(rb_str_new_cstr(unixpath(&addr, len))); } return rb_str_dup(fptr->pathv); }
static VALUE unix_peeraddr(VALUE sock) { rb_io_t *fptr; struct sockaddr_un addr; socklen_t len = sizeof addr; GetOpenFile(sock, fptr); if (getpeername(fptr->fd, (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getpeername(2)"); return unixaddr(&addr, len); }
static VALUE unix_recv_io(int argc, VALUE *argv, VALUE sock) { #if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS) VALUE klass, mode; rb_io_t *fptr; struct iomsg_arg arg; struct iovec vec[2]; char buf[1]; int fd; #if FD_PASSING_BY_MSG_CONTROL struct { struct cmsghdr hdr; char pad[8+sizeof(int)+8]; } cmsg; #endif rb_scan_args(argc, argv, "02", &klass, &mode); if (argc == 0) klass = rb_cIO; if (argc <= 1) mode = Qnil; GetOpenFile(sock, fptr); arg.msg.msg_name = NULL; arg.msg.msg_namelen = 0; vec[0].iov_base = buf; vec[0].iov_len = sizeof(buf); arg.msg.msg_iov = vec; arg.msg.msg_iovlen = 1; #if FD_PASSING_BY_MSG_CONTROL arg.msg.msg_control = (caddr_t)&cmsg; arg.msg.msg_controllen = CMSG_SPACE(sizeof(int)); arg.msg.msg_flags = 0; cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(&cmsg.hdr) = -1; #else arg.msg.msg_accrights = (caddr_t)&fd; arg.msg.msg_accrightslen = sizeof(fd); fd = -1; #endif arg.fd = fptr->fd; rb_thread_wait_fd(arg.fd); if ((int)BLOCKING_REGION(recvmsg_blocking, &arg) == -1) rb_sys_fail("recvmsg(2)"); #if FD_PASSING_BY_MSG_CONTROL if (arg.msg.msg_controllen < CMSG_LEN(sizeof(int))) { rb_raise(rb_eSocket, "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)", (int)arg.msg.msg_controllen, (int)CMSG_LEN(sizeof(int))); } if (CMSG_SPACE(sizeof(int)) < arg.msg.msg_controllen) { rb_raise(rb_eSocket, "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)", (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int))); } if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_len=%d, %d expected)", (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); } if (cmsg.hdr.cmsg_level != SOL_SOCKET) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_level=%d, %d expected)", cmsg.hdr.cmsg_level, SOL_SOCKET); } if (cmsg.hdr.cmsg_type != SCM_RIGHTS) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_type=%d, %d expected)", cmsg.hdr.cmsg_type, SCM_RIGHTS); } #else if (arg.msg.msg_accrightslen != sizeof(fd)) { rb_raise(rb_eSocket, "file descriptor was not passed (accrightslen) : %d != %d", arg.msg.msg_accrightslen, (int)sizeof(fd)); } #endif #if FD_PASSING_BY_MSG_CONTROL fd = *(int *)CMSG_DATA(&cmsg.hdr); #endif if (klass == Qnil) return INT2FIX(fd); else { ID for_fd; int ff_argc; VALUE ff_argv[2]; CONST_ID(for_fd, "for_fd"); ff_argc = mode == Qnil ? 1 : 2; ff_argv[0] = INT2FIX(fd); ff_argv[1] = mode; return rb_funcall2(klass, for_fd, ff_argc, ff_argv); } #else rb_notimplement(); return Qnil; /* not reached */ #endif }
static VALUE unix_recvfrom(int argc, VALUE *argv, VALUE sock) { return s_recvfrom(sock, argc, argv, RECV_UNIX); }
static VALUE unix_send_io(VALUE sock, VALUE val) { #if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS) int fd; rb_io_t *fptr; struct iomsg_arg arg; struct iovec vec[1]; char buf[1]; #if FD_PASSING_BY_MSG_CONTROL struct { struct cmsghdr hdr; char pad[8+sizeof(int)+8]; } cmsg; #endif if (rb_obj_is_kind_of(val, rb_cIO)) { rb_io_t *valfptr; GetOpenFile(val, valfptr); fd = valfptr->fd; } else if (FIXNUM_P(val)) { fd = FIX2INT(val); } else { rb_raise(rb_eTypeError, "neither IO nor file descriptor"); } GetOpenFile(sock, fptr); arg.msg.msg_name = NULL; arg.msg.msg_namelen = 0; /* Linux and Solaris doesn't work if msg_iov is NULL. */ buf[0] = '\0'; vec[0].iov_base = buf; vec[0].iov_len = 1; arg.msg.msg_iov = vec; arg.msg.msg_iovlen = 1; #if FD_PASSING_BY_MSG_CONTROL arg.msg.msg_control = (caddr_t)&cmsg; arg.msg.msg_controllen = CMSG_LEN(sizeof(int)); arg.msg.msg_flags = 0; MEMZERO((char*)&cmsg, char, sizeof(cmsg)); cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(&cmsg.hdr) = fd; #else arg.msg.msg_accrights = (caddr_t)&fd; arg.msg.msg_accrightslen = sizeof(fd); #endif arg.fd = fptr->fd; rb_thread_fd_writable(arg.fd); if ((int)BLOCKING_REGION(sendmsg_blocking, &arg) == -1) rb_sys_fail("sendmsg(2)"); return Qnil; #else rb_notimplement(); return Qnil; /* not reached */ #endif }
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.