getaddrinfo
From:
ts <decoux@...>
Date:
2002-06-22 13:32:30 UTC
List:
ruby-core #184
I've had some free times to look at this.
Actually there are 3 cases :
1) ruby use its own (old ???) version of getaddrinfo
nasun% ./ruby -rsocket -ve 'p Socket.sockaddr_in(21, "moulon")'
ruby 1.7.2 (2002-06-04) [sparc-solaris2.8]
"\000\002\000\025\212fr\001\000\000\000\000\000\000\000\000"
nasun%
2) ruby use the system getaddrinfo
pigeon% ruby -rsocket -ve 'p Socket.sockaddr_in(21, "moulon")'
ruby 1.7.2 (2002-06-20) [i686-linux]
-e:1:in `sockaddr_in': getaddrinfo: Servname not supported for ai_socktype (SocketError)
from -e:1
pigeon%
Reasons are given in
http://www.wcug.wwu.edu/lists/ipng/200002/msg00134.html
http://www.wcug.wwu.edu/lists/ipng/200002/msg00119.html
3) ruby is compiled with --with-lookup-order-hack
pigeon% ruby -rsocket -ve 'p Socket.sockaddr_in(21, "moulon")'
ruby 1.7.2 (2002-06-20) [i686-linux]
-e:1: [BUG] Segmentation fault
ruby 1.7.2 (2002-06-20) [i686-linux]
Aborted
pigeon%
easy to understand why.
To make these 3 versions happy
pigeon% diff -u socket.c.old socket.c
--- socket.c.old Sat Jun 22 14:18:46 2002
+++ socket.c Sat Jun 22 14:41:33 2002
@@ -548,6 +548,22 @@
mkipaddr0((struct sockaddr*)&sin, buf, len);
}
+static int
+str_isnumber(p)
+ const char *p;
+{
+ char *ep;
+
+ if (!p || *p == '\0')
+ return 0;
+ ep = NULL;
+ (void)strtoul(p, &ep, 10);
+ if (ep && *ep == '\0')
+ return 1;
+ else
+ return 0;
+}
+
static struct addrinfo*
sock_addrinfo(host, port, socktype, flags)
VALUE host, port;
@@ -598,17 +614,16 @@
portp = RSTRING(port)->ptr;
}
- if (socktype == 0 && flags == 0) {
- hintsp = 0;
- }
- else {
- hintsp = &hints;
- MEMZERO(&hints, struct addrinfo, 1);
- hints.ai_family = PF_UNSPEC;
- hints.ai_protocol = 0;
- hints.ai_socktype = socktype;
- hints.ai_flags = flags;
+ if (socktype == 0 && flags == 0 && str_isnumber(portp)) {
+ socktype = SOCK_DGRAM;
}
+
+ hintsp = &hints;
+ MEMZERO(&hints, struct addrinfo, 1);
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_protocol = 0;
+ hints.ai_socktype = socktype;
+ hints.ai_flags = flags;
error = getaddrinfo(hostp, portp, hintsp, &res);
if (error) {
if (hostp && hostp[strlen(hostp)-1] == '\n') {
pigeon%
pigeon% ruby -rsocket -ve 'p Socket.sockaddr_in(21, "moulon")'
ruby 1.7.2 (2002-06-20) [i686-linux]
"\002\000\000\025\212fr\001\000\000\000\000\000\000\000\000"
pigeon%
Guy Decoux