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:
parent
a52442f27e
commit
5df72288f8
4 changed files with 136 additions and 52 deletions
13
ChangeLog
13
ChangeLog
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue