diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | defines.h | 9 | ||||
-rw-r--r-- | eval.c | 9 | ||||
-rw-r--r-- | ext/socket/extconf.rb | 22 | ||||
-rw-r--r-- | ext/socket/socket.c | 265 | ||||
-rw-r--r-- | ext/tcltklib/extconf.rb | 14 | ||||
-rw-r--r-- | intern.h | 4 | ||||
-rw-r--r-- | lib/date2.rb | 100 | ||||
-rw-r--r-- | lib/thread.rb | 31 | ||||
-rw-r--r-- | pack.c | 6 | ||||
-rw-r--r-- | parse.y | 2 | ||||
-rw-r--r-- | regex.c | 4 | ||||
-rw-r--r-- | ruby.c | 10 | ||||
-rw-r--r-- | ruby.h | 10 | ||||
-rw-r--r-- | sample/cal.rb | 149 | ||||
-rw-r--r-- | version.h | 4 | ||||
-rw-r--r-- | win32/Makefile | 4 |
17 files changed, 425 insertions, 235 deletions
@@ -3,6 +3,23 @@ Wed May 24 16:03:06 2000 Wakou Aoyama <wakou@fsinet.or.jp> * lib/cgi.rb bug fix: CGI::escape(), CGI::Cookie::new() * lib/net/telnet.rb improve: binmode(), telnetmode() interface +Tue May 23 08:36:24 2000 Yukihiro Matsumoto <matz@netlab.co.jp> + + * regex.c (re_compile_pattern): forgot to restore old option + status by (?ix-ix). + +Mon May 22 15:10:39 2000 Yukihiro Matsumoto <matz@netlab.co.jp> + + * eval.c (find_file): should check if the file really exists. + +Sun May 21 20:58:08 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp> + + * pack.c: fix OFF16 and OFF32 definitions for Alpha and IRIX64. + +Wed May 17 02:22:03 2000 Yukihiro Matsumoto <matz@netlab.co.jp> + + * parse.y (expr): avoid calling value_expr() twice. + Fri May 12 17:33:44 2000 Yukihiro Matsumoto <matz@netlab.co.jp> * regex.c (re_compile_pattern): charset_not should not exclude @@ -34,6 +34,15 @@ #include "win32/win32.h" #endif +#if defined __CYGWIN__ +# undef EXTERN +# if defined USEIMPORTLIB +# define EXTERN extern __declspec(dllimport) +# else +# define EXTERN extern __declspec(dllexport) +# endif +#endif + #ifndef EXTERN #define EXTERN extern #endif @@ -4688,8 +4688,15 @@ find_file(file) else { path = 0; } + file = dln_find_file(file, path); + if (file) { + FILE *f = fopen(file, "r"); - return dln_find_file(file, path); + if (f == NULL) return 0; + fclose(f); + return file; + } + return 0; } void diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 91ac8f6123..9ac24cd763 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -2,8 +2,8 @@ require 'mkmf' $LDFLAGS += " -L/usr/local/lib" if File.directory?("/usr/local/lib") $CFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len" -case PLATFORM -when /mswin32/ +case RUBY_PLATFORM +when /mswin32|mingw/ test_func = "WSACleanup" have_library("wsock32", "WSACleanup") have_func("closesocket") @@ -99,6 +99,10 @@ EOF $ipv6lib="inet6" $ipv6libdir="/usr/local/v6/lib" $CFLAGS="-DINET6 "+$CFLAGS + else + $ipv6lib=with_config("ipv6-lib", nil) + $ipv6libdir=with_config("ipv6-libdir", nil) + $CFLAGS="-DINET6 "+$CFLAGS end if $ipv6lib @@ -273,6 +277,20 @@ EOS exit end +case with_config("ipv6-lookup-order", "INET") +when "INET" + $CFLAGS="-DDEFAULT_LOOKUP_ORDER_INET "+$CFLAGS +when "INET6" + $CFLAGS="-DDEFAULT_LOOKUP_ORDER_INET6 "+$CFLAGS +when "UNSPEC" + $CFLAGS="-DDEFAULT_LOOKUP_ORDER_UNSPEC "+$CFLAGS +else + print <<EOS + +Fatal: invalid --ipv6-lookup-order (expected INET, INET6 or UNSPEC) +EOS + exit +end $objs = ["socket.#{$OBJEXT}"] diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 6a07f43764..e975a2bb98 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -6,6 +6,8 @@ $Date$ created at: Thu Mar 31 12:21:29 JST 1994 + Copyright (C) 1993-2000 Yukihiro Matsumoto + ************************************************/ #include "ruby.h" @@ -13,6 +15,11 @@ #include "rubysig.h" #include <stdio.h> #include <sys/types.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + #ifndef NT #include <sys/socket.h> #include <netinet/in.h> @@ -29,13 +36,6 @@ #include <sys/un.h> #endif -#ifdef USE_CWGUSI -extern int fileno(FILE *stream); /* <unix.mac.h> */ -extern int rb_thread_select(int, fd_set*, fd_set*, fd_set*, struct timeval*); /* thread.c */ -# include <sys/errno.h> -# include <GUSI.h> -#endif - #if defined(HAVE_FCNTL) #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> @@ -104,6 +104,91 @@ struct sockaddr_storage { }; #endif +#define LOOKUP_ORDER_UNSPEC 0 +#define LOOKUP_ORDER_INET 1 +#define LOOKUP_ORDER_INET6 2 + +#if defined(DEFAULT_LOOKUP_ORDER_UNSPEC) +# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_UNSPEC +#elif defined(DEFAULT_LOOKUP_ORDER_INET) +# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_INET +#elif defined(DEFAULT_LOOKUP_ORDER_INET6) +# define LOOKUP_ORDER_DEFAULT LOOKUP_ORDER_INET6 +#endif + +#ifdef INET6 +#define LOOKUP_ORDERS 3 +int lookup_order_table[LOOKUP_ORDERS][LOOKUP_ORDERS] = { + {PF_UNSPEC, PF_UNSPEC, PF_UNSPEC}, /* 0:unspec */ + {PF_INET, PF_INET6, PF_UNSPEC}, /* 1:inet inet6 */ + {PF_INET6, PF_INET, PF_UNSPEC} /* 2:inet6 inet */ +}; + +static int lookup_order = LOOKUP_ORDER_DEFAULT; + +static VALUE +lookup_order_get(self) + VALUE self; +{ + return INT2FIX(lookup_order); +} + +static VALUE +lookup_order_set(self, order) + VALUE self, order; +{ + int n = NUM2INT(order); + + if (n < 0 || LOOKUP_ORDERS <= n) { + rb_raise(rb_eArgError, "invalid value for lookup_order"); + } + lookup_order = n; + return order; +} + +static int +rb_getaddrinfo(nodename, servname, hints, res) + char *nodename; + char *servname; + struct addrinfo *hints; + struct addrinfo **res; +{ + struct addrinfo tmp_hints; + int i, af, error; + + for (i = 0; i < LOOKUP_ORDERS; i++) { + af = lookup_order_table[lookup_order][i]; + MEMCPY(&tmp_hints, hints, struct addrinfo, 1); + tmp_hints.ai_family = af; + error = getaddrinfo(nodename, servname, &tmp_hints, res); + if (error) { + if (tmp_hints.ai_family == PF_UNSPEC) { + break; + } + } + else { + break; + } + } + + return error; +} +#else +static VALUE +lookup_order_get(self) + VALUE self; +{ + return INT2FIX(LOOKUP_ORDER_DEFAULT); +} + +static VALUE +lookup_order_set(self, order) + VALUE self, order; +{ + return order; +} +#endif + #ifdef NT static void sock_finalize(fptr) @@ -128,7 +213,6 @@ sock_new(class, fd) NEWOBJ(sock, struct RFile); OBJSETUP(sock, class, T_FILE); - rb_secure(4); MakeOpenFile(sock, fp); fp->f = rb_fdopen(fd, "r"); #ifdef NT @@ -153,7 +237,9 @@ bsock_shutdown(argc, argv, sock) int how; OpenFile *fptr; - rb_secure(4); + if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) { + rb_raise(rb_eSecurityError, "Insecure: can't shutdown socket"); + } rb_scan_args(argc, argv, "01", &howto); if (howto == Qnil) how = 2; @@ -176,7 +262,9 @@ bsock_close_read(sock) { OpenFile *fptr; - rb_secure(4); + if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) { + rb_raise(rb_eSecurityError, "Insecure: can't close socket"); + } GetOpenFile(sock, fptr); shutdown(fileno(fptr->f), 0); if (fptr->f2 == 0) { @@ -201,7 +289,9 @@ bsock_close_write(sock) { OpenFile *fptr; - rb_secure(4); + if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) { + rb_raise(rb_eSecurityError, "Insecure: can't close socket"); + } GetOpenFile(sock, fptr); if (fptr->f2 == 0) { return rb_io_close(sock); @@ -273,7 +363,7 @@ bsock_getsockopt(sock, lev, optname) if (getsockopt(fileno(fptr->f), level, option, buf, &len) < 0) rb_sys_fail(fptr->path); - return rb_str_new(buf, len); + return rb_tainted_str_new(buf, len); #else rb_notimplement(); #endif @@ -290,7 +380,7 @@ bsock_getsockname(sock) GetOpenFile(sock, fptr); if (getsockname(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0) rb_sys_fail("getsockname(2)"); - return rb_str_new(buf, len); + return rb_tainted_str_new(buf, len); } static VALUE @@ -304,7 +394,7 @@ bsock_getpeername(sock) GetOpenFile(sock, fptr); if (getpeername(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0) rb_sys_fail("getpeername(2)"); - return rb_str_new(buf, len); + return rb_tainted_str_new(buf, len); } static VALUE @@ -387,10 +477,14 @@ s_recv(sock, argc, argv, from) if (flg == Qnil) flags = 0; else flags = NUM2INT(flg); - str = rb_str_new(0, NUM2INT(len)); - GetOpenFile(sock, fptr); + if (rb_read_pending(fptr->f)) { + rb_raise(rb_eIOError, "recv for buffered IO"); + } fd = fileno(fptr->f); + + str = rb_tainted_str_new(0, NUM2INT(len)); + rb_thread_wait_fd(fd); retry: TRAP_BEG; @@ -430,7 +524,7 @@ s_recv(sock, argc, argv, from) return rb_assoc_new(str, unixaddr((struct sockaddr_un *)buf)); #endif case RECV_SOCKET: - return rb_assoc_new(str, rb_str_new(buf, alen)); + return rb_assoc_new(str, rb_tainted_str_new(buf, alen)); } } @@ -464,8 +558,7 @@ mkipaddr0(addr, buf, len) { int error; - error = getnameinfo(addr, SA_LEN(addr), buf, len, NULL, 0, - NI_NUMERICHOST); + error = getnameinfo(addr, SA_LEN(addr), buf, len, NULL, 0, NI_NUMERICHOST); if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -478,7 +571,7 @@ mkipaddr(addr) char buf[1024]; mkipaddr0(addr, buf, sizeof(buf)); - return rb_str_new2(buf); + return rb_tainted_str_new2(buf); } static void @@ -515,16 +608,18 @@ ip_addrsetup(host, port) hostp = hbuf; } else { - char *name = STR2CSTR(host); + char *name; + Check_SafeStr(host); + name = RSTRING(host)->ptr; if (*name == 0) { mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf)); } else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) { mkinetaddr(INADDR_BROADCAST, hbuf, sizeof(hbuf)); } - else if (strlen(name) > sizeof(hbuf)-1) { - rb_raise(rb_eSocket, "hostname too long (%d)", strlen(name)); + else if (strlen(name) >= sizeof(hbuf)) { + rb_raise(rb_eArgError, "hostname too long (%d)", strlen(name)); } else { strcpy(hbuf, name); @@ -535,17 +630,22 @@ ip_addrsetup(host, port) portp = 0; } else if (FIXNUM_P(port)) { - snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port)); + snprintf(pbuf, sizeof(pbuf), "%ld", FIX2INT(port)); portp = pbuf; } else { + Check_SafeStr(port); portp = STR2CSTR(port); } MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; +#ifndef INET6 error = getaddrinfo(hostp, portp, &hints, &res); +#else + error = rb_getaddrinfo(hostp, portp, &hints, &res); +#endif if (error) { if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); @@ -596,14 +696,14 @@ ipaddr(sockaddr) if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } - addr1 = rb_str_new2(hbuf); + addr1 = rb_tainted_str_new2(hbuf); } error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } - addr2 = rb_str_new2(hbuf); + addr2 = rb_tainted_str_new2(hbuf); if (do_not_reverse_lookup) { addr1 = addr2; } @@ -613,17 +713,6 @@ ipaddr(sockaddr) return ary; } -static void -thread_write_select(fd) - int fd; -{ - fd_set fds; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - rb_thread_select(fd+1, 0, &fds, 0, 0); -} - static int ruby_socket(domain, type, proto) int domain, type, proto; @@ -640,6 +729,17 @@ ruby_socket(domain, type, proto) return fd; } +static void +thread_write_select(fd) + int fd; +{ + fd_set fds; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + rb_thread_select(fd+1, 0, &fds, 0, 0); +} + static int ruby_connect(fd, sockaddr, len, socks) int fd; @@ -723,11 +823,14 @@ open_inet(class, h, serv, type) host = NULL; } if (FIXNUM_P(serv)) { - snprintf(pbuf, sizeof(pbuf), "%d", FIX2UINT(serv)); + snprintf(pbuf, sizeof(pbuf), "%ld", FIX2UINT(serv)); portp = pbuf; } else { - strcpy(pbuf, STR2CSTR(serv)); + Check_SafeStr(serv); + if (RSTRING(serv)->len >= sizeof(pbuf)) + rb_raise(rb_eArgError, "servicename too long (%d)", RSTRING(serv)->len); + strcpy(pbuf, RSTRING(serv)->ptr); portp = pbuf; } MEMZERO(&hints, struct addrinfo, 1); @@ -736,7 +839,11 @@ open_inet(class, h, serv, type) if (type == INET_SERVER) { hints.ai_flags = AI_PASSIVE; } +#ifndef INET6 error = getaddrinfo(host, portp, &hints, &res0); +#else + error = rb_getaddrinfo(host, portp, &hints, &res0); +#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -823,6 +930,9 @@ socks_s_close(sock) { OpenFile *fptr; + if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) { + rb_raise(rb_eSecurityError, "Insecure: can't close socket"); + } GetOpenFile(sock, fptr); shutdown(fileno(fptr->f), 2); shutdown(fileno(fptr->f2), 2); @@ -844,9 +954,11 @@ tcp_s_gethostbyname(obj, host) char **pch; VALUE ary, names; + rb_secure(3); if (rb_obj_is_kind_of(host, rb_cInteger)) { long i = NUM2LONG(host); struct sockaddr_in *sin; + sin = (struct sockaddr_in *)&addr; MEMZERO(sin, struct sockaddr_in, 1); sin->sin_family = AF_INET; @@ -890,11 +1002,11 @@ tcp_s_gethostbyname(obj, host) #endif } ary = rb_ary_new(); - rb_ary_push(ary, rb_str_new2(h->h_name)); + rb_ary_push(ary, rb_tainted_str_new2(h->h_name)); names = rb_ary_new(); rb_ary_push(ary, names); for (pch = h->h_aliases; *pch; pch++) { - rb_ary_push(names, rb_str_new2(*pch)); + rb_ary_push(names, rb_tainted_str_new2(*pch)); } rb_ary_push(ary, INT2NUM(h->h_addrtype)); #ifdef h_addr @@ -965,6 +1077,7 @@ s_accept(class, fd, sockaddr, len) { int fd2; + rb_secure(3); retry: rb_thread_wait_fd(fd); TRAP_BEG; @@ -1110,6 +1223,7 @@ udp_s_open(argc, argv, class) int socktype = AF_INET; int fd; + rb_secure(3); if (rb_scan_args(argc, argv, "01", &arg) == 1) { socktype = NUM2INT(arg); } @@ -1129,6 +1243,7 @@ udp_connect(sock, host, port) int fd; struct addrinfo *res0, *res; + rb_secure(3); GetOpenFile(sock, fptr); fd = fileno(fptr->f); res0 = ip_addrsetup(host, port); @@ -1151,6 +1266,7 @@ udp_bind(sock, host, port) OpenFile *fptr; struct addrinfo *res0, *res; + rb_secure(3); GetOpenFile(sock, fptr); res0 = ip_addrsetup(host, port); for (res = res0; res; res = res->ai_next) { @@ -1182,6 +1298,7 @@ udp_send(argc, argv, sock) if (argc == 2) { return bsock_send(argc, argv, sock); } + rb_secure(4); rb_scan_args(argc, argv, "4", &mesg, &flags, &host, &port); GetOpenFile(sock, fptr); @@ -1189,7 +1306,7 @@ udp_send(argc, argv, sock) f = GetWriteFile(fptr); m = rb_str2cstr(mesg, &mlen); for (res = res0; res; res = res->ai_next) { - retry: + retry: n = sendto(fileno(f), m, mlen, NUM2INT(flags), res->ai_addr, res->ai_addrlen); if (n >= 0) { @@ -1205,7 +1322,7 @@ udp_send(argc, argv, sock) #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - thread_write_select(fileno(f)); + rb_thread_fd_writable(fileno(f)); goto retry; } } @@ -1245,7 +1362,7 @@ unix_path(sock) rb_sys_fail(0); fptr->path = strdup(addr.sun_path); } - return rb_str_new2(fptr->path); + return rb_tainted_str_new2(fptr->path); } static VALUE @@ -1282,7 +1399,8 @@ static VALUE unixaddr(sockaddr) struct sockaddr_un *sockaddr; { - return rb_assoc_new(rb_str_new2("AF_UNIX"),rb_str_new2(sockaddr->sun_path)); + return rb_assoc_new(rb_str_new2("AF_UNIX"), + rb_tainted_str_new2(sockaddr->sun_path)); } static VALUE @@ -1324,6 +1442,7 @@ setup_domain_and_type(domain, dv, type, tv) char *ptr; if (TYPE(domain) == T_STRING) { + Check_SafeStr(domain); ptr = RSTRING(domain)->ptr; if (strcmp(ptr, "AF_INET") == 0) *dv = AF_INET; @@ -1372,6 +1491,7 @@ setup_domain_and_type(domain, dv, type, tv) *dv = NUM2INT(domain); } if (TYPE(type) == T_STRING) { + Check_SafeStr(type); ptr = RSTRING(type)->ptr; if (strcmp(ptr, "SOCK_STREAM") == 0) *tv = SOCK_STREAM; @@ -1408,6 +1528,7 @@ sock_s_open(class, domain, type, protocol) int fd; int d, t; + rb_secure(3); setup_domain_and_type(domain, &d, type, &t); fd = ruby_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); @@ -1486,6 +1607,7 @@ sock_listen(sock, log) { OpenFile *fptr; + rb_secure(4); GetOpenFile(sock, fptr); if (listen(fileno(fptr->f), NUM2INT(log)) < 0) rb_sys_fail("listen(2)"); @@ -1514,7 +1636,7 @@ sock_accept(sock) GetOpenFile(sock, fptr); sock2 = s_accept(rb_cSocket,fileno(fptr->f),(struct sockaddr*)buf,&len); - return rb_assoc_new(sock2, rb_str_new(buf, len)); + return rb_assoc_new(sock2, rb_tainted_str_new(buf, len)); } #ifdef HAVE_GETHOSTNAME @@ -1524,11 +1646,12 @@ sock_gethostname(obj) { char buf[1024]; + rb_secure(3); if (gethostname(buf, (int)sizeof buf - 1) < 0) rb_sys_fail("gethostname"); buf[sizeof buf - 1] = '\0'; - return rb_str_new2(buf); + return rb_tainted_str_new2(buf); } #else #ifdef HAVE_UNAME @@ -1539,10 +1662,11 @@ static VALUE sock_gethostname(obj) VALUE obj; { - struct utsname un; + struct utsname un; - uname(&un); - return rb_str_new2(un.nodename); + rb_secure(3); + uname(&un); + return rb_tainted_str_new2(un.nodename); } #else static VALUE @@ -1570,19 +1694,19 @@ mkhostent(h) #endif } ary = rb_ary_new(); - rb_ary_push(ary, rb_str_new2(h->h_name)); + rb_ary_push(ary, rb_tainted_str_new2(h->h_name)); names = rb_ary_new(); rb_ary_push(ary, names); for (pch = h->h_aliases; *pch; pch++) { - rb_ary_push(names, rb_str_new2(*pch)); + rb_ary_push(names, rb_tainted_str_new2(*pch)); } rb_ary_push(ary, INT2NUM(h->h_addrtype)); #ifdef h_addr for (pch = h->h_addr_list; *pch; pch++) { - rb_ary_push(ary, rb_str_new(*pch, h->h_length)); + rb_ary_push(ary, rb_tainted_str_new(*pch, h->h_length)); } #else - rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length)); + rb_ary_push(ary, rb_tainted_str_new(h->h_addr, h->h_length)); #endif return ary; @@ -1728,8 +1852,7 @@ sock_s_getaddrinfo(argc, argv) int error; host = port = family = socktype = protocol = flags = Qnil; - rb_scan_args(argc, argv, "24", &host, &port, &family, &socktype, &protocol, - &flags); + rb_scan_args(argc, argv, "24", &host, &port, &family, &socktype, &protocol, &flags); if (NIL_P(host)) { hptr = NULL; } @@ -1742,7 +1865,7 @@ sock_s_getaddrinfo(argc, argv) pptr = NULL; } else if (FIXNUM_P(port)) { - snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port)); + snprintf(pbuf, sizeof(pbuf), "%ld", FIX2INT(port)); pptr = pbuf; } else { @@ -1755,9 +1878,11 @@ sock_s_getaddrinfo(argc, argv) if (!NIL_P(family)) { hints.ai_family = NUM2INT(family); } +#ifndef INET6 else { hints.ai_family = PF_UNSPEC; } +#endif if (!NIL_P(socktype)) { hints.ai_socktype = NUM2INT(socktype); } @@ -1767,7 +1892,16 @@ sock_s_getaddrinfo(argc, argv) if (!NIL_P(flags)) { hints.ai_flags = NUM2INT(flags); } +#ifndef INET6 error = getaddrinfo(hptr, pptr, &hints, &res); +#else + if (!NIL_P(family)) { + error = getaddrinfo(hptr, pptr, &hints, &res); + } + else { + error = rb_getaddrinfo(hptr, pptr, &hints, &res); + } +#endif if (error) { rb_raise(rb_eSocket, "%s", gai_strerror(error)); } @@ -1782,7 +1916,7 @@ sock_s_getnameinfo(argc, argv) int argc; VALUE *argv; { - VALUE sa, af, host, port, flags; + VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags; static char hbuf[1024], pbuf[1024]; char *hptr, *pptr; int fl; @@ -1818,6 +1952,10 @@ sock_s_getnameinfo(argc, argv) host = RARRAY(sa)->ptr[2]; } } + else { + rb_raise(rb_eArgError, "array size should be 3 or 4, %d given", + RARRAY(sa)->len); + } if (NIL_P(host)) { hptr = NULL; } @@ -1831,7 +1969,7 @@ sock_s_getnameinfo(argc, argv) pptr = NULL; } else if (!NIL_P(port)) { - snprintf(pbuf, sizeof(pbuf), "%d", NUM2INT(port)); + snprintf(pbuf, sizeof(pbuf), "%ld", NUM2INT(port)); pptr = pbuf; } else { @@ -1866,7 +2004,6 @@ sock_s_getnameinfo(argc, argv) fl = NUM2INT(flags); } - gotsap: error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), fl); if (error) { @@ -1875,7 +2012,7 @@ sock_s_getnameinfo(argc, argv) if (res) freeaddrinfo(res); - return rb_ary_new3(2, rb_str_new2(hbuf), rb_str_new2(pbuf)); + return rb_assoc_new(rb_tainted_str_new2(hbuf), rb_tainted_str_new2(pbuf)); } static VALUE mConst; @@ -2037,6 +2174,12 @@ Init_socket() sock_define_const("PF_INET6", PF_INET6); #endif + sock_define_const("LOOKUP_INET", LOOKUP_ORDER_INET); + sock_define_const("LOOKUP_INET6", LOOKUP_ORDER_INET6); + sock_define_const("LOOKUP_UNSPEC", LOOKUP_ORDER_UNSPEC); + rb_define_singleton_method(rb_cBasicSocket, "lookup_order", lookup_order_get, 0); + rb_define_singleton_method(rb_cBasicSocket, "lookup_order=", lookup_order_set, 1); + sock_define_const("MSG_OOB", MSG_OOB); #ifdef MSG_PEEK sock_define_const("MSG_PEEK", MSG_PEEK); diff --git a/ext/tcltklib/extconf.rb b/ext/tcltklib/extconf.rb index 713cc811e5..5f56d42a52 100644 --- a/ext/tcltklib/extconf.rb +++ b/ext/tcltklib/extconf.rb @@ -2,10 +2,12 @@ require 'mkmf' -have_library("nsl", "t_open") -have_library("socket", "socket") -have_library("dl", "dlopen") -have_library("m", "log") +if RUBY_PLATFORM !~ /mswin32|mingw/ + have_library("nsl", "t_open") + have_library("socket", "socket") + have_library("dl", "dlopen") + have_library("m", "log") +end dir_config("tk") dir_config("tcl") @@ -21,6 +23,7 @@ def find_tcl(tcllib) find_library(tcllib, func, *paths) else find_library("tcl", func, *paths) or + find_library("tcl8.3", func, *paths) or find_library("tcl8.2", func, *paths) or find_library("tcl8.0", func, *paths) or find_library("tcl7.6", func, *paths) @@ -34,6 +37,7 @@ def find_tk(tklib) find_library(tklib, func, *paths) else find_library("tk", func, *paths) or + find_library("tk8.3", func, *paths) or find_library("tk8.2", func, *paths) or find_library("tk8.0", func, *paths) or find_library("tk4.2", func, *paths) @@ -41,7 +45,7 @@ def find_tk(tklib) end if have_header("tcl.h") && have_header("tk.h") && - (/mswin32/ =~ RUBY_PLATFORM || find_library("X11", "XOpenDisplay", + (/mswin32|mingw|cygwin/ =~ RUBY_PLATFORM || find_library("X11", "XOpenDisplay", "/usr/X11/lib", "/usr/X11R6/lib", "/usr/openwin/lib")) && find_tcl(tcllib) && find_tk(tklib) @@ -209,8 +209,8 @@ VALUE rb_Float _((VALUE)); VALUE rb_String _((VALUE)); VALUE rb_Array _((VALUE)); /* parse.y */ -extern int ruby_sourceline; -extern char *ruby_sourcefile; +EXTERN int ruby_sourceline; +EXTERN char *ruby_sourcefile; #define yyparse rb_yyparse #define yylex rb_yylex #define yyerror rb_yyerror diff --git a/lib/date2.rb b/lib/date2.rb index 38d477b78d..e1badcd3f7 100644 --- a/lib/date2.rb +++ b/lib/date2.rb @@ -1,5 +1,5 @@ -# date2.rb: Written by Tadayoshi Funaba 1998, 1999 -# $Id: date2.rb,v 1.17 1999/09/15 05:34:07 tadf Exp $ +# date2.rb: Written by Tadayoshi Funaba 1998-2000 +# $Id: date2.rb,v 1.21 2000/05/14 15:47:09 tadf Exp $ class Date @@ -110,6 +110,12 @@ class Date def jd_to_mjd(jd) jd - 2400000.5 end def tjd_to_jd(tjd) tjd + 2440000.5 end def jd_to_tjd(jd) jd - 2440000.5 end + def tjd2_to_jd(cycle, tjd) tjd_to_jd(cycle * 10000 + tjd) end + def jd_to_tjd2(jd) clfloor(jd_to_tjd(jd), 10000) end + def ld_to_jd(ld) ld + 2299160 end + def jd_to_ld(jd) jd - 2299160 end + + def jd_to_wday(jd) (jd + 1) % 7 end def julian_leap? (y) y % 4 == 0 end def gregorian_leap? (y) y % 4 == 0 and y % 100 != 0 or y % 400 == 0 end @@ -123,8 +129,8 @@ class Date m += 13 end if d < 0 - ny, nm = Date.clfloor(y * 12 + m, 12) - nm, = Date.clfloor(m + 1, 1) + ny, nm = clfloor(y * 12 + m, 12) + nm, = clfloor(m + 1, 1) la = nil 31.downto 1 do |z| break if la = exist3?(y, m, z, sg) @@ -195,10 +201,9 @@ class Date def once(*ids) for id in ids module_eval <<-"end;" - alias_method :__#{id}__, #{id} + alias_method :__#{id.to_i}__, :#{id.id2name} def #{id.id2name}(*args, &block) - def self.#{id.id2name}(*args, &block); @__#{id}__ end - @__#{id}__ = __#{id}__(*args, &block) + (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0] end end; end @@ -211,76 +216,76 @@ class Date def initialize(rjd=0, sg=ITALY) @rjd, @sg = rjd, sg end def rjd() @rjd end - def rmjd() Date.jd_to_mjd(@rjd) end - def rtjd() Date.jd_to_tjd(@rjd) end + def rmjd() type.jd_to_mjd(@rjd) end + def rtjd() type.jd_to_tjd(@rjd) end + def rtjd2() type.jd_to_tjd2(@rjd) end - once :rmjd, :rtjd + once :rmjd, :rtjd, :rtjd2 - def jd() Date.rjd_to_jd(@rjd)[0] end - def fr1() Date.rjd_to_jd(@rjd)[1] end - def mjd() Date.jd_to_mjd(jd) end - def tjd() Date.jd_to_tjd(jd) end + def jd() type.rjd_to_jd(@rjd)[0] end + def fr1() type.rjd_to_jd(@rjd)[1] end + def mjd() type.jd_to_mjd(jd) end + def tjd() type.jd_to_tjd(jd) end + def tjd2() type.jd_to_tjd2(jd) end + def ld() type.jd_to_ld(jd) end - once :jd, :fr1, :mjd, :tjd + once :jd, :fr1, :mjd, :tjd, :tjd2, :ld - def civil() Date.jd_to_civil(jd, @sg) end - def ordinal() Date.jd_to_ordinal(jd, @sg) end - def commercial() Date.jd_to_commercial(jd, @sg) end + def civil() type.jd_to_civil(jd, @sg) end + def ordinal() type.jd_to_ordinal(jd, @sg) end + def commercial() type.jd_to_commercial(jd, @sg) end once :civil, :ordinal, :commercial + private :civil, :ordinal, :commercial def year() civil[0] end def yday() ordinal[1] end def mon() civil[1] end alias_method :month, :mon - once :year, :yday, :mon, :month def mday() civil[2] end alias_method :day, :mday - once :mday, :day def cwyear() commercial[0] end def cweek() commercial[1] end def cwday() commercial[2] end - once :cwyear, :cweek, :cwday - - def wday() (jd + 1) % 7 end + def wday() type.jd_to_wday(jd) end once :wday - def os? () Date.os?(jd, @sg) end - def ns? () Date.ns?(jd, @sg) end + def os? () type.os?(jd, @sg) end + def ns? () type.ns?(jd, @sg) end once :os?, :ns? def leap? - Date.jd_to_civil(Date.civil_to_jd(year, 3, 1, ns?) - 1, + type.jd_to_civil(type.civil_to_jd(year, 3, 1, ns?) - 1, ns?)[-1] == 29 end once :leap? def sg() @sg end - def newsg(sg=Date::ITALY) Date.new(@rjd, sg) end + def newsg(sg=type::ITALY) type.new(@rjd, sg) end - def italy() newsg(Date::ITALY) end - def england() newsg(Date::ENGLAND) end - def julian() newsg(Date::JULIAN) end - def gregorian() newsg(Date::GREGORIAN) end + def italy() newsg(type::ITALY) end + def england() newsg(type::ENGLAND) end + def julian() newsg(type::JULIAN) end + def gregorian() newsg(type::GREGORIAN) end def + (n) case n - when Numeric; return Date.new(@rjd + n, @sg) + when Numeric; return type.new(@rjd + n, @sg) end fail TypeError, 'expected numeric' end def - (x) case x - when Numeric; return Date.new(@rjd - x, @sg) + when Numeric; return type.new(@rjd - x, @sg) when Date; return @rjd - x.rjd end fail TypeError, 'expected numeric or date' @@ -303,27 +308,21 @@ class Date end def >> (n) - y, m = Date.clfloor(year * 12 + (mon - 1) + n, 12) - m, = Date.clfloor(m + 1, 1) + y, m = type.clfloor(year * 12 + (mon - 1) + n, 12) + m, = type.clfloor(m + 1, 1) d = mday - d -= 1 until jd2 = Date.exist3?(y, m, d, ns?) + d -= 1 until jd2 = type.exist3?(y, m, d, ns?) self + (jd2 - jd) end def << (n) self >> -n end def step(limit, step) - rjd = @rjd - if (step > 0) - while rjd <= limit.rjd - yield Date.new(rjd, @sg) - rjd += step - end - else - while rjd >= limit.rjd - yield Date.new(rjd, @sg) - rjd += step - end + da = self + op = [:-,:<=,:>=][step<=>0] + while da.__send__(op, limit) + yield da + da += step end self end @@ -336,11 +335,12 @@ class Date alias_method :next, :succ def eql? (other) Date === other and self == other end - def hash() Date.clfloor(@rjd)[0] end - def inspect() format('#<Date: %s,%s>', @rjd, @sg) end + def hash() type.clfloor(@rjd)[0] end + + def inspect() format('#<%s: %s,%s>', type, @rjd, @sg) end def to_s() format('%.4d-%02d-%02d', year, mon, mday) end def _dump(limit) Marshal.dump([@rjd, @sg], -1) end - def Date._load(str) Date.new(*Marshal.load(str)) end + def self._load(str) new(*Marshal.load(str)) end end diff --git a/lib/thread.rb b/lib/thread.rb index 3880f07345..fd51d6d562 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -1,7 +1,10 @@ # # thread.rb - thread support classes # $Date$ -# by Yukihiro Matsumoto <matz@caelum.co.jp> +# by Yukihiro Matsumoto <matz@netlab.co.jp> +# +# Copyright (C) 2000 Network Applied Communication Laboratory, Inc. +# Copyright (C) 2000 Information-technology Promotion Agency, Japan # unless defined? Thread @@ -154,12 +157,16 @@ class Queue t.wakeup if t rescue ThreadError retry + ensure + Thread.critical = false end - Thread.critical = false + t.run if t + end + def enq(obj) + push(obj) end - alias enq push - def pop non_block=false + def pop(non_block=false) Thread.critical = true begin loop do @@ -177,8 +184,10 @@ class Queue Thread.critical = false end end - alias shift pop - alias deq pop + def shift(non_block=false) + pop(non_block=false) + end + alias deq shift def empty? @que.length == 0 @@ -191,8 +200,9 @@ class Queue def length @que.length end - alias size length - + def size + length + end def num_waiting @waiting.size @@ -247,10 +257,13 @@ class SizedQueue<Queue if @que.length < @max begin t = @queue_wait.shift - t.run if t + t.wakeup if t rescue ThreadError retry + ensure + Thread.critical = false end + t.run if t end super end @@ -23,9 +23,9 @@ #ifdef NATINT_PACK # define NATINT_LEN(type,len) (natint?sizeof(type):(len)) -# ifndef WORDS_BIGENDIAN -# define OFF16(p) ((char*)(p) + (natint?(sizeof(short) - 2):0)) -# define OFF32(p) ((char*)(p) + (natint?(sizeof(long) - 4):0)) +# ifdef WORDS_BIGENDIAN +# define OFF16(p) ((char*)(p) + (natint?0:(sizeof(short) - 2))) +# define OFF32(p) ((char*)(p) + (natint?0:(sizeof(long) - 4))) # endif #else # define NATINT_LEN(type,len) sizeof(type) @@ -394,14 +394,12 @@ expr : mlhs '=' mrhs } | kRETURN ret_args { - value_expr($2); if (!compile_for_eval && !cur_mid && !in_single) yyerror("return appeared outside of method"); $$ = NEW_RETURN($2); } | kYIELD ret_args { - value_expr($2); $$ = NEW_YIELD($2); } | command_call @@ -1219,6 +1219,7 @@ re_compile_pattern(pattern, size, bufp) int had_char_class = 0; int options = bufp->options; + int old_options = 0; bufp->fastmap_accurate = 0; bufp->must = 0; @@ -1624,6 +1625,7 @@ re_compile_pattern(pattern, size, bufp) break; case '(': + old_options = options; PATFETCH(c); if (c == '?') { int negative = 0; @@ -1754,7 +1756,7 @@ re_compile_pattern(pattern, size, bufp) break; } *stackp++ = c; - *stackp++ = options; + *stackp++ = old_options; fixup_alt_jump = 0; laststart = 0; begalt = b; @@ -540,6 +540,11 @@ proc_options(argcp, argvp) if (ruby_verbose) ruby_verbose = Qtrue; if (ruby_debug) ruby_debug = Qtrue; + if (rb_safe_level() == 0) { + rb_ary_push(rb_load_path, rb_str_new2(".")); + addpath(getenv("RUBYLIB")); + } + xflag = Qfalse; *argvp = argv; *argcp = argc; @@ -636,11 +641,6 @@ load_file(fname, script) while (p < pend && !ISSPACE(*p)) p++; *p++ = '\0'; - if (rb_safe_level() == 0) { - rb_ary_push(rb_load_path, rb_str_new2(".")); - addpath(getenv("RUBYLIB")); - } - if (p < pend) { argv = ALLOCA_N(char*, origargc+3); @@ -71,16 +71,6 @@ extern "C" { #include <alloca.h> #endif -#if defined(__CYGWIN32__) -#if defined(USEIMPORTLIB) -#include "import.h" -#else -#if !defined(__CYGWIN__) -#define environ (*__imp___cygwin_environ) -#endif -#endif -#endif - #ifdef _AIX #pragma alloca #endif diff --git a/sample/cal.rb b/sample/cal.rb index 8eea4abfdb..c15bb29fc6 100644 --- a/sample/cal.rb +++ b/sample/cal.rb @@ -1,9 +1,10 @@ #! /usr/local/bin/ruby -# cal.rb: Written by Tadayoshi Funaba 1998, 1999 -# $Id: cal.rb,v 1.6 1999/09/15 05:35:25 tadf Exp $ +# cal.rb: Written by Tadayoshi Funaba 1998-2000 +# $Id: cal.rb,v 1.10 2000/05/20 02:09:47 tadf Exp $ require 'date2' +require 'getopts' $tab = { @@ -31,89 +32,81 @@ $tab = $cc = 'gb' def usage - $stderr.puts 'usage: cal [-c iso3166] [-jy] [[month] year]' + $stderr.puts 'usage: cal [-c iso3166] [-jmty] [[month] year]' exit 1 end -def cal(m, y, sg) - for d in 1..31 - break if jd = Date.exist?(y, m, d, sg) - end - fst = cur = Date.new1(jd, sg) - ti = Date::MONTHNAMES[m] - ti << ' ' << y.to_s unless $yr - mo = ti.center((($w + 1) * 7) - 1) << "\n" - mo << ['S', 'M', 'Tu', 'W', 'Th', 'F', 'S']. - collect{|x| x.rjust($w)}.join(' ') << "\n" - mo << ' ' * (($w + 1) * fst.wday) - while cur.mon == fst.mon - mo << (if $jd then cur.yday else cur.mday end).to_s.rjust($w) - mo << (if (cur += 1).wday != 0 then "\s" else "\n" end) - end - mo << "\n" * (6 - ((fst.wday + (cur - fst)) / 7)) - mo +def pict(y, m, sg) + d = (1..31).detect{|d| Date.exist?(y, m, d, sg)} + fi = Date.new3(y, m, d, sg) + fi -= (fi.jd - $k + 1) % 7 + + ve = (fi..fi + 6).collect{|cu| + %w(S M Tu W Th F S)[cu.wday] + } + ve += (fi..fi + 41).collect{|cu| + if cu.mon == m then cu.send($da) end.to_s + } + + ve = ve.collect{|e| e.rjust($dw)} + + gr = group(ve, 7) + gr = trans(gr) if $OPT_t + ta = gr.collect{|xs| xs.join(' ')} + + ca = %w(January February March April + May June July August + September October November December)[m - 1] + ca = ca + ' ' + y.to_s if not $OPT_y + ca = ca.center($mw) + + ta.unshift(ca) end -def zip(xs) - yr = '' - until xs.empty? - ln = (if $jd then l, r, *xs = xs; [l, r] - else l, c, r, *xs = xs; [l, c, r] end). - collect{|x| x.split(/\n/no, -1)} - 8.times do - yr << ln.collect{|x| - x.shift.ljust((($w + 1) * 7) - 1)}.join(' ') << "\n" - end - end - yr +def group(xs, n) + (0..xs.size / n - 1).collect{|i| xs[i * n, n]} end -while /^-([^-].*)$/no =~ $*[0] - a = $1 - if /^c(.+)?$/no =~ a - if $1 - $cc = $1.downcase - elsif $*.length >= 2 - $cc = $*[1].downcase - $*.shift - else - usage - end - else - a.scan(/./no) do |c| - case c - when 'j'; $jd = true - when 'y'; $yr = true - else usage - end - end - end - $*.shift +def trans(xs) + (0..xs[0].size - 1).collect{|i| xs.collect{|x| x[i]}} end -$*.shift if /^--/no =~ $*[0] -usage if (sg = $tab[$cc]).nil? -case $*.length -when 0 - td = Date.today - m = td.mon - y = td.year -when 1 - y = $*[0].to_i - $yr = true -when 2 - m = $*[0].to_i - y = $*[1].to_i -else - usage + +def unite(xs) + if xs.empty? then [] else xs[0] + unite(xs[1..-1]) end end -usage unless m.nil? or (1..12) === m -usage unless y >= -4712 -$w = if $jd then 3 else 2 end -unless $yr - print cal(m, y, sg) -else - print y.to_s.center(((($w + 1) * 7) - 1) * - (if $jd then 2 else 3 end) + - (if $jd then 2 else 4 end)), "\n\n", - zip((1..12).collect{|m| cal(m, y, sg)}), "\n" + +def block(xs, n) + unite(group(xs, n).collect{|ys| trans(ys).collect{|zs| zs.join(' ')}}) +end + +def unlines(xs) + xs.collect{|x| x + "\n"}.join end + +usage unless getopts('jmty', "c:#{$cc}") + +y, m = ARGV.indexes(1, 0).compact.collect{|x| x.to_i} +$OPT_y ||= (y and not m) + +to = Date.today +y ||= to.year +m ||= to.mon + +usage unless m >= 1 and m <= 12 +usage unless y >= -4712 +usage unless sg = $tab[$OPT_c] + +$dw = if $OPT_j then 3 else 2 end +$mw = ($dw + 1) * 7 - 1 +$mn = if $OPT_j then 2 else 3 end +$tw = ($mw + 2) * $mn - 2 + +$k = if $OPT_m then 1 else 0 end +$da = if $OPT_j then :yday else :mday end + +print (if not $OPT_y + unlines(pict(y, m, sg)) + else + y.to_s.center($tw) + "\n\n" + + unlines(block((1..12).collect{|m| pict(y, m, sg)}, $mn)) + "\n" + end) @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.4.4" -#define RUBY_RELEASE_DATE "2000-05-12" +#define RUBY_RELEASE_DATE "2000-05-30" #define RUBY_VERSION_CODE 144 -#define RUBY_RELEASE_CODE 20000512 +#define RUBY_RELEASE_CODE 20000530 diff --git a/win32/Makefile b/win32/Makefile index af9349a070..620e2d731a 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -91,11 +91,9 @@ ext/extmk.rb: ext/extmk.rb.in rbconfig.rb miniruby$(EXEEXT): $(OBJS) $(MAINOBJ) $(EXTOBJS) @echo $(EXTOBJS) @echo $(LIBS) - @rm -f $@ $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(OBJS) $(LIBS) -o $@ $(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(LIBRUBY_SO) - @rm -f $@ $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) -o $@ $(LIBRUBYARG) -link /STACK:$(STACK) $(LIBRUBY_A): $(OBJS) dmyext.obj @@ -106,9 +104,7 @@ rubymw.lib: ruby.def $(LIBRUBY_SO): $(LIBRUBY_A) $(EXTOBJS) ruby.def set LIB=.\win32;$(ORGLIBPATH) - @rm -f $@ $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A) $(LIBS) -o $@ -link /DLL /DEF:ruby.def - @mv rubymw.map rubydll.map install: rbconfig.rb .\miniruby.exe $(srcdir)/instruby.rb $(DESTDIR) |