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

* ext/socket/addrinfo.h: typo.

* ext/socket/getaddrinfo.c (gai_strerror): get rid of warning.

* ext/socket/socket.c (init_inetsock): ensures resources are
  freed at exceptions.

* ext/socket/socket.c (init_unixsock): ditto.

* ext/socket/socket.c (udp_connect): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2511 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2002-06-03 15:52:28 +00:00
parent a52442f27e
commit 5df72288f8
4 changed files with 136 additions and 52 deletions

View file

@ -1,3 +1,16 @@
Tue Jun 4 00:45:50 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/socket/addrinfo.h: typo.
* ext/socket/getaddrinfo.c (gai_strerror): get rid of warning.
* ext/socket/socket.c (init_inetsock): ensures resources are
freed at exceptions.
* ext/socket/socket.c (init_unixsock): ditto.
* ext/socket/socket.c (udp_connect): ditto.
Mon Jun 3 20:39:51 2002 Masaki Suketa <masaki.suketa@nifty.ne.jp> Mon Jun 3 20:39:51 2002 Masaki Suketa <masaki.suketa@nifty.ne.jp>
* ext/win32ole/extconf.rb : change PLATFORM with RUBY_PLATFORM. * ext/win32ole/extconf.rb : change PLATFORM with RUBY_PLATFORM.

View file

@ -153,7 +153,7 @@ extern int getnameinfo __P((
int flags)); int flags));
extern void freehostent __P((struct hostent *)); extern void freehostent __P((struct hostent *));
extern void freeaddrent __P((struct addrinfo *)); extern void freeaddrinfo __P((struct addrinfo *));
#if defined __UCLIBC__ #if defined __UCLIBC__
const const
#endif #endif

View file

@ -200,7 +200,7 @@ gai_strerror(ecode)
{ {
if (ecode < 0 || ecode > EAI_MAX) if (ecode < 0 || ecode > EAI_MAX)
ecode = EAI_MAX; ecode = EAI_MAX;
return ai_errlist[ecode]; return (char *)ai_errlist[ecode];
} }
void void

View file

