summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog56
-rw-r--r--bignum.c2
-rw-r--r--configure.in2
-rw-r--r--ext/socket/socket.c100
-rw-r--r--gc.c12
-rw-r--r--lib/debug.rb25
-rw-r--r--lib/jcode.rb2
-rw-r--r--lib/matrix.rb4
-rw-r--r--lib/thwait.rb4
-rw-r--r--lib/tracer.rb4
-rw-r--r--ruby.c34
-rw-r--r--version.h4
-rw-r--r--win32/ruby.def1
-rw-r--r--win32/win32.c108
-rw-r--r--win32/win32.h4
15 files changed, 251 insertions, 111 deletions
diff --git a/ChangeLog b/ChangeLog
index c1f6a1d0dc..f0ecd1c982 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Wed Jun 28 17:26:06 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * ext/socket/socket.c (ip_recvfrom): udp_recvfrom and tcp_recvfrom
+ is merged and moved to IPSocket#recvfrom.
+
+ * ext/socket/socket.c (sock_s_getaddrinfo): family can be a
+ strings such as "AF_INET" etc.
+
+ * ruby.c (require_libraries): . and RUBYLIB added to $load_path
+ just before -r procedure.
+
+ * ruby.c (proc_options): -e, - did not exec -r.
+
+Wed Jun 28 10:11:06 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * gc.c: gc trigger threshold changed; GC_NEWOBJ_LIMIT removed,
+ FREE_MIN is increased to 4096.
+
Tue Jun 27 22:39:28 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.24.
@@ -14,16 +32,54 @@ Tue Jun 27 22:39:28 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
can use 1.2 implementation of head, get, post, put.
(see document)
+Tue Jun 27 12:05:10 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
+
+ * win32.c (myfdclr): new function.
+
+ * win32.h: add FD_CLR.
+
Mon Jun 26 23:41:41 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* ruby.h: add cast for ANSI style.
* gc.c (rb_data_object_alloc): use RUBY_DATA_FUNC.
+Mon Jun 26 22:20:03 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
+
+ * win32/win32.c (is_socket, extract_file_fd): New function.
+
+ * win32/win32.c (myfdopen): use is_socket().
+
+ * win32/win32.c (myselect): return non socket files immediately
+ if file and socket handles are mixed.
+
+Mon Jun 26 16:21:30 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * eval.c (rb_thread_schedule): wait_for cleared too early.
+
+Mon Jun 26 09:15:31 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * pack.c: remove obsolete 'F', 'D' specifiers.
+
+Sun Jun 25 00:55:03 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
+
+ * ext/socket/socket.c (sock_s_getnameinfo): `res' would not
+ be assigned if TYPE(sa) == T_STRING.
+
Sat Jun 24 14:36:29 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
* config*.dj, configure.bat, top.sed: move to djgpp/.
+Sat Jun 24 02:34:17 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * ruby.c (load_file): call require_libraries() here to let
+ debug.rb work properly.
+
+Fri Jun 23 22:34:51 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
+
+ * bignum.c (rb_big_lshift): reorder xds assignment to avoid
+ reusing `x' as `len' by VC++ 6.0 SP3 compiler with -Ox switch.
+
Fri Jun 23 01:11:27 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_substr): should return empty string (""),
diff --git a/bignum.c b/bignum.c
index 385ec7b4e3..9510be66ed 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1216,13 +1216,13 @@ rb_big_lshift(x, y)
long len, i;
if (shift < 0) return rb_big_rshift(x, INT2FIX(-shift));
- xds = BDIGITS(x);
len = RBIGNUM(x)->len;
z = bignew(len+s1+1, RBIGNUM(x)->sign);
zds = BDIGITS(z);
for (i=0; i<s1; i++) {
*zds++ = 0;
}
+ xds = BDIGITS(x);
for (i=0; i<len; i++) {
num = num | *xds++<<s2;
*zds++ = BIGLO(num);
diff --git a/configure.in b/configure.in
index 667b43fd97..1997e8cacb 100644
--- a/configure.in
+++ b/configure.in
@@ -520,7 +520,7 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=yes ;;
aix*) LDSHARED='/usr/ccs/bin/ld'
XLDFLAGS='-Wl,-bE:ruby.imp'
- DLDFLAGS='-eInit_$(TARGET) -bI:$(topdir)/ruby.imp -bM:SRE -T512 -H512 -lc'
+ DLDFLAGS='-brtl -eInit_$(TARGET) -bI:$(topdir)/ruby.imp -bM:SRE -T512 -H512 -lc'
LDFLAGS="-brtl"
rb_cv_dlopen=yes ;;
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 7f37f17174..d46092f119 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -413,14 +413,13 @@ static VALUE unixaddr _((struct sockaddr_un *));
enum sock_recv_type {
RECV_RECV, /* BasicSocket#recv(no from) */
- RECV_TCP, /* TCPSocket#recvfrom */
- RECV_UDP, /* UDPSocket#recvfrom */
+ RECV_IP, /* IPSocket#recvfrom */
RECV_UNIX, /* UNIXSocket#recvfrom */
RECV_SOCKET, /* Socket#recvfrom */
};
static VALUE
-s_recv(sock, argc, argv, from)
+s_recvfrom(sock, argc, argv, from)
VALUE sock;
int argc;
VALUE *argv;
@@ -472,8 +471,7 @@ s_recv(sock, argc, argv, from)
switch (from) {
case RECV_RECV:
return (VALUE)str;
- case RECV_TCP:
- case RECV_UDP:
+ case RECV_IP:
#if 0
if (alen != sizeof(struct sockaddr_in)) {
rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
@@ -495,7 +493,7 @@ bsock_recv(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
- return s_recv(sock, argc, argv, RECV_RECV);
+ return s_recvfrom(sock, argc, argv, RECV_RECV);
}
static VALUE
@@ -613,6 +611,15 @@ ip_addrsetup(host, port)
return res;
}
+static VALUE
+ip_recvfrom(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return s_recvfrom(sock, argc, argv, RECV_IP);
+}
+
static void
setipaddr(name, addr)
VALUE name;
@@ -635,6 +642,9 @@ ipaddr(sockaddr)
char hbuf[1024], pbuf[1024];
switch (sockaddr->sa_family) {
+ case AF_UNSPEC:
+ family = rb_str_new2("AF_UNSPEC");
+ break;
case AF_INET:
family = rb_str_new2("AF_INET");
break;
@@ -643,8 +653,18 @@ ipaddr(sockaddr)
family = rb_str_new2("AF_INET6");
break;
#endif
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ family = rb_str_new2("AF_LOCAL");
+ break;
+#elif AF_UNIX
+ case AF_UNIX:
+ family = rb_str_new2("AF_UNIX");
+ break;
+#endif
default:
- family = 0;
+ sprintf(pbuf, "unknown:%d", sockaddr->sa_family);
+ family = rb_str_new2(pbuf);
break;
}
if (!do_not_reverse_lookup) {
@@ -1068,15 +1088,6 @@ tcp_accept(sock)
(struct sockaddr*)&from, &fromlen);
}
-static VALUE
-tcp_recvfrom(argc, argv, sock)
- int argc;
- VALUE *argv;
- VALUE sock;
-{
- return s_recv(sock, argc, argv, RECV_TCP);
-}
-
#ifdef HAVE_SYS_UN_H
static VALUE
open_unix(class, path, server)
@@ -1284,15 +1295,6 @@ udp_send(argc, argv, sock)
return INT2FIX(n);
}
-static VALUE
-udp_recvfrom(argc, argv, sock)
- int argc;
- VALUE *argv;
- VALUE sock;
-{
- return s_recv(sock, argc, argv, RECV_UDP);
-}
-
#ifdef HAVE_SYS_UN_H
static VALUE
unix_s_sock_open(sock, path)
@@ -1331,7 +1333,7 @@ unix_recvfrom(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
- return s_recv(sock, argc, argv, RECV_UNIX);
+ return s_recvfrom(sock, argc, argv, RECV_UNIX);
}
static VALUE
@@ -1574,7 +1576,7 @@ sock_recvfrom(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
- return s_recv(sock, argc, argv, RECV_SOCKET);
+ return s_recvfrom(sock, argc, argv, RECV_SOCKET);
}
static VALUE
@@ -1828,12 +1830,21 @@ sock_s_getaddrinfo(argc, argv)
}
MEMZERO(&hints, struct addrinfo, 1);
- if (!NIL_P(family)) {
- hints.ai_family = NUM2INT(family);
- }
- else {
+ if (NIL_P(family)) {
hints.ai_family = PF_UNSPEC;
}
+ else if (FIXNUM_P(family)) {
+ hints.ai_family = FIX2INT(family);
+ }
+ else if (strcmp(STR2CSTR(family), "AF_INET") == 0) {
+ hints.ai_family = PF_INET;
+ }
+#ifdef INET6
+ else if (strcmp(STR2CSTR(family), "AF_INET6") == 0) {
+ hints.ai_family = PF_INET6;
+ }
+#endif
+
if (!NIL_P(socktype)) {
hints.ai_socktype = NUM2INT(socktype);
}
@@ -1961,19 +1972,21 @@ sock_s_getnameinfo(argc, argv)
error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),
pbuf, sizeof(pbuf), fl);
if (error) goto error_exit;
- for (r = res->ai_next; r; r = r->ai_next) {
- char hbuf2[1024], pbuf2[1024];
-
- sap = r->ai_addr;
- error = getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2),
- pbuf2, sizeof(pbuf2), fl);
- if (error) goto error_exit;
- if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
- freeaddrinfo(res);
- rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename");
+ if (res) {
+ for (r = res->ai_next; r; r = r->ai_next) {
+ char hbuf2[1024], pbuf2[1024];
+
+ sap = r->ai_addr;
+ error = getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2),
+ pbuf2, sizeof(pbuf2), fl);
+ if (error) goto error_exit;
+ if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
+ freeaddrinfo(res);
+ rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename");
+ }
}
+ freeaddrinfo(res);
}
- freeaddrinfo(res);
return rb_assoc_new(rb_tainted_str_new2(hbuf), rb_tainted_str_new2(pbuf));
error_exit:
@@ -2020,6 +2033,7 @@ Init_socket()
rb_define_global_const("IPsocket", rb_cIPSocket);
rb_define_method(rb_cIPSocket, "addr", ip_addr, 0);
rb_define_method(rb_cIPSocket, "peeraddr", ip_peeraddr, 0);
+ rb_define_method(rb_cIPSocket, "recvfrom", ip_recvfrom, -1);
rb_define_singleton_method(rb_cIPSocket, "getaddress", ip_s_getaddress, 1);
rb_cTCPSocket = rb_define_class("TCPSocket", rb_cIPSocket);
@@ -2027,7 +2041,6 @@ Init_socket()
rb_define_singleton_method(rb_cTCPSocket, "open", tcp_s_open, 2);
rb_define_singleton_method(rb_cTCPSocket, "new", tcp_s_open, 2);
rb_define_singleton_method(rb_cTCPSocket, "gethostbyname", tcp_s_gethostbyname, 1);
- rb_define_method(rb_cTCPSocket, "recvfrom", tcp_recvfrom, -1);
#ifdef SOCKS
rb_cSOCKSSocket = rb_define_class("SOCKSSocket", rb_cTCPSocket);
@@ -2052,7 +2065,6 @@ Init_socket()
rb_define_method(rb_cUDPSocket, "connect", udp_connect, 2);
rb_define_method(rb_cUDPSocket, "bind", udp_bind, 2);
rb_define_method(rb_cUDPSocket, "send", udp_send, -1);
- rb_define_method(rb_cUDPSocket, "recvfrom", udp_recvfrom, -1);
#ifdef HAVE_SYS_UN_H
rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket);
diff --git a/gc.c b/gc.c
index 8257143f9c..c615db031e 100644
--- a/gc.c
+++ b/gc.c
@@ -46,13 +46,10 @@ static void run_final();
#define GC_MALLOC_LIMIT 400000
#endif
#endif
-#define GC_NEWOBJ_LIMIT 10000
static unsigned long malloc_memories = 0;
static unsigned long alloc_objects = 0;
-static int malloc_called = 0;
-
static void
mem_error(mesg)
char *mesg;
@@ -74,17 +71,16 @@ ruby_xmalloc(size)
}
if (size == 0) size = 1;
malloc_memories += size;
- if (malloc_memories > GC_MALLOC_LIMIT && alloc_objects > GC_NEWOBJ_LIMIT) {
+ if (malloc_memories > GC_MALLOC_LIMIT) {
rb_gc();
}
- malloc_called++;
mem = malloc(size);
if (!mem) {
rb_gc();
mem = malloc(size);
if (!mem) {
if (size >= 10 * 1024 * 1024) {
- rb_raise(rb_eNoMemError, "try to allocate too big memory");
+ rb_raise(rb_eNoMemError, "tryed to allocate too big memory");
}
mem_error("failed to allocate memory");
}
@@ -124,7 +120,7 @@ ruby_xrealloc(ptr, size)
mem = realloc(ptr, size);
if (!mem)
if (size >= 10 * 1024 * 1024) {
- rb_raise(rb_eNoMemError, "try to re-allocate too big memory");
+ rb_raise(rb_eNoMemError, "tryed to re-allocate too big memory");
}
mem_error("failed to allocate memory(realloc)");
}
@@ -244,7 +240,7 @@ static int heaps_length = 0;
static int heaps_used = 0;
#define HEAP_SLOTS 10000
-#define FREE_MIN 512
+#define FREE_MIN 4096
static RVALUE *himem, *lomem;
diff --git a/lib/debug.rb b/lib/debug.rb
index 2f61e8da34..d20d1ebbfc 100644
--- a/lib/debug.rb
+++ b/lib/debug.rb
@@ -7,6 +7,14 @@ if $SAFE > 0
end
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
+require 'tracer'
+class Tracer
+ def Tracer.trace_func(*vars)
+ Single.trace_func *vars
+ end
+end
+
+
class DEBUGGER__
class Mutex
def initialize
@@ -80,6 +88,7 @@ class DEBUGGER__
@no_step = nil
@frames = []
@finish_pos = 0
+ @trace = false
end
def stop_next(n=1)
@@ -216,6 +225,20 @@ class DEBUGGER__
end
case input
+ when /^\s*tr(?:ace)?(?:\s+(on|off))?$/
+ if !defined?( $1 )
+ @trace = !@trace
+ elsif $1 == 'on'
+ @trace = true
+ else
+ @trace = false
+ end
+ if @trace
+ stdout.print "Trace on\n"
+ else
+ stdout.print "Trace off\n"
+ end
+
when /^\s*b(?:reak)?\s+((?:.*?+:)?.+)$/
pos = $1
if pos.index(":")
@@ -445,6 +468,7 @@ Commands
up[ nn] move to higher frame
down[ nn] move to lower frame
fin[ish] return to outer frame
+ tr[ace][ (on|off)] set trace mode
q[uit] exit from debugger
v[ar] g[lobal] show global variables
v[ar] l[ocal] show local variables
@@ -572,6 +596,7 @@ EOHELP
end
def trace_func(event, file, line, id, binding, klass)
+ Tracer.trace_func(event, file, line, id, binding) if @trace
@file = file
@line = line
case event
diff --git a/lib/jcode.rb b/lib/jcode.rb
index 49262857a8..193f3042ff 100644
--- a/lib/jcode.rb
+++ b/lib/jcode.rb
@@ -189,7 +189,7 @@ class String
end
def each_char
- if iterator?
+ if block_given?
scan(/./m) do |x|
yield x
end
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 80d28148ac..9de7dcb3a2 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -290,7 +290,7 @@ class Matrix
end
def row(i)
- if iterator?
+ if block_given?
for e in @rows[i]
yield e
@@ -301,7 +301,7 @@ class Matrix
end
def column(j)
- if iterator?
+ if block_given?
0.upto(row_size - 1) do
|i|
yield @rows[i][j]
diff --git a/lib/thwait.rb b/lib/thwait.rb
index 958163edef..45d6a89713 100644
--- a/lib/thwait.rb
+++ b/lib/thwait.rb
@@ -48,7 +48,7 @@ class ThreadsWait
def ThreadsWait.all_waits(*threads)
tw = ThreadsWait.new(*threads)
- if iterator?
+ if block_given?
tw.all_waits do
|th|
yield th
@@ -125,7 +125,7 @@ class ThreadsWait
def all_waits
until @threads.empty?
th = next_wait
- yield th if iterator?
+ yield th if block_given?
end
end
end
diff --git a/lib/tracer.rb b/lib/tracer.rb
index 095173e53b..8ee14ce378 100644
--- a/lib/tracer.rb
+++ b/lib/tracer.rb
@@ -45,7 +45,7 @@ class Tracer
end
def on
- if iterator?
+ if block_given?
on
begin
yield
@@ -126,7 +126,7 @@ class Tracer
Single = new
def Tracer.on
- if iterator?
+ if block_given?
Single.on{yield}
else
Single.on
diff --git a/ruby.c b/ruby.c
index ce9d5dcf35..d848160c6f 100644
--- a/ruby.c
+++ b/ruby.c
@@ -225,6 +225,8 @@ add_modules(mod)
req_list_last = list;
}
+extern void Init_ext _((void));
+
void
require_libraries()
{
@@ -235,6 +237,12 @@ require_libraries()
struct req_list *list = req_list_head.next;
struct req_list *tmp;
+ if (rb_safe_level() == 0) {
+ rb_ary_push(rb_load_path, rb_str_new2("."));
+ addpath(getenv("RUBYLIB"));
+ }
+
+ Init_ext(); /* should be called here for some reason :-( */
ruby_sourcefile = 0;
save[0] = ruby_eval_tree;
save[1] = ruby_eval_tree_begin;
@@ -252,8 +260,6 @@ require_libraries()
ruby_sourcefile = orig_sourcefile;
}
-extern void Init_ext _((void));
-
static void
process_sflag()
{
@@ -626,34 +632,21 @@ proc_options(argc, argv)
ruby_set_argv(argc, argv);
process_sflag();
-#if 0
- Init_ext(); /* should be called here for some reason :-( */
- require_libraries();
-#endif
-
ruby_sourcefile = argv0;
if (e_script) {
+ require_libraries();
rb_compile_string(script, e_script, 1);
}
else if (strlen(script) == 1 && script[0] == '-') {
+ require_libraries();
load_stdin();
}
else {
load_file(script, 1);
}
- if (rb_safe_level() == 0) {
- rb_ary_push(rb_load_path, rb_str_new2("."));
- addpath(getenv("RUBYLIB"));
- }
-
process_sflag();
xflag = 0;
-
-#if 1
- Init_ext(); /* should be called here for some reason :-( */
- require_libraries();
-#endif
}
extern int ruby__end__seen;
@@ -760,13 +753,10 @@ load_file(fname, script)
}
}
}
- else if (NIL_P(c)) {
- rb_io_close(f);
- return;
- }
- else {
+ else if (!NIL_P(c)) {
rb_io_ungetc(f, c);
}
+ require_libraries(); /* Why here? unnatural */
}
rb_compile_file(fname, f, line_start);
if (script && ruby__end__seen) {
diff --git a/version.h b/version.h
index 1a3c02dd66..be4a459d20 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
#define RUBY_VERSION "1.5.4"
-#define RUBY_RELEASE_DATE "2000-06-23"
+#define RUBY_RELEASE_DATE "2000-06-28"
#define RUBY_VERSION_CODE 154
-#define RUBY_RELEASE_CODE 20000623
+#define RUBY_RELEASE_CODE 20000628
diff --git a/win32/ruby.def b/win32/ruby.def
index 704e98b7b5..b6a2d31a30 100644
--- a/win32/ruby.def
+++ b/win32/ruby.def
@@ -125,6 +125,7 @@ EXPORTS
myfdclose
myaccept
mybind
+ myfdclr
myconnect
myfdset
myfdisset
diff --git a/win32/win32.c b/win32/win32.c
index 5590ea5a5d..5780bff261 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -1631,33 +1631,42 @@ my_open_osfhandle(long osfhandle, int flags)
return fh; /* return handle */
}
-FILE *
-myfdopen (int fd, const char *mode)
+static int
+is_socket(SOCKET fd)
{
char sockbuf[80];
int optlen;
int retval;
- int fh;
- extern int errno;
-
- //fprintf(stderr, "myfdopen()\n");
- optlen = sizeof(sockbuf);
- retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
+ optlen = sizeof(sockbuf);
+ retval = getsockopt(fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
if (retval == SOCKET_ERROR) {
int iRet;
iRet = WSAGetLastError();
if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED)
- return (_fdopen(fd, mode));
+ return FALSE;
}
//
// If we get here, then fd is actually a socket.
//
+ return TRUE;
+}
+
+FILE *
+myfdopen (int fd, const char *mode)
+{
+ if (is_socket((SOCKET)fd)) {
+ int fh;
+
fh = my_open_osfhandle((SOCKET)fd, O_RDWR|O_BINARY);
- return _fdopen(fh, mode); // return file pointer
+ return _fdopen(fh, mode); // return file pointer
+ }
+ else {
+ return (_fdopen(fd, mode));
+ }
}
@@ -1784,6 +1793,25 @@ myfdset(int fd, fd_set *set)
}
}
+#undef FD_CLR
+
+void
+myfdclr(int fd, fd_set *set)
+{
+ unsigned int i;
+ SOCKET s = TO_SOCKET(fd);
+
+ for (i = 0; i < set->fd_count; i++) {
+ if (set->fd_array[i] == s) {
+ while (i < set->fd_count - 1) {
+ set->fd_array[i] = set->fd_array[i + 1];
+ i++;
+ }
+ set->fd_count--;
+ break;
+ }
+ }
+}
#undef FD_ISSET
@@ -1803,11 +1831,45 @@ myfdisset(int fd, fd_set *set)
static int NtSocketsInitialized = 0;
+static int
+extract_file_fd(fd_set *set, fd_set *fileset)
+{
+ int idx;
+
+ fileset->fd_count = 0;
+ if (!set)
+ return 0;
+ for (idx = 0; idx < set->fd_count; idx++) {
+ SOCKET fd = set->fd_array[idx];
+
+ if (!is_socket(fd)) {
+ int i;
+
+ for (i = 0; i < fileset->fd_count; i++) {
+ if (fileset->fd_array[i] == fd) {
+ break;
+ }
+ }
+ if (i == fileset->fd_count) {
+ if (fileset->fd_count < FD_SETSIZE) {
+ fileset->fd_array[i] = fd;
+ fileset->fd_count++;
+ }
+ }
+ }
+ }
+ return fileset->fd_count;
+}
+
long
myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
struct timeval *timeout)
{
long r;
+ fd_set file_rd;
+ fd_set file_wr;
+ int file_nfds;
+
if (!NtSocketsInitialized++) {
StartSockets();
}
@@ -1815,28 +1877,22 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
return 0;
}
+ file_nfds = extract_file_fd(rd, &file_rd);
+ file_nfds += extract_file_fd(wr, &file_wr);
+ if (file_nfds)
+ {
+ // assume normal files are always readable/writable
+ // fake read/write fd_set and return value
+ if (rd) *rd = file_rd;
+ if (wr) *wr = file_wr;
+ return file_nfds;
+ }
if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
errno = WSAGetLastError();
switch (errno) {
case WSAEINTR:
errno = EINTR;
break;
- case WSAENOTSOCK:
- // assume normal files are always readable/writable
- // fake read/write fd_set and return value
- r = 0;
- if (rd) r += rd->fd_count;
- if (wr) r += wr->fd_count;
- if (ex && ex->fd_count > 0) {
- // exceptional condition never happen for normal files
- if (r > 0)
- ex->fd_count = 0;
- else {
- errno = EBADF;
- r = SOCKET_ERROR;
- }
- }
- break;
}
}
return r;
diff --git a/win32/win32.h b/win32/win32.h
index 0bfe711a79..add6f14250 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -183,6 +183,7 @@ extern SOCKET myaccept(SOCKET, struct sockaddr *, int *);
extern int mybind(SOCKET, struct sockaddr *, int);
extern int myconnect(SOCKET, struct sockaddr *, int);
extern void myfdset(int, fd_set*);
+extern void myfdclr(int, fd_set*);
extern int myfdisset(int, fd_set*);
extern long myselect(int, fd_set *, fd_set *, fd_set *, struct timeval *);
extern int mygetpeername(SOCKET, struct sockaddr *, int *);
@@ -288,6 +289,9 @@ extern char *mystrerror(int);
#undef FD_SET
#define FD_SET myfdset
+#undef FD_CLR
+#define FD_CLR myfdclr
+
#undef FD_ISSET
#define FD_ISSET myfdisset