diff --git a/ChangeLog b/ChangeLog index c6f6bb7257..3a2aa1a261 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri Apr 2 07:31:38 2004 Yukihiro Matsumoto + + * ext/socket/socket.c (make_hostent): fix memory leak, based on + the patch from HORIKAWA Hisashi . + Thu Apr 1 19:58:37 2004 NAKAMURA, Hiroshi * lib/soap/mapping/{factory.rb,registry.rb}: fixed illegal mapped URI diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 3bbc5fc8ea..d13f6484ae 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -65,7 +65,6 @@ #include "sockport.h" static int do_not_reverse_lookup = 0; -#define FMODE_NOREVLOOKUP 0x100 VALUE rb_cBasicSocket; VALUE rb_cIPSocket; @@ -179,9 +178,6 @@ init_sock(sock, fd) fp->f = rb_fdopen(fd, "r"); fp->f2 = rb_fdopen(fd, "w"); fp->mode = FMODE_READWRITE; - if (do_not_reverse_lookup) { - fp->mode |= FMODE_NOREVLOOKUP; - } rb_io_synchronized(fp); return sock; @@ -396,35 +392,7 @@ bsock_send(argc, argv, sock) return INT2FIX(n); } -static VALUE -bsock_do_not_reverse_lookup(sock) - VALUE sock; -{ - OpenFile *fptr; - - GetOpenFile(sock, fptr); - return (fptr->mode & FMODE_NOREVLOOKUP) ? Qtrue : Qfalse; -} - -static VALUE -bsock_do_not_reverse_lookup_set(sock, state) - VALUE sock; - VALUE state; -{ - OpenFile *fptr; - - rb_secure(4); - GetOpenFile(sock, fptr); - if (RTEST(state)) { - fptr->mode |= FMODE_NOREVLOOKUP; - } - else { - fptr->mode &= ~FMODE_NOREVLOOKUP; - } - return sock; -} - -static VALUE ipaddr _((struct sockaddr*, int)); +static VALUE ipaddr _((struct sockaddr*)); #ifdef HAVE_SYS_UN_H static VALUE unixaddr _((struct sockaddr_un*)); #endif @@ -492,7 +460,7 @@ s_recvfrom(sock, argc, argv, from) rb_raise(rb_eTypeError, "sockaddr size differs - should not happen"); } #endif - return rb_assoc_new(str, ipaddr((struct sockaddr*)buf, fptr->mode & FMODE_NOREVLOOKUP)); + return rb_assoc_new(str, ipaddr((struct sockaddr*)buf)); #ifdef HAVE_SYS_UN_H case RECV_UNIX: return rb_assoc_new(str, unixaddr((struct sockaddr_un*)buf)); @@ -528,15 +496,6 @@ bsock_do_not_rev_lookup_set(self, val) return val; } -static void -raise_socket_error(reason, error) - char *reason; - int error; -{ - if (error == EAI_SYSTEM) rb_sys_fail(reason); - rb_raise(rb_eSocket, "%s: %s", reason, gai_strerror(error)); -} - static void make_ipaddr0(addr, buf, len) struct sockaddr *addr; @@ -547,7 +506,7 @@ make_ipaddr0(addr, buf, len) error = getnameinfo(addr, SA_LEN(addr), buf, len, NULL, 0, NI_NUMERICHOST); if (error) { - raise_socket_error("getnameinfo", error); + rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error)); } } @@ -666,7 +625,8 @@ sock_addrinfo(host, port, socktype, flags) VALUE host, port; int socktype, flags; { - struct addrinfo hints, *hintsp, *res; + struct addrinfo hints; + struct addrinfo* res = NULL; char *hostp, *portp; int error; char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; @@ -678,18 +638,16 @@ sock_addrinfo(host, port, socktype, flags) socktype = SOCK_DGRAM; } - hintsp = &hints; MEMZERO(&hints, struct addrinfo, 1); - hints.ai_family = PF_UNSPEC; - hints.ai_protocol = 0; + hints.ai_family = AF_UNSPEC; hints.ai_socktype = socktype; hints.ai_flags = flags; - error = getaddrinfo(hostp, portp, hintsp, &res); + error = getaddrinfo(hostp, portp, &hints, &res); if (error) { if (hostp && hostp[strlen(hostp)-1] == '\n') { rb_raise(rb_eSocket, "newline at the end of hostname"); } - raise_socket_error("getaddrinfo", error); + rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error)); } #if defined(__APPLE__) && defined(__MACH__) @@ -713,9 +671,8 @@ sock_addrinfo(host, port, socktype, flags) } static VALUE -ipaddr(sockaddr, norevlookup) +ipaddr(sockaddr) struct sockaddr *sockaddr; - int norevlookup; { VALUE family, port, addr1, addr2; VALUE ary; @@ -748,22 +705,21 @@ ipaddr(sockaddr, norevlookup) family = rb_str_new2(pbuf); break; } - - if (!norevlookup) { + if (!do_not_reverse_lookup) { error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf), NULL, 0, 0); if (error) { - raise_socket_error("getnameinfo", error); + rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error)); } addr1 = rb_str_new2(hbuf); } error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (error) { - raise_socket_error("getnameinfo", error); + rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error)); } addr2 = rb_str_new2(hbuf); - if (norevlookup) { + if (do_not_reverse_lookup) { addr1 = addr2; } port = INT2FIX(atoi(pbuf)); @@ -1086,48 +1042,43 @@ socks_s_close(sock) #endif #endif -static VALUE -sock_gethostbyname(host, ipaddr) +struct hostent_arg { VALUE host; - VALUE (*ipaddr) _((struct sockaddr*, size_t)); + struct addrinfo* addr; + VALUE (*ipaddr)_((struct sockaddr*, size_t)); +}; + +static VALUE +make_hostent_internal(arg) + struct hostent_arg *arg; { - struct addrinfo *addr; + VALUE host = arg->host; + struct addrinfo* addr = arg->addr; + VALUE (*ipaddr)_((struct sockaddr*, size_t)) = arg->ipaddr; + struct addrinfo *ai; struct hostent *h; VALUE ary, names; - char *hostname; char **pch; + const char* hostp; + char hbuf[NI_MAXHOST]; - addr = sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME); ary = rb_ary_new(); if (addr->ai_canonname) { - hostname = addr->ai_canonname; + hostp = addr->ai_canonname; } else { - hostname = StringValuePtr(host); + hostp = host_str(host, hbuf, sizeof(hbuf)); } - rb_ary_push(ary, rb_str_new2(hostname)); -#if defined(HAVE_GETIPNODEBYNAME) - { - int error; + rb_ary_push(ary, rb_str_new2(hostp)); - h = getipnodebyname(hostname, addr->ai_family, AI_ALL, &error); - } -#elif defined(HAVE_GETHOSTBYNAME2) - h = gethostbyname2(hostname, addr->ai_family); -#else - h = gethostbyname(hostname); -#endif - if (h) { + if (addr->ai_canonname && (h = gethostbyname(addr->ai_canonname))) { names = rb_ary_new(); if (h->h_aliases != NULL) { for (pch = h->h_aliases; *pch; pch++) { rb_ary_push(names, rb_str_new2(*pch)); } } -#if defined(HAVE_GETIPNODEBYNAME) - freehostent(h); -#endif } else { names = rb_ary_new2(0); @@ -1141,6 +1092,22 @@ sock_gethostbyname(host, ipaddr) return ary; } +static VALUE +make_hostent(host, addr, ipaddr) + VALUE host; + struct addrinfo* addr; + VALUE (*ipaddr)_((struct sockaddr*, size_t)); +{ + VALUE ary; + struct hostent_arg arg; + + arg.host = host; + arg.addr = addr; + arg.ipaddr = ipaddr; + ary = rb_ensure(make_hostent_internal, (VALUE)&arg, + RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)addr); +} + VALUE tcp_sockaddr(addr, len) struct sockaddr *addr; @@ -1154,7 +1121,7 @@ tcp_s_gethostbyname(obj, host) VALUE obj, host; { rb_secure(3); - return sock_gethostbyname(host, tcp_sockaddr); + return make_hostent(host, sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), tcp_sockaddr); } static VALUE @@ -1314,7 +1281,7 @@ ip_addr(sock) if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getsockname(2)"); - return ipaddr((struct sockaddr*)&addr, fptr->mode & FMODE_NOREVLOOKUP); + return ipaddr((struct sockaddr*)&addr); } static VALUE @@ -1329,7 +1296,7 @@ ip_peeraddr(sock) if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0) rb_sys_fail("getpeername(2)"); - return ipaddr((struct sockaddr*)&addr, fptr->mode & FMODE_NOREVLOOKUP); + return ipaddr((struct sockaddr*)&addr); } static VALUE @@ -1715,7 +1682,6 @@ unix_sysaccept(sock) return s_accept(0, fileno(fptr->f), (struct sockaddr*)&from, &fromlen); } -#ifdef HAVE_SYS_UN_H static VALUE unixaddr(sockaddr) struct sockaddr_un *sockaddr; @@ -1723,7 +1689,6 @@ unixaddr(sockaddr) return rb_assoc_new(rb_str_new2("AF_UNIX"), rb_str_new2(sockaddr->sun_path)); } -#endif static VALUE unix_addr(sock) @@ -2045,10 +2010,7 @@ make_addrinfo(res0) } base = rb_ary_new(); for (res = res0; res; res = res->ai_next) { - ary = ipaddr(res->ai_addr, do_not_reverse_lookup); - if (res->ai_canonname) { - RARRAY(ary)->ptr[2] = rb_str_new2(res->ai_canonname); - } + ary = ipaddr(res->ai_addr); rb_ary_push(ary, INT2FIX(res->ai_family)); rb_ary_push(ary, INT2FIX(res->ai_socktype)); rb_ary_push(ary, INT2FIX(res->ai_protocol)); @@ -2070,7 +2032,7 @@ sock_s_gethostbyname(obj, host) VALUE obj, host; { rb_secure(3); - return sock_gethostbyname(host, sock_sockaddr); + return make_hostent(host, sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr); } static VALUE @@ -2219,7 +2181,7 @@ sock_s_getaddrinfo(argc, argv) } error = getaddrinfo(hptr, pptr, &hints, &res); if (error) { - raise_socket_error("getaddrinfo", error); + rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error)); } ret = make_addrinfo(res); @@ -2356,11 +2318,11 @@ sock_s_getnameinfo(argc, argv) error_exit_addr: if (res) freeaddrinfo(res); - raise_socket_error("getaddrinfo", error); + rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error)); error_exit_name: if (res) freeaddrinfo(res); - raise_socket_error("getnameinfo", error); + rb_raise(rb_eSocket, "getnameinfo: %s", gai_strerror(error)); } static VALUE @@ -2460,8 +2422,6 @@ Init_socket() rb_define_method(rb_cBasicSocket, "getpeername", bsock_getpeername, 0); rb_define_method(rb_cBasicSocket, "send", bsock_send, -1); rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1); - rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup", bsock_do_not_reverse_lookup, 0); - rb_define_method(rb_cBasicSocket, "do_not_reverse_lookup=", bsock_do_not_reverse_lookup_set, 1); rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket); rb_define_global_const("IPsocket", rb_cIPSocket); diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index dac90ee1a2..1972003059 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -561,186 +561,156 @@ The variable ruby-indent-level controls the amount of indentation. (defun ruby-indent-size (pos nest) (+ pos (* (or nest 1) ruby-indent-level))) -;;; maybe obsolete -(defconst ruby-assign-re "\\s *\\(&&\\|||\\|<<\\|>>\\|[-+*/%&|^]\\)?=\\s *") - -;;; maybe obsolete -(defun ruby-beginning-of-arg (start end) - (save-restriction - (narrow-to-region start (1+ end)) - (goto-char start) - (let ((beg t) arg) - (while - (progn - (skip-chars-forward " \t\n") - (and (not (eobp)) - (= (ruby-forward-sexp) 0))) - (skip-syntax-forward " ") - (cond ((looking-at ",") - (forward-char) - (setq arg start beg t)) - ((ruby-expr-beg) t) - ((looking-at "=>\\s *") - (goto-char (match-end 0)) - (setq arg nil beg nil)) - ((looking-at ruby-assign-re) - (goto-char (match-end 0)) - (if beg (setq beg nil arg (point)))) - ((looking-at ruby-operator-re) - (goto-char (match-end 0)) - (echo "foo %s %s" arg beg) - (if beg (setq beg nil arg (match-end 0)))) - ((not (eq (char-syntax (char-after)) ?\()) - (setq start (point))))) - (goto-char (or arg start))))) - (defun ruby-calculate-indent (&optional parse-start) (save-excursion (beginning-of-line) (let ((indent-point (point)) - (case-fold-search nil) - state bol eol begin - (paren (progn (skip-syntax-forward " ") - (and (char-after) (matching-paren (char-after))))) - (indent 0)) - (if parse-start - (goto-char parse-start) - (ruby-beginning-of-indent) - (setq parse-start (point))) - (back-to-indentation) - (setq indent (current-column)) - (setq state (ruby-parse-region parse-start indent-point)) - (cond - ((nth 0 state) ; within string - (setq indent nil)) ; do nothing - ((car (nth 1 state)) ; in paren - (goto-char (setq begin (cdr (nth 1 state)))) - (let ((deep (ruby-deep-indent-paren-p (car (nth 1 state))))) - (if deep - (cond ((and (eq deep t) (eq (car (nth 1 state)) paren)) - (skip-syntax-backward " ") - (setq indent (1- (current-column)))) - ((let ((s (ruby-parse-region (point) indent-point))) - (and (nth 2 s) (> (nth 2 s) 0) - (or (goto-char (cdr (nth 1 s))) t))) - (forward-word -1) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (setq indent (current-column)) - (cond ((eq deep 'space)) - (paren (setq indent (1- indent))) - (t (setq indent (ruby-indent-size (1- indent) 1)))))) - (if (nth 3 state) (goto-char (nth 3 state)) - (goto-char parse-start) (back-to-indentation)) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))))) - ((and (nth 2 state) (> (nth 2 state) 0)) ; in nest - (if (null (cdr (nth 1 state))) - (error "invalid nest")) - (goto-char (cdr (nth 1 state))) - (forward-word -1) ; skip back a keyword - (setq begin (point)) - (cond - ((looking-at "do\\>[^_]") ; iter block is a special case + (case-fold-search nil) + state bol eol begin op-end + (paren (progn (skip-syntax-forward " ") + (and (char-after) (matching-paren (char-after))))) + (indent 0)) + (if parse-start + (goto-char parse-start) + (ruby-beginning-of-indent) + (setq parse-start (point))) + (back-to-indentation) + (setq indent (current-column)) + (setq state (ruby-parse-region parse-start indent-point)) + (cond + ((nth 0 state) ; within string + (setq indent nil)) ; do nothing + ((car (nth 1 state)) ; in paren + (goto-char (setq begin (cdr (nth 1 state)))) + (let ((deep (ruby-deep-indent-paren-p (car (nth 1 state))))) + (if deep + (cond ((and (eq deep t) (eq (car (nth 1 state)) paren)) + (skip-syntax-backward " ") + (setq indent (1- (current-column)))) + ((let ((s (ruby-parse-region (point) indent-point))) + (and (nth 2 s) (> (nth 2 s) 0) + (or (goto-char (cdr (nth 1 s))) t))) + (forward-word -1) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (t + (setq indent (current-column)) + (cond ((eq deep 'space)) + (paren (setq indent (1- indent))) + (t (setq indent (ruby-indent-size (1- indent) 1)))))) (if (nth 3 state) (goto-char (nth 3 state)) (goto-char parse-start) (back-to-indentation)) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (setq indent (+ (current-column) ruby-indent-level))))) - - ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest - (setq indent (ruby-indent-size (current-column) (nth 2 state))))) - (when indent - (goto-char indent-point) - (end-of-line) - (setq eol (point)) - (beginning-of-line) - (cond - ((and (not (ruby-deep-indent-paren-p paren)) - (re-search-forward ruby-negative eol t)) - (and (not (eq ?_ (char-after (match-end 0)))) - (setq indent (- indent ruby-indent-level)))) - ;;operator terminated lines - ((and - (save-excursion - (beginning-of-line) - (not (bobp))) - (or (ruby-deep-indent-paren-p t) - (null (car (nth 1 state))))) - ;; goto beginning of non-empty no-comment line - (let (end done) - (while (not done) - (skip-chars-backward " \t\n") - (setq end (point)) - (beginning-of-line) - (if (re-search-forward "^\\s *#" end t) - (beginning-of-line) - (setq done t)))) - (setq bol (point)) - (end-of-line) - (skip-chars-backward " \t") - (let (end (pos (point))) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))))) + ((and (nth 2 state) (> (nth 2 state) 0)) ; in nest + (if (null (cdr (nth 1 state))) + (error "invalid nest")) + (goto-char (cdr (nth 1 state))) + (forward-word -1) ; skip back a keyword + (setq begin (point)) + (cond + ((looking-at "do\\>[^_]") ; iter block is a special case + (if (nth 3 state) (goto-char (nth 3 state)) + (goto-char parse-start) (back-to-indentation)) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (t + (setq indent (+ (current-column) ruby-indent-level))))) + + ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest + (setq indent (ruby-indent-size (current-column) (nth 2 state))))) + (when indent + (goto-char indent-point) + (end-of-line) + (setq eol (point)) + (beginning-of-line) + (cond + ((and (not (ruby-deep-indent-paren-p paren)) + (re-search-forward ruby-negative eol t)) + (and (not (eq ?_ (char-after (match-end 0)))) + (setq indent (- indent ruby-indent-level)))) + ((and + (save-excursion + (beginning-of-line) + (not (bobp))) + (or (ruby-deep-indent-paren-p t) + (null (car (nth 1 state))))) + ;; goto beginning of non-empty no-comment line + (let (end done) + (while (not done) + (skip-chars-backward " \t\n") + (setq end (point)) (beginning-of-line) - (while (and (re-search-forward "#" pos t) - (setq end (1- (point))) - (ruby-special-char-p end)) - (setq end nil)) - (goto-char (or end pos)) - (skip-chars-backward " \t") - (setq state (ruby-parse-region parse-start (point))) - (setq begin (or (nth 0 state) (cdr (nth 1 state)))) - (goto-char pos)) - (or (bobp) (forward-char -1)) - (and - (or (and (looking-at ruby-symbol-re) - (skip-chars-backward ruby-symbol-chars) - (looking-at ruby-block-hanging-re) - (not (eq (point) (nth 3 state))) - (save-excursion - (goto-char (match-end 0)) - (not (looking-at "[a-z_]")))) - (and (looking-at ruby-operator-re) - (not (ruby-special-char-p)) - (let ((c (char-after (point)))) - (and - (or (not (eq ?, c)) - (null begin) - (save-excursion - (goto-char begin) - (skip-chars-forward " \t") - (not (or (eolp) (looking-at "#") - (and (eq (car (nth 1 state)) ?{) - (looking-at "|")))))) - (or (not (eq ?/ c)) - (null (nth 0 (ruby-parse-region (or begin parse-start) (point))))) - (or (not (eq ?| (char-after (point)))) - (save-excursion - (or (eolp) (forward-char -1)) - (cond - ((search-backward "|" nil t) - (skip-chars-backward " \t\n") - (and (not (eolp)) - (progn - (forward-char -1) - (not (looking-at "{"))) - (progn - (forward-word -1) - (not (looking-at "do\\>[^_]"))))) - (t t)))))))) - (setq indent - (cond - ((and - (not (looking-at ruby-block-hanging-re)) - (eq (ruby-deep-indent-paren-p t) 'space) - (not (bobp))) - (save-excursion - (widen) - (goto-char (or begin parse-start)) - (skip-syntax-forward " ") -;; (ruby-beginning-of-arg (or begin parse-start) (point)) - (current-column))) - (t - (+ indent ruby-indent-level)))))))) - indent))) + (if (re-search-forward "^\\s *#" end t) + (beginning-of-line) + (setq done t)))) + (setq bol (point)) + (end-of-line) + ;; skip the comment at the end + (skip-chars-backward " \t") + (let (end (pos (point))) + (beginning-of-line) + (while (and (re-search-forward "#" pos t) + (setq end (1- (point))) + (or (ruby-special-char-p end) + (and (setq state (ruby-parse-region parse-start end)) + (nth 0 state)))) + (setq end nil)) + (goto-char (or end pos)) + (skip-chars-backward " \t") + (setq begin (if (nth 0 state) pos (cdr (nth 1 state)))) + (setq state (ruby-parse-region parse-start (point)))) + (or (bobp) (forward-char -1)) + (and + (or (and (looking-at ruby-symbol-re) + (skip-chars-backward ruby-symbol-chars) + (looking-at ruby-block-hanging-re) + (not (eq (point) (nth 3 state))) + (save-excursion + (goto-char (match-end 0)) + (not (looking-at "[a-z_]")))) + (and (looking-at ruby-operator-re) + (not (ruby-special-char-p)) + ;; operator at the end of line + (let ((c (char-after (point)))) + (and +;; (or (null begin) +;; (save-excursion +;; (goto-char begin) +;; (skip-chars-forward " \t") +;; (not (or (eolp) (looking-at "#") +;; (and (eq (car (nth 1 state)) ?{) +;; (looking-at "|")))))) + (or (not (eq ?/ c)) + (null (nth 0 (ruby-parse-region (or begin parse-start) (point))))) + (or (not (eq ?| (char-after (point)))) + (save-excursion + (or (eolp) (forward-char -1)) + (cond + ((search-backward "|" nil t) + (skip-chars-backward " \t\n") + (and (not (eolp)) + (progn + (forward-char -1) + (not (looking-at "{"))) + (progn + (forward-word -1) + (not (looking-at "do\\>[^_]"))))) + (t t)))) + (not (eq ?, c)) + (setq op-end t))))) + (setq indent + (cond + ((and + (null op-end) + (not (looking-at ruby-block-hanging-re)) + (eq (ruby-deep-indent-paren-p t) 'space) + (not (bobp))) + (save-excursion + (widen) + (goto-char (or begin parse-start)) + (skip-syntax-forward " ") + (current-column))) + (t + (+ indent ruby-indent-level)))))))) + indent))) (defun ruby-electric-brace (arg) (interactive "P")