@ -158,6 +158,11 @@ ruby_getaddrinfo(nodename, servname, hints, res)
#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res)) #define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res))
#endif #endif
#ifdef HAVE_CLOSESOCKET
#undef close
#define close closesocket
#endif
#ifdef NT #ifdef NT
static void sock_finalize _((OpenFile *fptr)); static void sock_finalize _((OpenFile *fptr));
@ -844,34 +849,63 @@ load_addr_info(h, serv, type, res)
} }
} }
static VALUE struct inetsock_arg
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; VALUE sock;
struct {
VALUE host, serv;
struct addrinfo *res;
} remote, local;
int type;
int fd;
};
static VALUE
inetsock_cleanup(arg)
struct inetsock_arg *arg;
{
if (arg->remote.res) {
freeaddrinfo(arg->remote.res);
arg->remote.res = 0;
}
if (arg->local.res) {
freeaddrinfo(arg->local.res);
arg->local.res = 0;
}
if (arg->fd >= 0) {
close(arg->fd);
}
return Qnil;
}
static VALUE
init_inetsock_internal(arg)
struct inetsock_arg *arg;
{
int type = arg->type;
struct addrinfo hints, *res;
int fd, status; int fd, status;
char *syscall; char *syscall;
res_remote = sock_addrinfo(remote_host, remote_serv, SOCK_STREAM, arg->remote.res = sock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM,
(type == INET_SERVER) ? AI_PASSIVE : 0); (type == INET_SERVER) ? AI_PASSIVE : 0);
/* /*
* Maybe also accept a local address * Maybe also accept a local address
*/ */
if (type != INET_SERVER && (!NIL_P(local_host) || !NIL_P(local_serv))) { if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) {
res_local = sock_addrinfo(local_host, local_serv, SOCK_STREAM, arg->local.res = sock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0);
(type == INET_SERVER) ? AI_PASSIVE : 0);
} }
fd = -1; arg->fd = fd = -1;
for (res = res_remote; res; res = res->ai_next) { for (res = arg->remote.res; res; res = res->ai_next) {
status = ruby_socket(res->ai_family,res->ai_socktype,res->ai_protocol); status = ruby_socket(res->ai_family,res->ai_socktype,res->ai_protocol);
syscall = "socket(2)"; syscall = "socket(2)";
fd = status; fd = status;
if (fd < 0) { if (fd < 0) {
continue; continue;
} }
arg->fd = fd;
if (type == INET_SERVER) { if (type == INET_SERVER) {
#ifndef NT #ifndef NT
status = 1; status = 1;
@ -882,8 +916,8 @@ init_inetsock(sock, remote_host, remote_serv, local_host, local_serv, type)
syscall = "bind(2)"; syscall = "bind(2)";
} }
else { else {
if (res_local) { if (arg->local.res) {
status = bind(fd, res_local->ai_addr, res_local->ai_addrlen); status = bind(fd, arg->local.res->ai_addr, arg->local.res->ai_addrlen);
syscall = "bind(2)"; syscall = "bind(2)";
} }
@ -895,38 +929,42 @@ init_inetsock(sock, remote_host, remote_serv, local_host, local_serv, type)
} }
if (status < 0) { if (status < 0) {
#if defined(HAVE_CLOSESOCKET)
closesocket(fd);
#else
close(fd); close(fd);
#endif arg->fd = fd = -1;
fd = -1;
continue; continue;
} else } else
break; break;
} }
if (status < 0) { if (status < 0) {
if (fd >= 0)
#if defined(HAVE_CLOSESOCKET)
closesocket(fd);
#else
close(fd);
#endif
freeaddrinfo(res_remote);
if (res_local) {
freeaddrinfo(res_local);
}
rb_sys_fail(syscall); rb_sys_fail(syscall);
} }
arg->fd = -1;
if (type == INET_SERVER) if (type == INET_SERVER)
listen(fd, 5); listen(fd, 5);
/* create new instance */ /* create new instance */
if (res_local) return init_sock(arg->sock, fd);
freeaddrinfo(res_local); }
freeaddrinfo(res_remote);
return init_sock(sock, fd); static VALUE
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 inetsock_arg arg;
arg.sock = sock;
arg.remote.host = remote_host;
arg.remote.serv = remote_serv;
arg.remote.res = 0;
arg.local.host = local_host;
arg.local.serv = local_serv;
arg.local.res = 0;
arg.type = type;
arg.fd = -1;
return rb_ensure(init_inetsock_internal, (VALUE)&arg,
inetsock_cleanup, (VALUE)&arg);
} }
static VALUE static VALUE
@ -1166,6 +1204,19 @@ tcp_sysaccept(sock)
} }
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
struct unixsock_arg {
struct sockaddr_un *sockaddr;
int fd;
};
static VALUE
unixsock_connect_internal(arg)
struct unixsock_arg *arg;
{
return (VALUE)ruby_connect(arg->fd, arg->sockaddr, sizeof(*arg->sockaddr),
0);
}
static VALUE static VALUE
init_unixsock(sock, path, server) init_unixsock(sock, path, server)
VALUE sock; VALUE sock;
@ -1191,15 +1242,19 @@ init_unixsock(sock, path, server)
status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
} }
else { else {
status = ruby_connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr), 0); int prot;
struct unixsock_arg arg;
arg.sockaddr = &sockaddr;
arg.fd = fd;
status = rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot);
if (prot) {
close(fd);
rb_jump_tag(prot);
}
} }
if (status < 0) { if (status < 0) {
#if defined(HAVE_CLOSESOCKET)
closesocket(fd);
#else
close(fd); close(fd);
#endif
rb_sys_fail(sockaddr.sun_path); rb_sys_fail(sockaddr.sun_path);
} }
@ -1284,27 +1339,43 @@ udp_init(argc, argv, sock)
return init_sock(sock, fd); return init_sock(sock, fd);
} }
struct udp_arg
{
struct addrinfo *res;
int fd;
};
static VALUE
udp_connect_internal(arg)
struct udp_arg *arg;
{
int fd = arg->fd;
struct addrinfo *res;
for (res = arg->res; res; res = res->ai_next) {
if (ruby_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) {
return Qtrue;
}
}
return Qfalse;
}
static VALUE static VALUE
udp_connect(sock, host, port) udp_connect(sock, host, port)
VALUE sock, host, port; VALUE sock, host, port;
{ {
OpenFile *fptr; OpenFile *fptr;
int fd; int fd;
struct addrinfo *res0, *res; struct udp_arg arg;
VALUE ret;
rb_secure(3); rb_secure(3);
GetOpenFile(sock, fptr); GetOpenFile(sock, fptr);
fd = fileno(fptr->f); arg.res = sock_addrinfo(host, port, SOCK_DGRAM, 0);
res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0); arg.fd = fileno(fptr->f);
for (res = res0; res; res = res->ai_next) { ret = rb_ensure(udp_connect_internal, (VALUE)&arg,
if (ruby_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) { RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)arg.res);
freeaddrinfo(res0); if (!ret) rb_sys_fail("connect(2)");
return INT2FIX(0);
}
}
freeaddrinfo(res0);
rb_sys_fail("connect(2)");
return INT2FIX(0); return INT2FIX(0);
} }