なかだです。 At Wed, 1 Jun 2005 09:22:18 +0900, Tanaka Akira wrote in [ruby-dev:26256]: > > fd_setの実装に激しく依存するような気はしますが。 > > * メモリを確保するときに少なくとも sizeof(fd_set) は確保する > * 最初に確保したときに MEMZERO の後で FD_ZERO で初期化 > > とすれば、(FD_SETSIZE 個までは) ポータブルな記述になる気がします。 こんな感じでしょうか。 typedef struct { int maxfd; fd_set *fdset; } rb_fdset_t; void rb_fd_init(fds) volatile rb_fdset_t *fds; { fds->maxfd = 0; fds->fdset = ALLOC(fd_set); FD_ZERO(fds->fdset); } void rb_fd_term(fds) rb_fdset_t *fds; { if (fds->fdset) free(fds->fdset); fds->maxfd = 0; fds->fdset = 0; } void rb_fd_zero(fds) rb_fdset_t *fds; { if (fds->fdset) { MEMZERO(fds->fdset, fd_mask, howmany(fds->maxfd, NFDBITS)); if (sizeof(fd_set) * CHAR_BIT != howmany(FD_SETSIZE, NFDBITS) * NFDBITS) FD_ZERO(fds->fdset); } } void rb_fd_set(n, fds) int n; rb_fdset_t *fds; { int m, o; if (n < FD_SETSIZE) m = sizeof(fd_set); else m = howmany(n + 1, NFDBITS) * NFDBITS; if (fds->maxfd <= FD_SETSIZE) o = sizeof(fd_set); else o = howmany(fds->maxfd, NFDBITS) * NFDBITS; if (m > o) { fds->fdset = realloc(fds->fdset, m); memset((char *)fds->fdset + o, 0, m - o); } if (n >= fds->maxfd) fds->maxfd = n + 1; FD_SET(n, fds->fdset); } void rb_fd_clr(n, fds) int n; rb_fdset_t *fds; { if (n > FD_SETSIZE && n >= fds->maxfd) return; FD_CLR(n, fds->fdset); } int rb_fd_isset(n, fds) int n; const rb_fdset_t *fds; { if (n > FD_SETSIZE && n >= fds->maxfd) return 0; return FD_ISSET(n, fds->fdset); } void rb_fd_copy(dst, src, max) rb_fdset_t *dst; const fd_set *src; int max; { int size = sizeof(fd_set); if ((dst->maxfd = max) > FD_SETSIZE) { size = howmany(max, NFDBITS) * NFDBITS; } dst->fdset = realloc(dst->fdset, size); memcpy(dst->fdset, src, size); } > # Windows の fd_set は違うというので探したら、 > # http://msdn.microsoft.com/library/en-us/winsock/winsock/fd_set_2.asp > # を見る限りは MEMZERO だけでよさそうですねぇ。 そもそもwinsockがFD_SETSIZE以上を見てくれるかどうか、というより もWaitForMultipleObjects()が見てくれなさげ。 -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