新井です。

fcntl(fd, F_SETLK, &lock) 

は、ロック済みの場合うちの48の環境では EACCES を返すので 
flock() が false を返さず例外になります。lockf() を使う実装
ではEACCES、EAGAIN をEWOULDBLOCKに直しているのでそれにあわせ
ました。

# glibc のマニュアルを見ると、fcntl() もEAGAINまたはEACCESのようなので

ただ、EWOULDBLOCK は定義されているとは限らないようなので呼び
出し側で EWOULDBLOCK、EAGAIN、EACCES それぞれをtrapするよう
な修正にしてます。

以上、missing/flock.c file.c:rb_file_flock() の修正

さらに、今は使ってない file.c:rb_thread_flock() は 
EWOULDBLOCK 等でbreak してましたが、continue なんではないか
なと思います。そして、EINTR が発生するかどうかはわからないの
ですが発生すれば-1 で return しても良いかと思い、case をはず
しました。

そして、error.c の修正は上記とは関係ないのですが、現在のrubyでは
  EWOULDBLOCK と EAGAIN が同じ値のシステム
の場合どちらの例外があがるかはrubyの実装依存になります。

これは利用者が困る場合があるのではないかと思い、
同じ値の errno に対してクラスを1つにし、他はそれを代入した
定数にしてみました。

p Errno::EWOULDBLOCK
=> Errno::EAGAIN

となったりするので、エラーメッセージを見た人は混乱するかも知
れませんが。。。
# __BEOS__ のところは一切触れていません。

以上、修正内容に関してご検証願います。


Index: file.c =================================================================== RCS file: /src/ruby/file.c,v retrieving revision 1.51 diff -u -p -u -r1.51 file.c --- file.c 2001/03/21 03:51:23 1.51 +++ file.c 2001/03/25 07:52:48 @@ -1584,7 +1584,7 @@ rb_file_truncate(obj, len) # define LOCK_UN 8 # endif -#if defined(EWOULDBLOCK) && 0 +#if 0 static int rb_thread_flock(fd, op, fptr) int fd, op; @@ -1596,11 +1596,14 @@ rb_thread_flock(fd, op, fptr) op |= LOCK_NB; while (flock(fd, op) < 0) { switch (errno) { - case EINTR: /* can be happen? */ + case EAGAIN: + case EACCES: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EWOULDBLOCK: +#endif rb_thread_polling(); /* busy wait */ rb_io_check_closed(fptr); - break; + continue; default: return -1; } @@ -1629,11 +1632,14 @@ rb_file_flock(obj, operation) ret = flock(fileno(fptr->f), NUM2INT(operation)); TRAP_END; if (ret < 0) { -#ifdef EWOULDBLOCK - if (errno == EWOULDBLOCK) { - return Qfalse; - } + switch (errno) { + case EAGAIN: + case EACCES: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: #endif + return Qfalse; + } rb_sys_fail(fptr->path); } #endif Index: missing/flock.c =================================================================== RCS file: /src/ruby/missing/flock.c,v retrieving revision 1.5 diff -u -p -u -r1.5 flock.c --- missing/flock.c 2001/02/26 05:29:06 1.5 +++ missing/flock.c 2001/03/25 07:53:08 @@ -94,7 +94,6 @@ flock(fd, operation) int fd; int operation; { - int i; switch (operation) { /* LOCK_SH - get a shared lock */ @@ -103,8 +102,7 @@ flock(fd, operation) return -1; /* LOCK_EX - get an exclusive lock */ case LOCK_EX: - i = lockf (fd, F_LOCK, 0); - break; + return lockf (fd, F_LOCK, 0); /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */ case LOCK_SH|LOCK_NB: @@ -112,24 +110,17 @@ flock(fd, operation) return -1; /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */ case LOCK_EX|LOCK_NB: - i = lockf (fd, F_TLOCK, 0); - if (i == -1) - if ((errno == EAGAIN) || (errno == EACCES)) - errno = EWOULDBLOCK; - break; + return lockf (fd, F_TLOCK, 0); /* LOCK_UN - unlock */ case LOCK_UN: - i = lockf (fd, F_ULOCK, 0); - break; + return lockf (fd, F_ULOCK, 0); /* Default - can't decipher operation */ default: - i = -1; errno = EINVAL; - break; + return -1; } - return i; } #elif !defined NT int Index: error.c =================================================================== RCS file: /src/ruby/error.c,v retrieving revision 1.25 diff -u -r1.25 error.c --- error.c 2001/02/19 09:14:58 1.25 +++ error.c 2001/03/25 08:16:07 @@ -485,12 +485,11 @@ const char *name; { #ifdef __BEOS__ - VALUE *list; - int ix, offset; -#endif + VALUE *list; + int ix, offset; VALUE error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError); rb_define_const(error, "Errno", INT2FIX(i)); -#ifdef __BEOS__ + if (i == B_ERROR) { syserr_error = error; rb_global_variable(&syserr_error); @@ -507,12 +506,22 @@ rb_global_variable(&list[i & 0xff]); } } + return error; #else - if (i <= sys_nerr) { - syserr_list[i] = error; - } + if (i <= sys_nerr && syserr_list[i]) { + VALUE error = syserr_list[i]; + rb_define_const(rb_mErrno, name, error); + return error; + } + else { + VALUE error = rb_define_class_under(rb_mErrno, name, + rb_eSystemCallError); + rb_define_const(error, "Errno", INT2FIX(i)); + if (i <= sys_nerr) + syserr_list[i] = error; + return error; + } #endif - return error; } static VALUE