きりかノート 3冊め

おあそびプログラミング

Snow LeopardでTCPServer.open("localhost", 0)がSocketError

とかとたぶん同じ話。

Snow Leopard上のrubyで、

 % ruby -rsocket -e 'TCPServer.open("localhost", 0)'
 -e:1:in `initialize': getaddrinfo: nodename nor servname provided, or not known
 (SocketError)
         from -e:1:in `open'
         from -e:1

となってしまって、test-allでdrbやnet/popのテストが失敗しまくる。Mac OS X 10.5.8では問題ない。

理由はよくわからないけど、getaddrinfoのサービス名として文字の"0"を渡すのがダメみたい。しかたないのでNULLを返すようにしてしまう。

 % cat patch-ext-socket-socket.c
 --- ext/socket/socket.c.orig  2009-01-27 15:18:04.000000000 +0900
 +++ ext/socket/socket.c       2010-01-16 01:45:57.000000000 +0900
 @@ -876,6 +876,12 @@
         return 0;
      }
      else if (FIXNUM_P(port)) {
 +#if defined(__APPLE__)
 +     // Mac OS X 10.6 does not accept service name "0". it should be NULL.
 +     if (FIX2LONG(port) == 0) {
 +         return 0;
 +     }
 +#endif
         snprintf(pbuf, len, "%ld", FIX2LONG(port));
         return pbuf;
      }
 @@ -887,6 +893,12 @@
         if (strlen(serv) >= len) {
             rb_raise(rb_eArgError, "service name too long (%d)", strlen(serv));
         }
 +#if defined(__APPLE__)
 +     // Mac OS X 10.6 does not accept service name "0". it should be NULL.
 +     if (strcmp(serv, "0") == 0) {
 +         return 0;
 +     }
 +#endif
         strcpy(pbuf, serv);
         return pbuf;
      }

これでruby-1.8(r26325)とruby-1.8.7-p249で問題のテストが通るようになった。けど、これでいいかよくわからん。

先に挙げたリンクでは、DNSの検索ドメインが影響しているということもあるようだけど、じぶんのところでは検索ドメインが未指定でもエラー。

 % scutil --dns
 DNS configuration

 resolver #1
   domain : *****.**.****.ne.jp
   nameserver[0] : 192.168.1.1
   order   : 200000

 resolver #2
   domain : local
   options : mdns
   timeout : 2
   order   : 300000
     :

再現するとか問題ないとか情報ありましたら教えてください。redmineに登録するには確証が足りないのです。

(2010/01/16 追記)Snow Leopard組み込みの/usr/bin/rubyでも再現するので、修正とは別にbugreport.apple.comに現象を報告しました。

(2010/01/20 追記)macports #15528Ruby Forumの"DRb Problems with Mac OS X 10.5.3"と同じ問題のよう。10.5でも起きてたんだね。