static VALUE unix_init(sock, path) VALUE sock, path; { return init_unixsock(sock, path, 0); }
static VALUE unix_s_socketpair(argc, argv, klass) 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(argc, argv, klass) 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(sock) VALUE sock; { OpenFile *fptr; struct sockaddr_un addr; socklen_t len = sizeof addr; GetOpenFile(sock, fptr); if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getsockname(2)"); return unixaddr(&addr, len); }
static VALUE unix_path(sock) VALUE sock; { OpenFile *fptr; GetOpenFile(sock, fptr); if (fptr->path == 0) { struct sockaddr_un addr; socklen_t len = sizeof(addr); if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0) rb_sys_fail(0); fptr->path = strdup(unixpath(&addr, len)); } return rb_str_new2(fptr->path); }
static VALUE unix_peeraddr(sock) VALUE sock; { OpenFile *fptr; struct sockaddr_un addr; socklen_t len = sizeof addr; GetOpenFile(sock, fptr); if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getpeername(2)"); return unixaddr(&addr, len); }
static VALUE unix_recv_io(argc, argv, sock) int argc; VALUE *argv; VALUE sock; { #if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS) VALUE klass, mode; OpenFile *fptr; struct msghdr msg; struct iovec vec[2]; char buf[1]; int fd; #if FD_PASSING_BY_MSG_CONTROL struct { struct cmsghdr hdr; int fd; } cmsg; #endif rb_scan_args(argc, argv, "02", &klass, &mode); if (argc == 0) klass = rb_cIO; if (argc <= 1) mode = Qnil; GetOpenFile(sock, fptr); thread_read_select(fileno(fptr->f)); msg.msg_name = NULL; msg.msg_namelen = 0; vec[0].iov_base = buf; vec[0].iov_len = sizeof(buf); msg.msg_iov = vec; msg.msg_iovlen = 1; #if FD_PASSING_BY_MSG_CONTROL msg.msg_control = (caddr_t)&cmsg; msg.msg_controllen = CMSG_SPACE(sizeof(int)); msg.msg_flags = 0; cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_RIGHTS; cmsg.fd = -1; #else msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); fd = -1; #endif if (recvmsg(fileno(fptr->f), &msg, 0) == -1) rb_sys_fail("recvmsg(2)"); #if FD_PASSING_BY_MSG_CONTROL if (msg.msg_controllen != CMSG_SPACE(sizeof(int))) { rb_raise(rb_eSocket, "file descriptor was not passed (msg_controllen : %d != %d)", msg.msg_controllen, CMSG_SPACE(sizeof(int))); } if (cmsg.hdr.cmsg_len != CMSG_SPACE(0) + sizeof(int)) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_len : %d != %d)", cmsg.hdr.cmsg_len, CMSG_SPACE(0) + sizeof(int)); } if (cmsg.hdr.cmsg_level != SOL_SOCKET) { rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_level : %d != %d)", 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)", cmsg.hdr.cmsg_type, SCM_RIGHTS); } #else if (msg.msg_accrightslen != sizeof(fd)) { rb_raise(rb_eSocket, "file descriptor was not passed (accrightslen) : %d != %d", msg.msg_accrightslen, sizeof(fd)); } #endif #if FD_PASSING_BY_MSG_CONTROL fd = cmsg.fd; #endif if (klass == Qnil) return INT2FIX(fd); else { static ID for_fd = 0; int ff_argc; VALUE ff_argv[2]; if (!for_fd) for_fd = rb_intern("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(argc, argv, sock) int argc; VALUE *argv; VALUE sock; { return s_recvfrom(sock, argc, argv, RECV_UNIX); }
static VALUE unix_send_io(sock, val) VALUE sock, val; { #if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS) int fd; OpenFile *fptr; struct msghdr msg; struct iovec vec[1]; char buf[1]; #if FD_PASSING_BY_MSG_CONTROL struct { struct cmsghdr hdr; int fd; } cmsg; #endif if (rb_obj_is_kind_of(val, rb_cIO)) { OpenFile *valfptr; GetOpenFile(val, valfptr); fd = fileno(valfptr->f); } else if (FIXNUM_P(val)) { fd = FIX2INT(val); } else { rb_raise(rb_eTypeError, "neither IO nor file descriptor"); } GetOpenFile(sock, fptr); msg.msg_name = NULL; 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; msg.msg_iov = vec; msg.msg_iovlen = 1; #if FD_PASSING_BY_MSG_CONTROL msg.msg_control = (caddr_t)&cmsg; msg.msg_controllen = CMSG_SPACE(sizeof(int)); msg.msg_flags = 0; cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_RIGHTS; cmsg.fd = fd; #else msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); #endif if (sendmsg(fileno(fptr->f), &msg, 0) == -1) rb_sys_fail("sendmsg(2)"); return Qnil; #else rb_notimplement(); return Qnil; /* not reached */ #endif }