diff --git a/ChangeLog b/ChangeLog index d81327eaa4..62f3952718 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Thu Jan 17 16:21:42 2002 Yukihiro Matsumoto + + * eval.c (block_pass): allow "retry" from within argument passed + block. [new] + + * eval.c (localjump_error): should preserve exit status in the + exception object. [new] + + * eval.c (proc_invoke): should raise exception for "break" if it's + yielding, not calling. [new] + + * eval.c (block_pass): should NOT raise exception for "break". [new] + + * eval.c (block_pass): should allow block argument relay even in + the tainted mode. + +Thu Jan 17 04:51:48 2002 Yukihiro Matsumoto + + * ext/socket/socket.c: support subclassing by proper "initialize" + calling convention. [new] + Wed Jan 16 18:25:08 2002 Yukihiro Matsumoto * st.c: primes should be primes. @@ -5,10 +26,10 @@ Wed Jan 16 18:25:08 2002 Yukihiro Matsumoto Wed Jan 16 12:29:14 2002 Tanaka Akira * lib/timeout.rb (timeout): new optional argument to specify an - exception class. + exception class. * lib/resolv.rb: use Resolv::ResolvTimeout for internal timeout to - avoid problem with timeout of application. + avoid problem with timeout of application. Wed Jan 16 11:12:30 2002 Nobuyoshi Nakada diff --git a/eval.c b/eval.c index 55e5dd6f1d..069c7be361 100644 --- a/eval.c +++ b/eval.c @@ -1311,6 +1311,22 @@ rb_eval_string_wrap(str, state) return val; } +static void +localjump_error(mesg, status) + const char *mesg; +{ + VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg); + rb_iv_set(exc, "@status", status); + rb_exc_raise(exc); +} + +static VALUE +localjump_exitstatus(exc) + VALUE exc; +{ + return rb_iv_get(exc, "@status"); +} + static void jump_tag_but_local_jump(state) int state; @@ -1319,19 +1335,19 @@ jump_tag_but_local_jump(state) case 0: break; case TAG_RETURN: - rb_raise(rb_eLocalJumpError, "unexpected return"); + localjump_error("unexpected return", Qnil); break; case TAG_NEXT: - rb_raise(rb_eLocalJumpError, "unexpected next"); + localjump_error("unexpected next", Qnil); break; case TAG_BREAK: - rb_raise(rb_eLocalJumpError, "unexpected break"); + localjump_error("unexpected break", Qnil); break; case TAG_REDO: - rb_raise(rb_eLocalJumpError, "unexpected redo"); + localjump_error("unexpected redo", Qnil); break; case TAG_RETRY: - rb_raise(rb_eLocalJumpError, "retry outside of rescue clause"); + localjump_error("retry outside of rescue clause", Qnil); break; default: JUMP_TAG(state); @@ -3660,7 +3676,7 @@ rb_yield_0(val, self, klass, pcall) static unsigned serial = 1; if (!rb_block_given_p()) { - rb_raise(rb_eLocalJumpError, "no block given"); + localjump_error("no block given", Qnil); } PUSH_VARS(); @@ -6309,22 +6325,30 @@ proc_save_safe_level(data) } } -static void -proc_set_safe_level(data) +static int +proc_get_safe_level(data) VALUE data; { if (OBJ_TAINTED(data)) { switch (RBASIC(data)->flags & PROC_TMASK) { case PROC_T3: - ruby_safe_level = 3; - break; + return 3; case PROC_T4: - ruby_safe_level = 4; - break; + return 4; case PROC_TMAX: - ruby_safe_level = 5; - break; + return 5; } + return 3; + } + return 0; +} + +static void +proc_set_safe_level(data) + VALUE data; +{ + if (OBJ_TAINTED(data)) { + ruby_safe_level = proc_get_safe_level(data); } } @@ -6461,14 +6485,17 @@ proc_invoke(proc, args, pcall, self) case 0: break; case TAG_BREAK: + if (!pcall && orphan) { + localjump_error("break from proc-closure", prot_tag->retval); + } result = prot_tag->retval; break; case TAG_RETRY: - rb_raise(rb_eLocalJumpError, "retry from proc-closure"); + localjump_error("retry from proc-closure", Qnil); break; case TAG_RETURN: if (orphan) { /* orphan procedure */ - rb_raise(rb_eLocalJumpError, "return from proc-closure"); + localjump_error("return from proc-closure", prot_tag->retval); } /* fall through */ default: @@ -6577,12 +6604,15 @@ block_pass(self, node) } if (rb_safe_level() >= 1 && OBJ_TAINTED(block)) { - rb_raise(rb_eSecurityError, "Insecure: tainted block value"); + if (rb_safe_level() > proc_get_safe_level(block)) { + rb_raise(rb_eSecurityError, "Insecure: tainted block value"); + } } Data_Get_Struct(block, struct BLOCK, data); orphan = blk_orphan(data); + retry: /* PUSH BLOCK from data */ old_block = ruby_block; _block = *data; @@ -6626,16 +6656,13 @@ block_pass(self, node) case 0: break; case TAG_BREAK: - if (orphan) { - rb_raise(rb_eLocalJumpError, "break from proc-closure"); - } + result = prot_tag->retval; break; case TAG_RETRY: - rb_raise(rb_eLocalJumpError, "retry from proc-closure"); - break; + goto retry; case TAG_RETURN: if (orphan) { - rb_raise(rb_eLocalJumpError, "return from proc-closure"); + localjump_error("return from proc-closure", prot_tag->retval); } default: JUMP_TAG(state); @@ -7008,6 +7035,8 @@ void Init_Proc() { rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError); + rb_define_method(rb_eLocalJumpError, "exitstatus", localjump_exitstatus, 0); + rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError); rb_cProc = rb_define_class("Proc", rb_cObject); diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 49a162149f..5e676e5b6d 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -172,12 +172,11 @@ sock_finalize(fptr) #endif static VALUE -sock_new(class, fd) - VALUE class; +init_sock(sock, fd) + VALUE sock; int fd; { OpenFile *fp; - VALUE sock = rb_obj_alloc(class); MakeOpenFile(sock, fp); fp->f = rb_fdopen(fd, "r"); @@ -811,8 +810,8 @@ load_addr_info(h, serv, type, res) } static VALUE -open_inet(class, remote_host, remote_serv, local_host, local_serv, type) - VALUE class, remote_host, remote_serv, local_host, local_serv; +init_inetsock(sock, remote_host, remote_serv, local_host, local_serv, type) + VALUE sock, remote_host, remote_serv, local_host, local_serv; int type; { struct addrinfo hints, *res, *res_remote, *res_local = NULL; @@ -890,14 +889,14 @@ open_inet(class, remote_host, remote_serv, local_host, local_serv, type) if (res_local) freeaddrinfo(res_local); freeaddrinfo(res_remote); - return sock_new(class, fd); + return init_sock(sock, fd); } static VALUE -tcp_s_open(argc, argv, class) +tcp_init(argc, argv, sock) int argc; VALUE *argv; - VALUE class; + VALUE sock; { VALUE remote_host, remote_serv; VALUE local_host, local_serv; @@ -906,19 +905,23 @@ tcp_s_open(argc, argv, class) &remote_host, &remote_serv, &local_host, &local_serv); - SafeStringValue(remote_host); - if (!NIL_P(local_host)) { - SafeStringValue(local_host); - } + return init_inetsock(sock, remote_host, remote_serv, + local_host, local_serv, INET_CLIENT); +} - return open_inet(class, remote_host, remote_serv, - local_host, local_serv, INET_CLIENT); +static VALUE +tcp_s_open(argc, argv, klass) + int argc; + VALUE *argv; + VALUE klass; +{ + return tcp_init(argc, argv, rb_obj_alloc(klass)); } #ifdef SOCKS static VALUE -socks_s_open(class, host, serv) - VALUE class, host, serv; +socks_init(sock, host, serv) + VALUE sock, host, serv; { static init = 0; @@ -927,8 +930,14 @@ socks_s_open(class, host, serv) init = 1; } - SafeStringValue(host); - return open_inet(class, host, serv, Qnil, Qnil, INET_SOCKS); + return init_inetsock(class, host, serv, Qnil, Qnil, INET_SOCKS); +} + +static VALUE +socks_s_open(klass, host, serv) + VALUE klass, host, serv; +{ + return socks_init(rb_obj_alloc(klass), host, serv); } #ifdef SOCKS5 @@ -1063,22 +1072,31 @@ tcp_s_gethostbyname(obj, host) } static VALUE -tcp_svr_s_open(argc, argv, class) +tcp_svr_init(argc, argv, sock) int argc; VALUE *argv; - VALUE class; + VALUE sock; { VALUE arg1, arg2; if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) - return open_inet(class, arg1, arg2, NULL, Qnil, INET_SERVER); + return init_inetsock(sock, arg1, arg2, NULL, Qnil, INET_SERVER); else - return open_inet(class, Qnil, arg1, NULL, Qnil, INET_SERVER); + return init_inetsock(sock, Qnil, arg1, NULL, Qnil, INET_SERVER); } static VALUE -s_accept(class, fd, sockaddr, len) - VALUE class; +tcp_svr_s_open(argc, argv, klass) + int argc; + VALUE *argv; + VALUE klass; +{ + return tcp_svr_s_init(argc, argv, rb_obj_alloc(klass)); +} + +static VALUE +s_accept(klass, fd, sockaddr, len) + VALUE klass; int fd; struct sockaddr *sockaddr; socklen_t *len; @@ -1110,7 +1128,7 @@ s_accept(class, fd, sockaddr, len) } rb_sys_fail(0); } - return sock_new(class, fd2); + return init_sock(rb_obj_alloc(klass), fd2); } static VALUE @@ -1129,14 +1147,13 @@ tcp_accept(sock) #ifdef HAVE_SYS_UN_H static VALUE -open_unix(class, path, server) - VALUE class; +init_unixsock(sock, path, server) + VALUE sock; VALUE path; int server; { struct sockaddr_un sockaddr; int fd, status; - VALUE sock; OpenFile *fptr; SafeStringValue(path); @@ -1168,7 +1185,7 @@ open_unix(class, path, server) if (server) listen(fd, 5); - sock = sock_new(class, fd); + init_sock(sock, fd); GetOpenFile(sock, fptr); fptr->path = strdup(RSTRING(path)->ptr); @@ -1226,10 +1243,10 @@ ip_s_getaddress(obj, host) } static VALUE -udp_s_open(argc, argv, class) +udp_init(argc, argv, sock) int argc; VALUE *argv; - VALUE class; + VALUE sock; { VALUE arg; int socktype = AF_INET; @@ -1244,7 +1261,16 @@ udp_s_open(argc, argv, class) rb_sys_fail("socket(2) - udp"); } - return sock_new(class, fd); + return init_sock(sock, fd); +} + +static VALUE +udp_s_open(argc, argv, klass) + int argc; + VALUE *argv; + VALUE klass; +{ + return udp_init(argc, argv, rb_obj_alloc(klass)); } static VALUE @@ -1336,10 +1362,17 @@ udp_send(argc, argv, sock) #ifdef HAVE_SYS_UN_H static VALUE -unix_s_sock_open(sock, path) +unix_s_sock_open(klass, path) + VALUE klass, path; +{ + return init_unixsock(rb_obj_alloc(klass), path, 0); +} + +static VALUE +unix_init(sock, path) VALUE sock, path; { - return open_unix(sock, path, 0); + return init_unixsock(sock, path, 0); } static VALUE @@ -1360,7 +1393,14 @@ unix_path(sock) } static VALUE -unix_svr_s_open(sock, path) +unix_svr_s_open(klass, path) + VALUE klass, path; +{ + return init_unixsock(rb_obj_alloc(klass), path, 1); +} + +static VALUE +unix_svr_init(sock, path) VALUE sock, path; { return open_unix(sock, path, 1); @@ -1520,8 +1560,8 @@ setup_domain_and_type(domain, dv, type, tv) } static VALUE -sock_s_open(class, domain, type, protocol) - VALUE class, domain, type, protocol; +sock_init(sock, domain, type, protocol) + VALUE sock, domain, type, protocol; { int fd; int d, t; @@ -1531,19 +1571,26 @@ sock_s_open(class, domain, type, protocol) fd = ruby_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); - return sock_new(class, fd); + return init_sock(sock, fd); } static VALUE -sock_s_for_fd(class, fd) - VALUE class, fd; +sock_s_open(klass, domain, type, protocol) + VALUE klass, domain, type, protocol; { - return sock_new(class, NUM2INT(fd)); + return init_sock(rb_obj_alloc(klass), domain, type, protocol); } static VALUE -sock_s_socketpair(class, domain, type, protocol) - VALUE class, domain, type, protocol; +sock_s_for_fd(klass, fd) + VALUE klass, fd; +{ + return init_sock(rb_obj_alloc(klass), NUM2INT(fd)); +} + +static VALUE +sock_s_socketpair(klass, domain, type, protocol) + VALUE klass, domain, type, protocol; { #if !defined(NT) && !defined(__BEOS__) && !defined(__EMX__) && !defined(__QNXNTO__) int d, t, sp[2]; @@ -1558,7 +1605,7 @@ sock_s_socketpair(class, domain, type, protocol) rb_sys_fail("socketpair(2)"); } - return rb_assoc_new(sock_new(class, sp[0]), sock_new(class, sp[1])); + return rb_assoc_new(sock_new(klass, sp[0]), sock_new(klass, sp[1])); #else rb_notimplement(); #endif @@ -2117,8 +2164,8 @@ Init_socket() rb_eSocket = rb_define_class("SocketError", rb_eStandardError); rb_cBasicSocket = rb_define_class("BasicSocket", rb_cIO); - rb_undef_method(CLASS_OF(rb_cBasicSocket), "new"); rb_undef_method(CLASS_OF(rb_cBasicSocket), "open"); + rb_undef_method(rb_cBasicSocket, "initialize"); rb_define_singleton_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_rev_lookup, 0); @@ -2145,14 +2192,14 @@ Init_socket() rb_cTCPSocket = rb_define_class("TCPSocket", rb_cIPSocket); rb_define_global_const("TCPsocket", rb_cTCPSocket); rb_define_singleton_method(rb_cTCPSocket, "open", tcp_s_open, -1); - rb_define_singleton_method(rb_cTCPSocket, "new", tcp_s_open, -1); rb_define_singleton_method(rb_cTCPSocket, "gethostbyname", tcp_s_gethostbyname, 1); + rb_define_method(rb_cTCPSocket, "initialize", tcp_init, -1); #ifdef SOCKS rb_cSOCKSSocket = rb_define_class("SOCKSSocket", rb_cTCPSocket); rb_define_global_const("SOCKSsocket", rb_cSOCKSSocket); rb_define_singleton_method(rb_cSOCKSSocket, "open", socks_s_open, 2); - rb_define_singleton_method(rb_cSOCKSSocket, "new", socks_s_open, 2); + rb_define_method(rb_cSOCKSSocket, "initialize", socks_init, 2); #ifdef SOCKS5 rb_define_method(rb_cSOCKSSocket, "close", socks_s_close, 0); #endif @@ -2161,14 +2208,14 @@ Init_socket() rb_cTCPServer = rb_define_class("TCPServer", rb_cTCPSocket); rb_define_global_const("TCPserver", rb_cTCPServer); rb_define_singleton_method(rb_cTCPServer, "open", tcp_svr_s_open, -1); - rb_define_singleton_method(rb_cTCPServer, "new", tcp_svr_s_open, -1); rb_define_method(rb_cTCPServer, "accept", tcp_accept, 0); + rb_define_method(rb_cTCPServer, "initialize", tcp_svr_init, -1); rb_define_method(rb_cTCPServer, "listen", sock_listen, 1); rb_cUDPSocket = rb_define_class("UDPSocket", rb_cIPSocket); rb_define_global_const("UDPsocket", rb_cUDPSocket); rb_define_singleton_method(rb_cUDPSocket, "open", udp_s_open, -1); - rb_define_singleton_method(rb_cUDPSocket, "new", udp_s_open, -1); + rb_define_method(rb_cUDPSocket, "initialize", udp_init, -1); 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); @@ -2177,7 +2224,7 @@ Init_socket() rb_cUNIXSocket = rb_define_class("UNIXSocket", rb_cBasicSocket); rb_define_global_const("UNIXsocket", rb_cUNIXSocket); rb_define_singleton_method(rb_cUNIXSocket, "open", unix_s_sock_open, 1); - rb_define_singleton_method(rb_cUNIXSocket, "new", unix_s_sock_open, 1); + rb_define_method(rb_cUNIXSocket, "initialize", unix_init, 1); rb_define_method(rb_cUNIXSocket, "path", unix_path, 0); rb_define_method(rb_cUNIXSocket, "addr", unix_addr, 0); rb_define_method(rb_cUNIXSocket, "peeraddr", unix_peeraddr, 0); @@ -2186,16 +2233,16 @@ Init_socket() rb_cUNIXServer = rb_define_class("UNIXServer", rb_cUNIXSocket); rb_define_global_const("UNIXserver", rb_cUNIXServer); rb_define_singleton_method(rb_cUNIXServer, "open", unix_svr_s_open, 1); - rb_define_singleton_method(rb_cUNIXServer, "new", unix_svr_s_open, 1); + rb_define_method(rb_cUNIXServer, "initialize", unix_svr_init, 1); rb_define_method(rb_cUNIXServer, "accept", unix_accept, 0); rb_define_method(rb_cUNIXServer, "listen", sock_listen, 1); #endif rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); rb_define_singleton_method(rb_cSocket, "open", sock_s_open, 3); - rb_define_singleton_method(rb_cSocket, "new", sock_s_open, 3); rb_define_singleton_method(rb_cSocket, "for_fd", sock_s_for_fd, 1); + rb_define_method(rb_cSocket, "initialize", sock_init, 3); rb_define_method(rb_cSocket, "connect", sock_connect, 1); rb_define_method(rb_cSocket, "bind", sock_bind, 1); rb_define_method(rb_cSocket, "listen", sock_listen, 1); diff --git a/ext/tk/lib/README b/ext/tk/lib/README new file mode 100644 index 0000000000..87b59f4972 --- /dev/null +++ b/ext/tk/lib/README @@ -0,0 +1,15 @@ +README this file +tk.rb Tk interface +tkafter.rb handles Tcl after +tkbgerror.rb Tk error module +tkcanvas.rb Tk canvas interface +tkclass.rb provides generic names for Tk classes +tkdialog.rb Tk dialog class +tkentry.rb Tk entry class +tkfont.rb Tk font support +tkmenubar.rb TK menubar utility +tkmngfocus.rb focus manager +tkpalette.rb pallete support +tkscrollbox.rb scroll box, also example of compound widget +tktext.rb text classes +tkvirtevent.rb virtual event support diff --git a/version.h b/version.h index 38402e5514..bc00240015 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.7.2" -#define RUBY_RELEASE_DATE "2002-01-16" +#define RUBY_RELEASE_DATE "2002-01-17" #define RUBY_VERSION_CODE 172 -#define RUBY_RELEASE_CODE 20020116 +#define RUBY_RELEASE_CODE 20020117