From: nobuyoshi nakada Date: 2005-05-26T18:26:49+09:00 Subject: Re: shim for select() for VMS & general porting questions Hi, At Thu, 26 May 2005 08:47:11 +0900, nobu.nokada@softhome.net wrote in [ruby-core:05101]: > > I'm also uncertain where this stuff all properly belongs. There is a > > vms/vmsruby_private.c for which I see no equivalent file in other ports. > > There are no comments explaining what the file is for, so it is not > > clear what the author's intent was in designating these as "private". > > I did see just CVS trunk, not 1.8 branch. Those apparently > haven't been committed to the trunk yet, irregularly. I added > them to the trunk now. Moved all to vmsruby_private.[ch]. Does this work? Index: vms/config.h =================================================================== RCS file: /cvs/ruby/src/ruby/vms/config.h,v retrieving revision 1.2 diff -U2 -p -r1.2 config.h --- vms/config.h 14 May 2005 14:57:03 -0000 1.2 +++ vms/config.h 26 May 2005 03:34:52 -0000 @@ -112,4 +112,5 @@ #define SIZEOF_FLOAT 4 #define SIZEOF_DOUBLE 8 +#define SIZEOF_LONG_LONG 8 #if defined(__vax) Index: vms/vms.h =================================================================== RCS file: /cvs/ruby/src/ruby/vms/vms.h,v retrieving revision 1.3 diff -U2 -p -r1.3 vms.h --- vms/vms.h 26 Dec 2003 01:38:31 -0000 1.3 +++ vms/vms.h 26 May 2005 09:13:07 -0000 @@ -11,3 +11,2 @@ extern int snprintf(); #define LONG_LONG long long -#define SIZEOF_LONG_LONG sizeof(long long) Index: vms/vmsruby_private.c =================================================================== RCS file: /cvs/ruby/src/ruby/vms/vmsruby_private.c,v retrieving revision 1.2 diff -U2 -p -r1.2 vmsruby_private.c --- vms/vmsruby_private.c 25 May 2005 23:35:25 -0000 1.2 +++ vms/vmsruby_private.c 26 May 2005 09:13:41 -0000 @@ -1,5 +1,8 @@ -#include "vmsruby_private.h" #include #include +#include . +#include +#include +#include "vmsruby_private.h" void _vmsruby_init(void) @@ -51,2 +54,87 @@ long _vmsruby_set_switch(char *name, cha return status; } + +static int +is_socket(int fd) +{ + int type, len; + + len = sizeof(type); + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&type, &len) == 0) + return 1; + if (errno == ENOTSOCK) errno = 0; + + return 0; +} + +#undef select +int +rb_vms_select(int maxfd, fd_set *rfd, fd_set *wfd, fd_set *efd, struct timeval *tv) +{ + int i, maxsock, socks, nsocks, ret; + fd_set rs, ws, es, *rp, *wp, *ep; + struct timeval z; + + FD_ZERO(&rs); + FD_ZERO(&ws); + FD_ZERO(&es); + + /* count socket and non-socket fds */ + maxsock = socks = nsocks = 0; + if (rfd || wfd || efd) { + for (i = 0; i < maxfd; ++i) { + int r = (rfd != 0) && FD_ISSET(i, rfd); + int w = (wfd != 0) && FD_ISSET(i, wfd); + int e = (efd != 0) && FD_ISSET(i, efd); + if (!r && !w && !e) continue; + if (is_socket(i)) { + if (r) FD_SET(i, (rp = &rs)); + if (w) FD_SET(i, (wp = &ws)); + if (e) FD_SET(i, (ep = &es)); + maxsock = i + 1; + socks++; + } + else { + nsocks++; + } + } + } + + if (!nsocks) { + /* sockets only */ + return select(maxsock, rfd, wfd, efd, tv); + } + + if (!socks) { + /* assuming non-socket fds are always ready */ + return nsocks; + } + + /* check if sockets are ready */ + z.tv_sec = 0; + z.tv_usec = 0; + ret = select(maxsock, rp, wp, ep, &z); + if (ret < 0) { + if (rfd) *rfd = rs; + if (wfd) *wfd = ws; + if (efd) *efd = es; + return nsocks; + } + + for (i = 0; i < maxsock; ++i) { + if (rp && FD_ISSET(i, rp)) { + FD_SET(i, rfd); + ret++; + } + if (wp && FD_ISSET(i, wp)) { + FD_SET(i, wfd); + ret++; + } + if (ep && FD_ISSET(i, ep)) { + FD_SET(i, efd); + ret++; + } + } + + return ret; +} Index: vms/vmsruby_private.h =================================================================== RCS file: /cvs/ruby/src/ruby/vms/vmsruby_private.h,v retrieving revision 1.2 diff -U2 -p -r1.2 vmsruby_private.h --- vms/vmsruby_private.h 25 May 2005 23:35:25 -0000 1.2 +++ vms/vmsruby_private.h 26 May 2005 09:12:36 -0000 @@ -5,3 +5,6 @@ void _vmsruby_init(void); long _vmsruby_set_switch(char *, char *); +int rb_vms_select(int, fd_set*, fd_set*, fd_set*, struct timeval*); +#define select(n, r, w, e, t) rb_vms_select(n, r, w, e, t) + #endif /* VMSRUBY_H_INCLUDED */ -- Nobu Nakada