From: itojun@... Date: 1999-04-30T19:23:56+09:00 Subject: [ruby-dev:6695] Re: cvs repository ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="iso-2022-jp" Content-ID: <6667.925467778.1@coconut.itojun.org> Content-Transfer-Encoding: 7bit >|>手順は >|> $ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs login >|> (Logging in to anonymous@cvs.netlab.co.jp) >|> CVS password: guest >|> $ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs checkout -r ruby_1_3 ruby >|>です.こっちを書いた方が親切ですねえ.そうしましょうか. >| この方がいいですかね。 >そうしました.今日版はIPv6を含んでますから,いとじゅんさんに >も楽しんで(苦しんで?)いただけるのではないかと思います. こんなpatchをあてて、KAME/BSDIで一応コンパイル通りました(socket.cは static link)。 ただし、thread_connect()のどっかに問題があるらしく、添付の コードのc.getpeername()が成功しません(ENOTCONNが返る)。 デバッガで追ってると成功するので、「EAGAINだったらもう一度」の あたりでなにかいけないことが起きているように思います。 #define ss_family __ss_familyは、いちばん最初に必要です。 IPv6 basic API(RFC2553)の定義のときに、__ss_familyにするかss_familyに するかでもめて、両方の実装が存在します。 (一番安全なのはcc -Dで定義しちゃう) SA_LEN、SET_SIN_LENとSIN_LENはそれぞれポインタを期待してますか? 現物を期待していますか? なんか定義がまちまちに思います。 >write permissionが欲しいですか? > いとじゅんさん >cryptしたpasswdをくだされば追加します. 別便でお願いします。 itojun ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <6667.925467778.2@coconut.itojun.org> Content-Transfer-Encoding: 7bit ? config.log ? config.cache ? config.h ? config.status ? Makefile ? y.tab.h ? miniruby ? rbconfig.rb ? ruby ? ext/extinit.c ? ext/extmk.rb ? ext/config.cache ? ext/curses/Makefile ? ext/dbm/Makefile ? ext/etc/Makefile ? ext/fcntl/Makefile ? ext/kconv/Makefile ? ext/mandel/Makefile ? ext/md5/Makefile ? ext/nkf/Makefile ? ext/socket/Makefile ? ext/tk/Makefile Index: ext/Setup =================================================================== RCS file: /home/cvs/ruby/ext/Setup,v retrieving revision 1.1.1.3 diff -c -r1.1.1.3 Setup *** Setup 1999/01/20 04:59:31 1.1.1.3 --- Setup 1999/04/30 09:58:13 *************** *** 7,13 **** #fcntl #kconv #md5 ! #socket #tkutil #tcltklib #gtk --- 7,13 ---- #fcntl #kconv #md5 ! socket #tkutil #tcltklib #gtk Index: ext/socket/extconf.rb =================================================================== RCS file: /home/cvs/ruby/ext/socket/extconf.rb,v retrieving revision 1.1.1.3.2.4 diff -c -r1.1.1.3.2.4 extconf.rb *** extconf.rb 1999/04/30 08:19:59 1.1.1.3.2.4 --- extconf.rb 1999/04/30 09:58:18 *************** *** 100,106 **** end if $ipv6lib ! if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/#{ipv6lib}.a" $LDFLAGS += " -L#$ipv6libdir -l#$ipv6lib" else print < #include *************** *** 256,263 **** struct sockaddr_storage storage; struct sockaddr_storage *addr = 0; ! addr->_ss_family = &storage.__ss_family; ! addr->_ss_len = &storage.__ss_len; return 0; } EOF --- 260,267 ---- struct sockaddr_storage storage; struct sockaddr_storage *addr = 0; ! addr->__ss_family = &storage.__ss_family; ! addr->__ss_len = &storage.__ss_len; return 0; } EOF Index: ext/socket/socket.c =================================================================== RCS file: /home/cvs/ruby/ext/socket/socket.c,v retrieving revision 1.1.1.3.2.10 diff -c -r1.1.1.3.2.10 socket.c *** socket.c 1999/04/30 08:20:00 1.1.1.3.2.10 --- socket.c 1999/04/30 09:58:53 *************** *** 8,13 **** --- 8,20 ---- ************************************************/ + /* + * NOTE: this has to be placed before any inclusion of header files, + * to cope with version oddity of IPv6 basic API. + */ + #define ss_family __ss_family + #define ss_len __ss_len + #include "ruby.h" #include "rubyio.h" #include "rubysig.h" *************** *** 48,58 **** # include "addrinfo.h" #endif #ifdef SOCKADDR_STORAGE - # define ss_family __ss_family # define SS_LEN(ss) (ss)->__ss_len #else # define SOCKADDR_STORAGE sockaddr # define ss_family sa_family # ifdef SA_LEN # define SS_LEN(ss) SA_LEN(ss) --- 55,94 ---- # include "addrinfo.h" #endif + #ifdef HAVE_SA_LEN + # ifndef SA_LEN + # define SA_LEN(sa) (sa)->sa_len + # endif + # ifndef SIN_LEN + # define SIN_LEN(sin) (sin).sin_len + # endif + # ifndef SET_SIN_LEN + # define SET_SIN_LEN(sin, len) {(sin).sin_len = (len);} + # endif + #else + # ifndef SA_LEN + # ifdef INET6 + # define SA_LEN(sa) \ + (((sa)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr)) + # else + /* by tradition, sizeof(struct sockaddr) covers most of the sockaddrs */ + # define SA_LEN(sa) (sizeof(struct sockaddr)) + # endif + # endif + # ifndef SIN_LEN + # define SIN_LEN(sin) (sizeof(struct sockaddr_in)) + # endif + # ifndef SET_SIN_LEN + # define SET_SIN_LEN(sin, len) { /*nothing to do*/ } + # endif + #endif + #ifdef SOCKADDR_STORAGE # define SS_LEN(ss) (ss)->__ss_len #else # define SOCKADDR_STORAGE sockaddr + # undef ss_family # define ss_family sa_family # ifdef SA_LEN # define SS_LEN(ss) SA_LEN(ss) *************** *** 714,720 **** sin = (struct sockaddr_in *)&addr; memset(sin, 0, sizeof(*sin)); sin->sin_family = AF_INET; ! SET_SIN_LEN(sin, sizeof(*sin)); sin->sin_addr.s_addr = htonl(i); } else { --- 750,756 ---- sin = (struct sockaddr_in *)&addr; memset(sin, 0, sizeof(*sin)); sin->sin_family = AF_INET; ! SET_SIN_LEN(*sin, sizeof(*sin)); sin->sin_addr.s_addr = htonl(i); } else { ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <6667.925467778.3@coconut.itojun.org> Content-Transfer-Encoding: 7bit # simple httpd # The code demonstrates how a multi-protocol daemon should be written. # CAVEAT: # "fork" cannot be replaced with "Thread.start" because TCPserver does not # support multi-threading in TCPserver.accept (at least in ruby 1.2.5). # Frankly, fork isn't really necessary. I hoped to use Thread.start but # I just couldn't. #require "socket" #require "thread" port = 8888 res = Socket.getaddrinfo(nil, port, nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE) sockpool = [] names = [] res.each do |i| s = TCPserver.new(i[3], i[1]) n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ") sockpool.push s names.push n end (0 .. sockpool.size - 1).each do |i| mysock = sockpool[i] myname = names[i] STDERR.print "socket #{mysock} started, address #{myname}\n" fork do # Thread.start cannot be used here! ls = mysock # copy to dynamic variable STDERR.print "socket #{myname} started, pid #{$$}\n" while TRUE as = ls.accept Thread.start do STDERR.print "socket #{myname} accepted, thread ", Thread.current, "\n" s = as # copy to dynamic variable str = s.gets STDERR.print "socket #{myname} got string\n" s.write("Content-type: text/plain\n\n") s.write("this is test: my name is #{myname}, you sent:\n") s.write("---start\n") s.write(str) s.write("---end\n") s.close STDERR.print "socket #{myname} processed, thread ", Thread.current, " terminating\n" end end exit 0 end end sleep 1 # just for message sequencing... STDERR.print "I have #{sockpool.size} children\n" (0 .. sockpool.size - 1).each do |i| STDERR.print Process.wait, " seems to be dead\n" end STDERR.print "all children seems to be dead, bye\n" ------- =_aaaaaaaaaa0--