山本です。 一番肝心な ___topen という関数が「未定義です」というエラーになってしまって、うまくいき ませんでした。 しかたないので、EINVAL にも対処してお茶を濁しました。その他の fp == NULL && errno == 0 のケースはほぼ ENOMEM なのですが、fp->token != fp のときなど、バリデーションチェックに も使われているので、念のため保留しました。 Index: lib/drb/drb.rb =================================================================== RCS file: /var/cvs/src/ruby/lib/drb/drb.rb,v retrieving revision 1.19 diff -u -w -b -p -r1.19 drb.rb --- lib/drb/drb.rb 16 May 2004 15:09:52 -0000 1.19 +++ lib/drb/drb.rb 22 Jun 2004 03:09:29 -0000 @@ -702,6 +702,8 @@ module DRb rescue DRbBadScheme rescue DRbConnError raise($!) + rescue Errno::ENFILE, Errno::EMFILE + raise($!) rescue raise(DRbConnError, "#{uri} - #{$!.inspect}") end @@ -1075,16 +1077,29 @@ module DRb @pool = new_pool end - conn = self.new(remote_uri) unless conn + until conn + begin + conn = self.new(remote_uri) + rescue Errno::ENFILE, Errno::EMFILE + @mutex.synchronize do + raise(DRbConnError, "#{remote_uri} - #{$!.inspect}") if @pool.empty? + @pool.pop.close + end + end + end + succ, result = yield(conn) return succ, result ensure + if conn @mutex.synchronize do - if @pool.size > POOL_SIZE or ! succ - conn.close if conn - else + if succ @pool.unshift(conn) + @pool.pop.close while @pool.size > POOL_SIZE + else + conn.close + end end end end Index: win32/win32.c =================================================================== RCS file: /var/cvs/src/ruby/win32/win32.c,v retrieving revision 1.117 diff -u -w -b -p -r1.117 win32.c --- win32/win32.c 21 Jun 2004 00:27:39 -0000 1.117 +++ win32/win32.c 22 Jun 2004 02:46:40 -0000 @@ -2726,6 +2726,89 @@ isUNCRoot(const char *path) } #ifdef __BORLANDC__ +static int +too_many_files(void) +{ + register FILE *fp; + for (fp = _streams; fp < _streams + _nfile; fp++) + if (fp->fd < 0) return 0; + return 1; +} +static int +invalid_type(register const char *type) +{ + switch (*type++) { + case 'r': + case 'w': + case 'a': + break; + default: + return 1; + } + if (*type == '+') type++; + switch (*type) { + case 't': + case 'b': + case '+': + case '\0': + return 0; + default: + return 1; + } +} +#undef fopen +FILE * +rb_w32_fopen(const char *path, const char *type) +{ + if (too_many_files()) { + errno = EMFILE; + return NULL; + } + else if (invalid_type(type)) { + errno = EINVAL; + return NULL; + } + else { + errno = 0; + return fopen(path, type); + } +} +FILE * +rb_w32_fdopen(int handle, char *type) +{ + if (handle < 0) { + errno = EBADF; + return NULL; + } + else if (too_many_files()) { + errno = EMFILE; + return NULL; + } + else if (invalid_type(type)) { + errno = EINVAL; + return NULL; + } + else { + errno = 0; + return _fdopen(handle, type); + } +} +FILE * +rb_w32_fsopen(const char *path, const char *type, int shflag) +{ + if (too_many_files()) { + errno = EMFILE; + return NULL; + } + else if (invalid_type(type)) { + errno = EINVAL; + return NULL; + } + else { + errno = 0; + return _fsopen(path, type, shflag); + } +} #undef fstat int rb_w32_fstat(int fd, struct stat *st) @@ -3034,10 +3117,14 @@ rb_w32_getc(FILE* stream) else #endif { +#if defined __BORLANDC__ || defined _WIN32_WCE + errno = 0; +#endif c = _filbuf(stream); #if defined __BORLANDC__ || defined _WIN32_WCE if ((c == EOF) && (errno == EPIPE)) { clearerr(stream); + stream->flags |= _F_EOF; } #endif rb_trap_immediate = trap_immediate; @@ -3065,6 +3152,22 @@ rb_w32_putc(int c, FILE* stream) } return c; } + +#if defined __BORLANDC__ || defined _WIN32_WCE +#undef fread +size_t +rb_w32_fread(void *ptr, size_t size, size_t n, FILE *stream) +{ + size_t i; + errno = 0; + i = fread(ptr, size, n, stream); + if ((i < n) && (errno == EPIPE)) { + clearerr(stream); + stream->flags |= _F_EOF; + } + return i; +} +#endif struct asynchronous_arg_t { /* output field */ Index: win32/win32.h =================================================================== RCS file: /var/cvs/src/ruby/win32/win32.h,v retrieving revision 1.51 diff -u -w -b -p -r1.51 win32.h --- win32/win32.h 19 Feb 2004 09:08:23 -0000 1.51 +++ win32/win32.h 21 Jun 2004 16:44:57 -0000 @@ -115,6 +115,16 @@ extern "C++" { #define sopen _sopen #undef fstat #define fstat(fd,st) rb_w32_fstat(fd,st) +#undef fopen +#define fopen(p, t) rb_w32_fopen(p, t) +#undef fdopen +#define fdopen(h, t) rb_w32_fdopen(h, t) +#undef fsopen +#define fsopen(p, t, f) rb_w32_fsopen(p, t, f) +#endif +#if defined __BORLANDC__ || defined _WIN32_WCE +#undef fread +#define fread(p, m, n, stream) rb_w32_fread(p, m, n, stream) #endif #define fsync(h) _commit(h) #undef stat @@ -178,6 +188,15 @@ extern int rb_w32_spawn(int, const char extern int rb_w32_aspawn(int, const char *, char *const *); extern int kill(int, int); extern pid_t rb_w32_getpid(void); +#ifdef __BORLANDC__ +extern int rb_w32_fstat(int fd, struct stat *st); +extern FILE *rb_w32_fopen(const char *path, const char *type); +extern FILE *rb_w32_fdopen(int handle, char *type); +extern FILE *rb_w32_fsopen(const char *path, const char *type, int shflag); +#endif +#if defined __BORLANDC__ || defined _WIN32_WCE +extern size_t rb_w32_fread(void *ptr, size_t size, size_t n, FILE *stream); +#endif #include <float.h> #if !defined __MINGW32__ || defined __NO_ISOCEXT