diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-05-10 08:22:50 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-05-10 08:22:50 +0000 |
commit | 27e948fd458b06c3a018d46f04599a874f43fd92 (patch) | |
tree | e369ed2a78f4d5393074804b71f136c84e9dfca5 /ext/socket | |
parent | 192463c7a5525008a7bf95065261877eff79cf74 (diff) |
regexp,range,squeeze
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@463 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket')
-rw-r--r-- | ext/socket/addrinfo.h | 8 | ||||
-rw-r--r-- | ext/socket/extconf.rb | 30 | ||||
-rw-r--r-- | ext/socket/getaddrinfo.c | 2 | ||||
-rw-r--r-- | ext/socket/getnameinfo.c | 2 | ||||
-rw-r--r-- | ext/socket/socket.c | 207 |
5 files changed, 138 insertions, 111 deletions
diff --git a/ext/socket/addrinfo.h b/ext/socket/addrinfo.h index 1236437897..5d2c7dea45 100644 --- a/ext/socket/addrinfo.h +++ b/ext/socket/addrinfo.h @@ -66,7 +66,7 @@ #define freeaddrinfo freeaddrinfo__compat #ifndef __P -# ifdef HAVE_PROTOTYPES 1 +# ifdef HAVE_PROTOTYPES # define __P(args) args # else # define __P(args) @@ -136,12 +136,6 @@ struct addrinfo { struct addrinfo *ai_next; /* next structure in linked list */ }; -struct sockaddr_storage { - u_int8_t __ss_len; - u_int8_t __ss_family; - u_int8_t fill[126]; -}; - extern int getaddrinfo __P(( const char *hostname, const char *servname, const struct addrinfo *hints, diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 12b24667b4..0526e319ec 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -21,17 +21,13 @@ else end $ipv6 = false -if enable_config("ipv6", true) - if try_run(<<EOF) +if enable_config("ipv6", false) + if try_link(<<EOF) #include <sys/types.h> #include <sys/socket.h> main() { - exit(0); - if (socket(AF_INET6, SOCK_STREAM, 0) < 0) - exit(1); - else - exit(0); + socket(AF_INET6, SOCK_STREAM, 0); } EOF $CFLAGS+=" -DENABLE_IPV6" @@ -39,7 +35,6 @@ EOF end end - $ipv6type = nil $ipv6lib = nil $ipv6libdir = nil @@ -101,9 +96,10 @@ EOF if $ipv6lib if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a" - $LDFLAGS += " -L#$ipv6libdir -l#$ipv6lib" + $LOCAL_LIBS = " -L#$ipv6libdir -l#$ipv6lib" else print <<EOS + Fatal: no #$ipv6lib library found. cannot continue. You need to fetch lib#{$ipv6lib}.a from appropriate ipv6 kit and compile beforehand. @@ -235,13 +231,21 @@ main() EOF $getaddr_info_ok = true end +if $ipv6 and not $getaddr_info_ok + print <<EOS + +Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature. +But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry, +you cannot compile IPv6 socket classes with broken these functions. +EOS + exit +end + $objs = ["socket.o"] -if $getaddr_info_ok - if have_func("getaddrinfo") and have_func("getnameinfo") - have_getaddrinfo = true - end +if $getaddr_info_ok and have_func("getaddrinfo") and have_func("getnameinfo") + have_getaddrinfo = true end if have_getaddrinfo diff --git a/ext/socket/getaddrinfo.c b/ext/socket/getaddrinfo.c index 64d29b17ab..cdc3de52e4 100644 --- a/ext/socket/getaddrinfo.c +++ b/ext/socket/getaddrinfo.c @@ -221,7 +221,7 @@ inet_pton(af, hostname, pton) struct in_addr in; #ifdef HAVE_INET_ATON - if (!inet_aton(hostname, &in.s_addr)) + if (!inet_aton(hostname, &in)) return 0; #else int d1, d2, d3, d4; diff --git a/ext/socket/getnameinfo.c b/ext/socket/getnameinfo.c index e4a57c6554..89245d324f 100644 --- a/ext/socket/getnameinfo.c +++ b/ext/socket/getnameinfo.c @@ -93,7 +93,7 @@ inet_ntop(af, addr, numaddr, numaddr_len) #ifdef HAVE_INET_NTOA struct in_addr in; memcpy(&in.s_addr, addr, sizeof(in.s_addr)); - strncpy(numaddr, numaddr_len, inet_ntoa(in)); + snprintf(numaddr, numaddr_len, "%s", inet_ntoa(in)); #else unsigned long x = ntohl(*(unsigned long*)addr); snprintf(numaddr, numaddr_len, "%d.%d.%d.%d", diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 6126ddf2b9..875f6f33d3 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -309,11 +309,13 @@ bsock_send(argc, argv, sock) if (n < 0) { switch (errno) { case EINTR: + rb_thread_schedule(); + goto retry; case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - rb_thread_schedule(); + rb_thread_fd_writable(fd); goto retry; } rb_sys_fail("send(2)"); @@ -367,11 +369,14 @@ s_recv(sock, argc, argv, from) if (RSTRING(str)->len < 0) { switch (errno) { case EINTR: + rb_thread_schedule(); + goto retry; + case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - rb_thread_schedule(); + rb_thread_wait_fd(fd); goto retry; } rb_sys_fail("recvfrom(2)"); @@ -422,7 +427,7 @@ mkipaddr(addr) error = getnameinfo(addr, SA_LEN(addr), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } return rb_str_new2(buf); } @@ -453,13 +458,13 @@ ipaddr(sockaddr) error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf), NULL, 0, 0); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%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) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } addr2 = rb_str_new2(hbuf); port = INT2FIX(atoi(pbuf)); @@ -479,7 +484,7 @@ setipaddr(name, addr) sin = (struct sockaddr_in *)addr; if (name[0] == 0) { - memset(sin, 0, sizeof(*sin)); + MEMZERO(sin, struct sockaddr_in, 1); sin->sin_family = AF_INET; SET_SIN_LEN(sin, sizeof(*sin)); sin->sin_addr.s_addr = INADDR_ANY; @@ -490,11 +495,11 @@ setipaddr(name, addr) sin->sin_addr.s_addr = INADDR_BROADCAST; } else { - memset(&hints, 0, sizeof(hints)); + MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; error = getaddrinfo(name, NULL, &hints, &res); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } /* just take the first one */ memcpy(addr, res->ai_addr, res->ai_addrlen); @@ -502,17 +507,27 @@ setipaddr(name, addr) } } +static void +thread_write_select(fd) + int fd; +{ + fd_set fds; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + rb_thread_select(fd+1, 0, &fds, 0, 0); +} + #if defined(HAVE_FCNTL) static int -thread_connect(fd, sockaddr, len, type) +ruby_connect(fd, sockaddr, len, socks) int fd; struct sockaddr *sockaddr; int len; - int type; + int socks; { int status; int mode; - fd_set fds; mode = fcntl(fd, F_GETFL, 0); @@ -528,7 +543,7 @@ thread_connect(fd, sockaddr, len, type) fcntl(fd, F_SETFL, mode|NONBLOCKING); for (;;) { #ifdef SOCKS - if (type == INET_SOCKS) { + if (socks) { status = Rconnect(fd, sockaddr, len); } else @@ -538,22 +553,15 @@ thread_connect(fd, sockaddr, len, type) } if (status < 0) { switch (errno) { -#ifdef EAGAIN case EAGAIN: #ifdef EINPROGRESS case EINPROGRESS: #endif - rb_thread_fd_writable(fd); + thread_write_select(fd); continue; -#endif #ifdef EISCONN case EISCONN: -#endif -#ifdef EALREADY - case EALREADY: -#endif -#if defined(EISCONN) || defined(EALREADY) status = 0; errno = 0; break; @@ -565,6 +573,29 @@ thread_connect(fd, sockaddr, len, type) return status; } } + +#else + +#ifdef SOCKS +static int +ruby_connect(fd, sockaddr, len, socks) + int fd; + struct sockaddr *sockaddr; + int len; + int socks; +{ + if (socks) { + return Rconnect(fd, sockaddr, len); + } + else { + return connect(fd, sockaddr, len); + } +} +#else + +#define ruby_connect(fd, sockaddr, len, socks) connect(fd, sockaddr, len) + +#endif /* SOCKS */ #endif static VALUE @@ -595,7 +626,7 @@ open_inet(class, h, serv, type) strcpy(pbuf, STR2CSTR(serv)); portp = pbuf; } - memset(&hints, 0, sizeof(hints)); + MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (type == INET_SERVER) { @@ -603,7 +634,7 @@ open_inet(class, h, serv, type) } error = getaddrinfo(host, portp, &hints, &res0); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } fd = -1; @@ -621,19 +652,8 @@ open_inet(class, h, serv, type) syscall = "bind(2)"; } else { -#if defined(HAVE_FCNTL) - status = thread_connect(fd, res->ai_addr, res->ai_addrlen, type); -#else -#ifdef SOCKS - if (type == INET_SOCKS) { - status = Rconnect(fd, res->ai_addr, res->ai_addrlen); - } - else -#endif - { - status = connect(fd, res->ai_addr, res->ai_addrlen); - } -#endif + status = ruby_connect(fd, res->ai_addr, res->ai_addrlen, + (type == INET_SOCKS)); syscall = "connect(2)"; } @@ -698,10 +718,10 @@ tcp_s_gethostbyname(obj, host) VALUE ary, names; if (rb_obj_is_kind_of(host, rb_cInteger)) { - int i = NUM2INT(host); + long i = NUM2LONG(host); struct sockaddr_in *sin; sin = (struct sockaddr_in *)&addr; - memset(sin, 0, sizeof(*sin)); + MEMZERO(sin, struct sockaddr_in, 1); sin->sin_family = AF_INET; SET_SIN_LEN(sin, sizeof(*sin)); sin->sin_addr.s_addr = htonl(i); @@ -737,7 +757,7 @@ tcp_s_gethostbyname(obj, host) if (h == NULL) { #ifdef HAVE_HSTERROR extern int h_errno; - rb_raise(rb_eSocket, (char *)hsterror(h_errno)); + rb_raise(rb_eSocket, "%s", (char *)hsterror(h_errno)); #else rb_raise(rb_eSocket, "host not found"); #endif @@ -756,7 +776,7 @@ tcp_s_gethostbyname(obj, host) case AF_INET: { struct sockaddr_in sin; - memset(&sin, 0, sizeof(sin)); + MEMZERO(&sin, struct sockaddr_in, 1); sin.sin_family = AF_INET; SET_SIN_LEN(&sin, sizeof(sin)); memcpy((char *) &sin.sin_addr, *pch, h->h_length); @@ -770,7 +790,7 @@ tcp_s_gethostbyname(obj, host) case AF_INET6: { struct sockaddr_in6 sin6; - memset(&sin6, 0, sizeof(sin6)); + MEMZERO(&sin6, struct sockaddr_in6, 1); sin6.sin6_family = AF_INET; sin6.sin6_len = sizeof(sin6); memcpy((char *) &sin6.sin6_addr, *pch, h->h_length); @@ -824,11 +844,14 @@ s_accept(class, fd, sockaddr, len) if (fd2 < 0) { switch (errno) { case EINTR: + rb_thread_schedule(); + goto retry; + case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - rb_thread_schedule(); + rb_thread_wait_fd(fd); goto retry; } rb_sys_fail(0); @@ -875,7 +898,7 @@ open_unix(class, path, server) fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) rb_sys_fail("socket(2)"); - memset(&sockaddr, 0, sizeof(sockaddr)); + MEMZERO(&sockaddr, struct sockaddr_un, 1); sockaddr.sun_family = AF_UNIX; strncpy(sockaddr.sun_path, path->ptr, sizeof(sockaddr.sun_path)-1); sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0'; @@ -884,7 +907,7 @@ open_unix(class, path, server) status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); } else { - status = connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); + status = ruby_connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr), 0); } if (status < 0) { @@ -939,10 +962,10 @@ ip_s_getaddress(obj, host) struct sockaddr addr; if (rb_obj_is_kind_of(host, rb_cInteger)) { - int i = NUM2INT(host); + long i = NUM2LONG(host); struct sockaddr_in *sin; sin = (struct sockaddr_in *)&addr; - memset(sin, 0, sizeof(*sin)); + MEMZERO(sin, struct sockaddr_in, 1); sin->sin_family = AF_INET; SET_SIN_LEN(sin, sizeof(*sin)); sin->sin_addr.s_addr = htonl(i); @@ -961,18 +984,12 @@ udp_s_open(argc, argv, class) VALUE class; { VALUE arg; + int socktype = AF_INET; if (rb_scan_args(argc, argv, "01", &arg) == 1) { - if (rb_obj_is_kind_of(arg, rb_cInteger)) { - return sock_new(class, socket(NUM2INT(arg), SOCK_DGRAM, 0)); - } - else { - rb_raise(rb_eSocket, "argument must be Integer"); - } - } - else { - return sock_new(class, socket(AF_INET, SOCK_DGRAM, 0)); + socktype = NUM2INT(arg); } + return sock_new(class, socket(socktype, SOCK_DGRAM, 0)); } static struct addrinfo * @@ -990,15 +1007,15 @@ udp_addrsetup(fptr, host, port) } else if (rb_obj_is_kind_of(host, rb_cInteger)) { struct sockaddr_in sin; - int i = NUM2INT(host); - memset(&sin, 0, sizeof(sin)); + long i = NUM2LONG(host); + MEMZERO(&sin, struct sockaddr_in, 1); sin.sin_family = AF_INET; SET_SIN_LEN(&sin, sizeof(sin)); sin.sin_addr.s_addr = htonl(i); error = getnameinfo((struct sockaddr *)&sin, SIN_LEN(&sin), hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } hostp = hbuf; } @@ -1014,12 +1031,12 @@ udp_addrsetup(fptr, host, port) portp = STR2CSTR(port); } - memset(&hints, 0, sizeof(hints)); + MEMZERO(&hints, struct addrinfo, 1); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; error = getaddrinfo(hostp, portp, &hints, &res); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } return res; @@ -1030,23 +1047,28 @@ udp_connect(sock, host, port) VALUE sock, host, port; { OpenFile *fptr; + int fd; struct addrinfo *res0, *res; GetOpenFile(sock, fptr); + fd = fileno(fptr->f); res0 = udp_addrsetup(fptr, host, port); for (res = res0; res; res = res->ai_next) { retry: - if (connect(fileno(fptr->f), res->ai_addr, res->ai_addrlen) >= 0) { + if (ruby_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) { freeaddrinfo(res0); return INT2FIX(0); } switch (errno) { case EINTR: + rb_thread_schedule(); + goto retry; + case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - rb_thread_schedule(); + thread_write_select(fd); goto retry; } } @@ -1111,11 +1133,14 @@ udp_send(argc, argv, sock) } switch (errno) { case EINTR: + rb_thread_schedule(); + goto retry; + case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - rb_thread_schedule(); + thread_write_select(fileno(f)); goto retry; } } @@ -1354,20 +1379,24 @@ sock_connect(sock, addr) VALUE sock, addr; { OpenFile *fptr; + int fd; Check_Type(addr, T_STRING); rb_str_modify(addr); GetOpenFile(sock, fptr); + fd = fileno(fptr->f); retry: - if (connect(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0) { + if (ruby_connect(fd, (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len, 0) < 0) { switch (errno) { case EINTR: + rb_thread_schedule(); + goto retry; case EWOULDBLOCK: #if EAGAIN != EWOULDBLOCK case EAGAIN: #endif - rb_thread_schedule(); + thread_write_select(fd); goto retry; } rb_sys_fail("connect(2)"); @@ -1476,7 +1505,7 @@ mkhostent(h) if (h == NULL) { #ifdef HAVE_HSTRERROR extern int h_errno; - rb_raise(rb_eSocket, (char *)hstrerror(h_errno)); + rb_raise(rb_eSocket, "%s", (char *)hstrerror(h_errno)); #else rb_raise(rb_eSocket, "host not found"); #endif @@ -1534,10 +1563,10 @@ sock_s_gethostbyname(obj, host) struct hostent *h; if (rb_obj_is_kind_of(host, rb_cInteger)) { - int i = NUM2INT(host); + long i = NUM2LONG(host); struct sockaddr_in *sin; sin = (struct sockaddr_in *)&addr; - memset(sin, 0, sizeof(*sin)); + MEMZERO(sin, struct sockaddr_in, 1); sin->sin_family = AF_INET; SET_SIN_LEN(sin, sizeof(*sin)); sin->sin_addr.s_addr = htonl(i); @@ -1642,7 +1671,7 @@ sock_s_getaddrinfo(argc, argv) host = port = family = socktype = protocol = flags = Qnil; rb_scan_args(argc, argv, "24", &host, &port, &family, &socktype, &protocol, - &flags); + &flags); if (NIL_P(host)) { hptr = NULL; } @@ -1654,7 +1683,7 @@ sock_s_getaddrinfo(argc, argv) if (NIL_P(port)) { pptr = NULL; } - else if (rb_obj_is_kind_of(port, rb_cInteger)) { + else if (FIXNUM_P(port)) { snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port)); pptr = pbuf; } @@ -1664,25 +1693,25 @@ sock_s_getaddrinfo(argc, argv) pptr = pbuf; } - memset(&hints, 0, sizeof(hints)); - if (!NIL_P(family) && rb_obj_is_kind_of(family, rb_cInteger)) { - hints.ai_family = FIX2INT(family); + MEMZERO(&hints, struct addrinfo, 1); + if (!NIL_P(family)) { + hints.ai_family = NUM2INT(family); } else { hints.ai_family = PF_UNSPEC; } - if (!NIL_P(socktype) && rb_obj_is_kind_of(socktype, rb_cInteger)) { - hints.ai_socktype = socktype; + if (!NIL_P(socktype)) { + hints.ai_socktype = NUM2INT(socktype); } - if (!NIL_P(protocol) && rb_obj_is_kind_of(protocol, rb_cInteger)) { - hints.ai_protocol = protocol; + if (!NIL_P(protocol)) { + hints.ai_protocol = NUM2INT(protocol); } - if (!NIL_P(flags) && rb_obj_is_kind_of(flags, rb_cInteger)) { - hints.ai_flags = flags; + if (!NIL_P(flags)) { + hints.ai_flags = NUM2INT(flags); } error = getaddrinfo(hptr, pptr, &hints, &res); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } ret = mkaddrinfo(res); @@ -1743,8 +1772,8 @@ sock_s_getnameinfo(argc, argv) strcpy(pbuf, "0"); pptr = NULL; } - else if (rb_obj_is_kind_of(port, rb_cInteger)) { - snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port)); + else if (!NIL_P(port)) { + snprintf(pbuf, sizeof(pbuf), "%d", NUM2INT(port)); pptr = pbuf; } else { @@ -1752,21 +1781,21 @@ sock_s_getnameinfo(argc, argv) pbuf[sizeof(pbuf) - 1] = '\0'; pptr = pbuf; } - memset(&hints, 0, sizeof(hints)); + MEMZERO(&hints, struct addrinfo, 1); if (strcmp(STR2CSTR(af), "AF_INET") == 0) { hints.ai_family = PF_INET; } - #ifdef INET6 +#ifdef INET6 else if (strcmp(STR2CSTR(af), "AF_INET6") == 0) { hints.ai_family = PF_INET6; } - #endif +#endif else { hints.ai_family = PF_UNSPEC; } error = getaddrinfo(hptr, pptr, &hints, &res); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } sap = res->ai_addr; } @@ -1775,15 +1804,15 @@ sock_s_getnameinfo(argc, argv) } fl = 0; - if (!NIL_P(flags) && rb_obj_is_kind_of(flags, rb_cInteger)) { - fl = FIX2INT(flags); + if (!NIL_P(flags)) { + fl = NUM2INT(flags); } -gotsap: + gotsap: error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), fl); if (error) { - rb_raise(rb_eSocket, gai_strerror(error)); + rb_raise(rb_eSocket, "%s", gai_strerror(error)); } if (res) freeaddrinfo(res); |