mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* ext/socket/extconf.rb (have_struct_member): new method.
check msg_control and msg_accrights in struct msghdr. check sys/uio.h. * socket/socket.c: include sys/uio.h if available. (thread_read_select): new function. (unix_send_io): ditto. (unix_recv_io): ditto. (unix_s_socketpair): ditto. (Init_socket): define UNIXSocket#send_io, UNIXSocket#recv_io, git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2150 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									bf7037833d
								
							
						
					
					
						commit
						4efd36bbd9
					
				
					 3 changed files with 247 additions and 0 deletions
				
			
		
							
								
								
									
										13
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
					@ -1,3 +1,16 @@
 | 
				
			||||||
 | 
					Fri Mar  1 06:25:49 2002  Tanaka Akira  <akr@m17n.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* ext/socket/extconf.rb (have_struct_member): new method.
 | 
				
			||||||
 | 
						check msg_control and msg_accrights in struct msghdr.  check sys/uio.h.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* socket/socket.c: include sys/uio.h if available.
 | 
				
			||||||
 | 
						(thread_read_select): new function.
 | 
				
			||||||
 | 
						(unix_send_io): ditto.
 | 
				
			||||||
 | 
						(unix_recv_io): ditto.
 | 
				
			||||||
 | 
						(unix_s_socketpair): ditto.
 | 
				
			||||||
 | 
						(Init_socket): define UNIXSocket#send_io, UNIXSocket#recv_io, 
 | 
				
			||||||
 | 
						UNIXSocket#socketpair and UNIXSocket#pair.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Wed Feb 27 16:30:50 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
					Wed Feb 27 16:30:50 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* eval.c (rb_mod_include): load modules in argument order.
 | 
						* eval.c (rb_mod_include): load modules in argument order.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,42 @@ require 'mkmf'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len"
 | 
					$CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def have_struct_member(type, member, header=nil)
 | 
				
			||||||
 | 
					  printf "checking for %s.%s... ", type, member
 | 
				
			||||||
 | 
					  STDOUT.flush
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  libs = $libs
 | 
				
			||||||
 | 
					  src = 
 | 
				
			||||||
 | 
					    if /mswin32|mingw/ =~ RUBY_PLATFORM
 | 
				
			||||||
 | 
					      r = <<"SRC"
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					#include <winsock.h>
 | 
				
			||||||
 | 
					SRC
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      ""
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  unless header.nil?
 | 
				
			||||||
 | 
					    header = [header] unless header.kind_of? Array
 | 
				
			||||||
 | 
					    header.each {|h|
 | 
				
			||||||
 | 
					      src << <<"SRC"
 | 
				
			||||||
 | 
					#include <#{h}>
 | 
				
			||||||
 | 
					SRC
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  src << <<"SRC"
 | 
				
			||||||
 | 
					int main() { return 0; }
 | 
				
			||||||
 | 
					int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
 | 
				
			||||||
 | 
					SRC
 | 
				
			||||||
 | 
					  r = try_link(src, libs) # xxx try_compile is not available.
 | 
				
			||||||
 | 
					  unless r
 | 
				
			||||||
 | 
					    print "no\n"
 | 
				
			||||||
 | 
					    return false
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  $defs.push(format("-DHAVE_ST_%s", member.upcase))
 | 
				
			||||||
 | 
					  print "yes\n"
 | 
				
			||||||
 | 
					  return true
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case RUBY_PLATFORM
 | 
					case RUBY_PLATFORM
 | 
				
			||||||
when /mswin32|mingw/
 | 
					when /mswin32|mingw/
 | 
				
			||||||
  test_func = "WSACleanup"
 | 
					  test_func = "WSACleanup"
 | 
				
			||||||
| 
						 | 
					@ -176,6 +212,9 @@ end
 | 
				
			||||||
have_header("netinet/tcp.h") if not /cygwin/ === RUBY_PLATFORM # for cygwin 1.1.5
 | 
					have_header("netinet/tcp.h") if not /cygwin/ === RUBY_PLATFORM # for cygwin 1.1.5
 | 
				
			||||||
have_header("netinet/udp.h")
 | 
					have_header("netinet/udp.h")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					have_struct_member('struct msghdr', 'msg_control', header=['sys/types.h', 'sys/socket.h'])
 | 
				
			||||||
 | 
					have_struct_member('struct msghdr', 'msg_accrights', header=['sys/types.h', 'sys/socket.h'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$getaddr_info_ok = false
 | 
					$getaddr_info_ok = false
 | 
				
			||||||
if not enable_config("wide-getaddrinfo", false) and try_run(<<EOF)
 | 
					if not enable_config("wide-getaddrinfo", false) and try_run(<<EOF)
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
| 
						 | 
					@ -329,6 +368,7 @@ EOF
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
have_header("sys/un.h")
 | 
					have_header("sys/un.h")
 | 
				
			||||||
 | 
					have_header("sys/uio.h")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if have_func(test_func)
 | 
					if have_func(test_func)
 | 
				
			||||||
  have_func("hsterror")
 | 
					  have_func("hsterror")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,10 @@
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_SYS_UIO_H
 | 
				
			||||||
 | 
					#include <sys/uio.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef NT
 | 
					#ifndef NT
 | 
				
			||||||
#if defined(__BEOS__)
 | 
					#if defined(__BEOS__)
 | 
				
			||||||
# include <net/socket.h>
 | 
					# include <net/socket.h>
 | 
				
			||||||
| 
						 | 
					@ -683,6 +687,17 @@ ruby_socket(domain, type, proto)
 | 
				
			||||||
    return fd;
 | 
					    return fd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					thread_read_select(fd)
 | 
				
			||||||
 | 
					    int fd;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    fd_set fds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FD_ZERO(&fds);
 | 
				
			||||||
 | 
					    FD_SET(fd, &fds);
 | 
				
			||||||
 | 
					    rb_thread_select(fd+1, &fds, 0, 0, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
thread_write_select(fd)
 | 
					thread_write_select(fd)
 | 
				
			||||||
    int fd;
 | 
					    int fd;
 | 
				
			||||||
| 
						 | 
					@ -1381,6 +1396,161 @@ unix_recvfrom(argc, argv, sock)
 | 
				
			||||||
    return s_recvfrom(sock, argc, argv, RECV_UNIX);
 | 
					    return s_recvfrom(sock, argc, argv, RECV_UNIX);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static VALUE
 | 
				
			||||||
 | 
					unix_send_io(sock, val)
 | 
				
			||||||
 | 
					    VALUE sock, val;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(HAVE_ST_MSG_CONTROL) || defined(HAVE_ST_MSG_ACCRIGHTS)
 | 
				
			||||||
 | 
					    int fd;
 | 
				
			||||||
 | 
					    OpenFile *fptr;
 | 
				
			||||||
 | 
					    struct msghdr msg;
 | 
				
			||||||
 | 
					    struct iovec vec[1];
 | 
				
			||||||
 | 
					    char buf[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(HAVE_ST_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, "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 defined(HAVE_ST_MSG_CONTROL)
 | 
				
			||||||
 | 
					    msg.msg_control = (caddr_t)&cmsg;
 | 
				
			||||||
 | 
					    msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
 | 
				
			||||||
 | 
					    msg.msg_flags = 0;
 | 
				
			||||||
 | 
					    cmsg.hdr.cmsg_len = sizeof(struct cmsghdr) + 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();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static VALUE
 | 
				
			||||||
 | 
					unix_recv_io(argc, argv, sock)
 | 
				
			||||||
 | 
					    int argc;
 | 
				
			||||||
 | 
					    VALUE *argv;
 | 
				
			||||||
 | 
					    VALUE sock;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(HAVE_ST_MSG_CONTROL) || defined(HAVE_ST_MSG_ACCRIGHTS)
 | 
				
			||||||
 | 
					    VALUE klass, mode;
 | 
				
			||||||
 | 
					    OpenFile *fptr;
 | 
				
			||||||
 | 
					    struct msghdr msg;
 | 
				
			||||||
 | 
					    struct iovec vec[2];
 | 
				
			||||||
 | 
					    char buf[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int fd;
 | 
				
			||||||
 | 
					#if defined(HAVE_ST_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 defined(HAVE_ST_MSG_CONTROL)
 | 
				
			||||||
 | 
					    msg.msg_control = (caddr_t)&cmsg;
 | 
				
			||||||
 | 
					    msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
 | 
				
			||||||
 | 
					    msg.msg_flags = 0;
 | 
				
			||||||
 | 
					    cmsg.hdr.cmsg_len = sizeof(struct cmsghdr) + 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 (
 | 
				
			||||||
 | 
					#if defined(HAVE_ST_MSG_CONTROL)
 | 
				
			||||||
 | 
						msg.msg_controllen != sizeof(struct cmsghdr) + sizeof(int) ||
 | 
				
			||||||
 | 
					        cmsg.hdr.cmsg_len != sizeof(struct cmsghdr) + sizeof(int) ||
 | 
				
			||||||
 | 
						cmsg.hdr.cmsg_level != SOL_SOCKET ||
 | 
				
			||||||
 | 
						cmsg.hdr.cmsg_type != SCM_RIGHTS
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        msg.msg_accrightslen != sizeof(fd)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						) {
 | 
				
			||||||
 | 
						rb_raise(rb_eSocket, "File descriptor was not passed");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(HAVE_ST_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();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static VALUE
 | 
					static VALUE
 | 
				
			||||||
unix_accept(sock)
 | 
					unix_accept(sock)
 | 
				
			||||||
    VALUE sock;
 | 
					    VALUE sock;
 | 
				
			||||||
| 
						 | 
					@ -1564,6 +1734,26 @@ sock_s_socketpair(klass, domain, type, protocol)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_SYS_UN_H
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static VALUE
 | 
					static VALUE
 | 
				
			||||||
sock_connect(sock, addr)
 | 
					sock_connect(sock, addr)
 | 
				
			||||||
    VALUE sock, addr;
 | 
					    VALUE sock, addr;
 | 
				
			||||||
| 
						 | 
					@ -2177,6 +2367,10 @@ Init_socket()
 | 
				
			||||||
    rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0);
 | 
					    rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0);
 | 
				
			||||||
    rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0);
 | 
					    rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0);
 | 
				
			||||||
    rb_define_method(rb_cUNIXSocket, "recvfrom", unix_recvfrom, -1);
 | 
					    rb_define_method(rb_cUNIXSocket, "recvfrom", unix_recvfrom, -1);
 | 
				
			||||||
 | 
					    rb_define_method(rb_cUNIXSocket, "send_io", unix_send_io, 1);
 | 
				
			||||||
 | 
					    rb_define_method(rb_cUNIXSocket, "recv_io", unix_recv_io, -1);
 | 
				
			||||||
 | 
					    rb_define_singleton_method(rb_cUNIXSocket, "socketpair", unix_s_socketpair, -1);
 | 
				
			||||||
 | 
					    rb_define_singleton_method(rb_cUNIXSocket, "pair", unix_s_socketpair, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
 | 
					    rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket);
 | 
				
			||||||
    rb_define_global_const("UNIXserver", rb_cUNIXServer);
 | 
					    rb_define_global_const("UNIXserver", rb_cUNIXServer);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue