1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/socket/socket.c (make_hostent): fix memory leak, based on

the patch from HORIKAWA Hisashi <vzw00011@nifty.ne.jp>.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6065 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2004-04-01 23:13:39 +00:00
parent b9e7165e78
commit 64ec09d456
3 changed files with 203 additions and 268 deletions

View file

@ -1,3 +1,8 @@
Fri Apr 2 07:31:38 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
* ext/socket/socket.c (make_hostent): fix memory leak, based on
the patch from HORIKAWA Hisashi <vzw00011@nifty.ne.jp>.
Thu Apr 1 19:58:37 2004 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
* lib/soap/mapping/{factory.rb,registry.rb}: fixed illegal mapped URI

View file

@ -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);

View file

@ -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")