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
	
	 akr
						akr