とみたです。

Solaris で FIFOファイルを 256個以上オープンしようとすると、おかしなエ
ラーになります。ソケットでも同様です。

% mkfifo /tmp/pipe
% ruby -v -e 'a=[]; 256.times{a<<File.open("/tmp/pipe", File::NONBLOCK)}'
ruby 1.6.8 (2002-12-24) [sparc-solaris2.8]
-e:1:in `open': Error 0 (Errno::E000)
        from -e:1
        from -e:1:in `times'
        from -e:1
% ruby-1.8.1 -v -e 'a=[]; 256.times{a<<File.open("/tmp/pipe", File::NONBLOCK)}'
ruby 1.8.1 (2003-12-25) [sparc-solaris2.8]
-e:1: [BUG] rb_sys_fail() - errno == 0
ruby 1.8.1 (2003-12-25) [sparc-solaris2.8]

Abort

Solaris の stdio(3C) によると、

     Note that no more than 255 files may be opened using fopen(), and
     only file descriptors 0 through 255 can be used in a stream.

ということなので、エラーになるのはいいのですが、Errno::E000 というのは
変ですね。

ちなみに、通常ファイルの場合は、エラーにはなりますが、ちゃんと EMFILE 
になります。

% ruby -v -e 'a=[]; 256.times{a<<File.open("/etc/hosts")}';
ruby 1.6.8 (2002-12-24) [sparc-solaris2.8]
-e:1:in `open': Too many open files - "/etc/hosts" (Errno::EMFILE)
        from -e:1
        from -e:1:in `times'
        from -e:1
% ruby-1.8.1 -v -e 'a=[]; 256.times{a<<File.open("/etc/hosts")}' ;
ruby 1.8.1 (2003-12-25) [sparc-solaris2.8]
-e:1:in `initialize': Too many open files - /etc/hosts (Errno::EMFILE)
        from -e:1:in `open'
        from -e:1
        from -e:1:in `times'
        from -e:1

ちょっと調べてみたところ、fdopen(3C) の

     The fdopen() function may fail and not set errno if there are no
     free stdio streams.

「エラーなのに errno を設定しない」というのが影響しているようです。

ということで、ruby 1.8.1 用のパッチです。

*** io.c.orig	Wed Dec 24 17:47:36 2003
--- io.c	Wed Apr  7 22:31:19 2004
***************
*** 1869,1884 ****
--- 1869,1891 ----
      FILE *file;
  
      file = fdopen(fd, mode);
      if (!file) {
+ #if defined(sun) && defined(sparc)
+ 	if (errno == 0 || errno == EMFILE || errno == ENFILE) {
+ #else
  	if (errno == EMFILE || errno == ENFILE) {
+ #endif
  	    rb_gc();
  	    file = fdopen(fd, mode);
  	}
  	if (!file) {
  #ifdef _WIN32
  	    if (errno == 0) errno = EINVAL;
  #endif
+ #if defined(sun) && defined(sparc)
+ 	    if (errno == 0) errno = EMFILE;
+ #endif
  	    rb_sys_fail(0);
  	}
      }
  

-- 
とみたまさひろ <tommy / tmtm.org>