From: Katsuyuki Komatsu Date: 1999-12-23T14:39:29+09:00 Subject: [ruby-list:19858] Re: [mswin32] TCPSocket::new() raises Errno::ENOENT 小松です。 In the message of [ruby-list:19789] Re: [mswin32] TCPSocket::new() raises Errno::ENOENT on 1999/12/21 17:30:11 Koji Oda wrote: |- if(fptr->f2) myfdclose(fptr->f); |+ if(fptr->f2) myfdclose(fptr->f2); これだと、同じソケットハンドルを2回クローズすることになるので、 NTでVC++のIDEの中から実行していると、EXCEPTION_INVALID_HANDLE (0xC0000008) の例外が発生してしまいます。 ソケットハンドルをDuplicateする方が望ましいと思います。 98とNT4.0+SP5上で ruby 1.5.0 (1999-12-14) [i386-mswin32] で確認しました。 -- 小松克行 / Katsuyuki Komatsu --- ext/socket/socket.c.dist Tue Dec 14 15:49:56 1999 +++ ext/socket/socket.c Thu Dec 23 14:22:10 1999 @@ -89,19 +89,19 @@ int Rconnect(); #ifdef NT -static void -sock_finalize(fptr) - OpenFile *fptr; +static int +sock_dup(fd) + int fd; { - SOCKET s; - extern int errno; - - if (!fptr->f) return; + int fd2; + int error; - myfdclose(fptr->f); - if(fptr->f2) myfdclose(fptr->f); -/* - s = get_osfhandle(fileno(fptr->f)); - closesocket(s); -*/ + error = !DuplicateHandle(GetCurrentProcess(), (HANDLE)fd, + GetCurrentProcess(), (LPHANDLE)&fd2, + 0, TRUE, DUPLICATE_SAME_ACCESS); + if (error) { + errno = GetLastError(); + rb_sys_fail("DuplicateHandle"); + } + return fd2; } #endif @@ -119,5 +119,5 @@ sock_new(class, fd) fp->f = rb_fdopen(fd, "r"); #ifdef NT - fp->finalize = sock_finalize; + fd = sock_dup(fd); #else fd = dup(fd);