From 969f4d4c68ecb9dd03bfc1fa8b12c19ea08046fe Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 1 Oct 2003 13:41:35 +0000 Subject: [PATCH] * ext/etc/etc.c: add new functions: setpwent, getpwent, endpwent, setgrent, getgrent, endgrent. * ext/socket/socket.c (sock_s_gethostbyname): do not reverse lookup. * Makefile.in: copy lex.c from $(srcdir) if it's not the current directory. [ruby-dev:21437] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4640 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 ++ Makefile.in | 6 +- eval.c | 4 +- ext/etc/etc.c | 78 +++++++- ext/socket/extconf.rb | 1 + ext/socket/socket.c | 445 +++++++++++++++++------------------------- intern.h | 2 +- 7 files changed, 277 insertions(+), 271 deletions(-) diff --git a/ChangeLog b/ChangeLog index f13ab7c4e9..df03ae4c6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,13 @@ Wed Oct 1 20:36:49 2003 WATANABE Hirofumi * MANIFEST: add wince/mkconfig_wce.rb. +Wed Oct 1 17:22:33 2003 Yukihiro Matsumoto + + * ext/etc/etc.c: add new functions: setpwent, getpwent, endpwent, + setgrent, getgrent, endgrent. + + * ext/socket/socket.c (sock_s_gethostbyname): do not reverse lookup. + Wed Oct 1 17:01:30 2003 Nobuyoshi Nakada * eval.c (rb_load): Object scope had priority over required file @@ -32,6 +39,11 @@ Wed Oct 01 08:02:52 2003 Takaaki Uematsu * wince/time_wce.c (time): add zero check. +Tue Sep 30 16:11:05 2003 Yukihiro Matsumoto + + * Makefile.in: copy lex.c from $(srcdir) if it's not the current + directory. [ruby-dev:21437] + Tue Sep 30 11:29:23 2003 Tanaka Akira * process.c (pst_inspect): describe stopped process "stopped". diff --git a/Makefile.in b/Makefile.in index f6a3cb6609..13de20321a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -218,7 +218,11 @@ $(srcdir)/configure: $(srcdir)/configure.in $(CC) $(CFLAGS) $(CPPFLAGS) -c $< lex.c: keywords - gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ $(srcdir)/keywords > lex.c + if test "$(srcdir)" = "."; then \ + gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ $> > $@; \ + else \ + cp $(srcdir)/lex.c .; \ + fi .y.c: $(YACC) $< diff --git a/eval.c b/eval.c index d8162916ba..622bbeff65 100644 --- a/eval.c +++ b/eval.c @@ -9752,7 +9752,7 @@ static VALUE rb_thread_raise(argc, argv, th) int argc; VALUE *argv; - rb_thread_t th; + volatile rb_thread_t th; { if (rb_thread_dead(th)) return Qnil; if (curr_thread == th) { @@ -9924,7 +9924,7 @@ rb_callcc(self) VALUE self; { volatile VALUE cont; - rb_thread_t th; + volatile rb_thread_t th; struct tag *tag; struct RVarmap *vars; diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 51668c400f..3d4052e27b 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -175,6 +175,40 @@ etc_passwd(obj) return Qnil; } +static VALUE +etc_setpwent(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + setpwent(); +#endif + return Qnil; +} + +static VALUE +etc_endpwent(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + endpwent(); +#endif + return Qnil; +} + +static VALUE +etc_getpwent(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + struct passwd *pw; + + if (pw = getpwent()) { + return setup_passwd(pw); + } +#endif + return Qnil; +} + #ifdef HAVE_GETGRENT static VALUE setup_group(grp) @@ -246,11 +280,11 @@ group_iterate() { struct group *pw; - setpwent(); + setgrent(); while (pw = getgrent()) { rb_yield(setup_group(pw)); } - endpwent(); + endgrent(); return Qnil; } #endif @@ -277,6 +311,40 @@ etc_group(obj) return Qnil; } +static VALUE +etc_setgrent(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + setgrent(); +#endif + return Qnil; +} + +static VALUE +etc_endgrent(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + endgrent(); +#endif + return Qnil; +} + +static VALUE +etc_getgrent(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + struct group *gr; + + if (gr = getgrent()) { + return setup_passwd(gr); + } +#endif + return Qnil; +} + static VALUE mEtc; void @@ -288,11 +356,17 @@ Init_etc() rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1); rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1); + rb_define_module_function(mEtc, "setpwent", etc_setpwent, 0); + rb_define_module_function(mEtc, "endpwent", etc_endpwent, 0); + rb_define_module_function(mEtc, "getpwent", etc_getpwent, 0); rb_define_module_function(mEtc, "passwd", etc_passwd, 0); rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, 1); rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1); rb_define_module_function(mEtc, "group", etc_group, 0); + rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0); + rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0); + rb_define_module_function(mEtc, "getgrent", etc_g,etgrent, 0); sPasswd = rb_struct_define("Passwd", "name", "passwd", "uid", "gid", diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index e888b2a197..234f373170 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -385,6 +385,7 @@ have_header("sys/uio.h") if have_func(test_func) have_func("hsterror") + have_func("getipnodebyname") or have_func("gethostbyname2") unless have_func("gethostname") have_func("uname") end diff --git a/ext/socket/socket.c b/ext/socket/socket.c index ca2528f549..ca7bdc50c2 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -492,7 +492,7 @@ bsock_do_not_rev_lookup_set(self, val) } static void -mkipaddr0(addr, buf, len) +make_ipaddr0(addr, buf, len) struct sockaddr *addr; char *buf; size_t len; @@ -506,17 +506,17 @@ mkipaddr0(addr, buf, len) } static VALUE -mkipaddr(addr) +make_ipaddr(addr) struct sockaddr *addr; { char buf[1024]; - mkipaddr0(addr, buf, sizeof(buf)); + make_ipaddr0(addr, buf, sizeof(buf)); return rb_str_new2(buf); } static void -mkinetaddr(host, buf, len) +make_inetaddr(host, buf, len) long host; char *buf; size_t len; @@ -527,7 +527,7 @@ mkinetaddr(host, buf, len) sin.sin_family = AF_INET; SET_SIN_LEN(&sin, sizeof(sin)); sin.sin_addr.s_addr = host; - mkipaddr0((struct sockaddr*)&sin, buf, len); + make_ipaddr0((struct sockaddr*)&sin, buf, len); } static int @@ -546,6 +546,75 @@ str_isnumber(p) return 0; } +static char * +host_str(host, hbuf, len) + VALUE host; + char *hbuf; + size_t len; +{ + if (NIL_P(host)) { + return NULL; + } + else if (rb_obj_is_kind_of(host, rb_cInteger)) { + long i = NUM2LONG(host); + + make_inetaddr(htonl(i), hbuf, len); + return hbuf; + } + else { + char *name; + + SafeStringValue(host); + name = RSTRING(host)->ptr; + if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "") == 0)) { + make_inetaddr(INADDR_ANY, hbuf, len); + } + else if (name[0] == '<' && strcmp(name, "") == 0) { + make_inetaddr(INADDR_BROADCAST, hbuf, len); + } + else if (strlen(name) >= len) { + rb_raise(rb_eArgError, "hostname too long (%d)", strlen(name)); + } + else { + strcpy(hbuf, name); + } + return hbuf; + } +} + +static char * +port_str(port, pbuf, len) + VALUE port; + char *pbuf; + size_t len; +{ + if (NIL_P(port)) { + return 0; + } + else if (FIXNUM_P(port)) { + snprintf(pbuf, len, "%d", FIX2INT(port)); + return pbuf; + } + else { + char *serv; + + SafeStringValue(port); + serv = RSTRING(port)->ptr; + if (strlen(serv) >= len) { + rb_raise(rb_eArgError, "service name too long (%d)", strlen(serv)); + } + strcpy(pbuf, serv); + return pbuf; + } +} + +#ifndef NI_MAXHOST +# define 1025 +#endif +#ifndef NI_MAXSERV +# define 32 +#endif + static struct addrinfo* sock_addrinfo(host, port, socktype, flags) VALUE host, port; @@ -554,47 +623,10 @@ sock_addrinfo(host, port, socktype, flags) struct addrinfo hints, *hintsp, *res; char *hostp, *portp; int error; - char hbuf[1024], pbuf[32]; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; - if (NIL_P(host)) { - hostp = NULL; - } - else if (rb_obj_is_kind_of(host, rb_cInteger)) { - long i = NUM2LONG(host); - - mkinetaddr(htonl(i), hbuf, sizeof(hbuf)); - hostp = hbuf; - } - else { - char *name; - - SafeStringValue(host); - name = RSTRING(host)->ptr; - if (!name || *name == 0 || (name[0] == '<' && strcmp(name, "") == 0)) { - mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf)); - } - else if (name[0] == '<' && strcmp(name, "") == 0) { - mkinetaddr(INADDR_BROADCAST, hbuf, sizeof(hbuf)); - } - else if (strlen(name) >= sizeof(hbuf)) { - rb_raise(rb_eArgError, "hostname too long (%d)", strlen(name)); - } - else { - strcpy(hbuf, name); - } - hostp = hbuf; - } - if (NIL_P(port)) { - portp = 0; - } - else if (FIXNUM_P(port)) { - snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port)); - portp = pbuf; - } - else { - SafeStringValue(port); - portp = RSTRING(port)->ptr; - } + hostp = host_str(host, hbuf, sizeof(hbuf)); + portp = port_str(port, pbuf, sizeof(pbuf)); if (socktype == 0 && flags == 0 && str_isnumber(portp)) { socktype = SOCK_DGRAM; @@ -617,18 +649,6 @@ sock_addrinfo(host, port, socktype, flags) return res; } -static void -setipaddr(name, addr) - VALUE name; - struct sockaddr_storage *addr; -{ - struct addrinfo *res = sock_addrinfo(name, Qnil, SOCK_STREAM, 0); - - /* just take the first one */ - memcpy(addr, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); -} - static VALUE ipaddr(sockaddr) struct sockaddr *sockaddr; @@ -703,17 +723,6 @@ ruby_socket(domain, type, proto) return fd; } -static void -thread_read_select(fd) - int fd; -{ - fd_set fds; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - rb_thread_select(fd+1, &fds, 0, 0, 0); -} - static void thread_write_select(fd) int fd; @@ -845,46 +854,6 @@ ruby_connect(fd, sockaddr, len, socks) } } -static void -load_addr_info(h, serv, type, res) - VALUE h, serv; - int type; - struct addrinfo **res; -{ - char *host; - char pbuf[1024], *portp; - struct addrinfo hints; - int error; - - if (!NIL_P(h)) { - SafeStringValue(h); - host = RSTRING(h)->ptr; - } - else { - host = NULL; - } - if (FIXNUM_P(serv)) { - snprintf(pbuf, sizeof(pbuf), "%u", FIX2UINT(serv)); - portp = pbuf; - } - else { - SafeStringValue(serv); - if (RSTRING(serv)->len >= sizeof(pbuf)) - rb_raise(rb_eArgError, "servicename too long (%ld)", RSTRING(serv)->len); - strcpy(pbuf, RSTRING(serv)->ptr); - portp = pbuf; - } - MEMZERO(&hints, struct addrinfo, 1); - hints.ai_family = PF_UNSPEC; - if (type == INET_SERVER) { - hints.ai_flags = AI_PASSIVE; - } - error = getaddrinfo(host, portp, &hints, res); - if (error) { - rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error)); - } -} - struct inetsock_arg { VALUE sock; @@ -1052,110 +1021,59 @@ socks_s_close(sock) #endif #endif -/* - * NOTE: using gethostbyname() against AF_INET6 is a bad idea, as it - * does not initialize sin_flowinfo nor sin_scope_id properly. - */ - -struct hostent* -sock_hostbyname(host) - VALUE host; +static VALUE +make_hostent(addr, ipaddr) + struct addrinfo *addr; + VALUE (*ipaddr) _((struct sockaddr*, size_t)); { - struct sockaddr_storage addr; + struct addrinfo *ai; struct hostent *h; + VALUE ary, names; + char **pch; - rb_secure(3); - setipaddr(host, &addr); - switch (addr.ss_family) { - case AF_INET: - { - struct sockaddr_in *sin; - sin = (struct sockaddr_in*)&addr; - h = gethostbyaddr((char*)&sin->sin_addr, - sizeof(sin->sin_addr), - sin->sin_family); - break; - } -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 *sin6; - sin6 = (struct sockaddr_in6*)&addr; - h = gethostbyaddr((char*)&sin6->sin6_addr, - sizeof(sin6->sin6_addr), - sin6->sin6_family); - break; - } -#endif - default: - h = NULL; - break; + ary = rb_ary_new(); + rb_ary_push(ary, rb_str_new2(addr->ai_canonname)); + names = rb_ary_new(); + rb_ary_push(ary, names); +#if defined(HAVE_GETIPNODEBYNAME) + { + int error; + + h = getipnodebyname(addr->ai_canonname, addr->ai_family, AI_ALL, &error); } - - if (h == NULL) { -#ifdef HAVE_HSTERROR - extern int h_errno; - rb_raise(rb_eSocket, "%s", (char*)hsterror(h_errno)); +#elif defined(HAVE_GETHOSTBYNAME2) + h = gethostbyname2(addr->ai_canonname, addr->ai_family); #else - rb_raise(rb_eSocket, "host not found"); + h = gethostbyname(addr->ai_canonname); #endif + for (pch = h->h_aliases; *pch; pch++) { + rb_ary_push(names, rb_str_new2(*pch)); } - return h; +#if defined(HAVE_GETIPNODEBYNAME) + freehostent(h); +#endif + rb_ary_push(ary, INT2NUM(addr->ai_family)); + for (ai = addr; ai; ai = ai->ai_next) { + rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen)); + } + + return ary; +} + +VALUE +tcp_sockaddr(addr, len) + struct sockaddr *addr; + size_t len; +{ + return make_ipaddr(addr); } static VALUE tcp_s_gethostbyname(obj, host) VALUE obj, host; { - struct hostent *h = sock_hostbyname(host); - VALUE ary, names; - char **pch; - - ary = rb_ary_new(); - rb_ary_push(ary, rb_str_new2(h->h_name)); - names = rb_ary_new(); - rb_ary_push(ary, names); - for (pch = h->h_aliases; *pch; pch++) { - rb_ary_push(names, rb_str_new2(*pch)); - } - rb_ary_push(ary, INT2NUM(h->h_addrtype)); -#ifdef h_addr - for (pch = h->h_addr_list; *pch; pch++) { - switch (h->h_length) { - case 4: /* AF_INET */ { - struct sockaddr_in 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); - rb_ary_push(ary, mkipaddr((struct sockaddr*)&sin)); - break; - } -#ifdef INET6 - case 8: /* AF_INET6 */ { - struct sockaddr_in6 sin6; - - MEMZERO(&sin6, struct sockaddr_in6, 1); - sin6.sin6_family = AF_INET6; -#ifdef SIN6_LEN - sin6.sin6_len = sizeof(sin6); -#endif - memcpy((char*)&sin6.sin6_addr, *pch, h->h_length); - rb_ary_push(ary, mkipaddr((struct sockaddr*)&sin6)); - break; - } -#endif - default: - break; - } - } -#else - memcpy((char*)&addr.sin_addr, h->h_addr, h->h_length); - rb_ary_push(ary, mkipaddr((struct sockaddr*)&addr)); -#endif - - return ary; + rb_secure(3); + return make_hostent(sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), tcp_sockaddr); } static VALUE @@ -1347,9 +1265,13 @@ ip_s_getaddress(obj, host) VALUE obj, host; { struct sockaddr_storage addr; + struct addrinfo *res = sock_addrinfo(host, Qnil, SOCK_STREAM, 0); - setipaddr(host, &addr); - return mkipaddr((struct sockaddr*)&addr); + /* just take the first one */ + memcpy(&addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + + return make_ipaddr((struct sockaddr*)&addr); } static VALUE @@ -1499,13 +1421,6 @@ unix_path(sock) return rb_str_new2(fptr->path); } -static VALUE -unix_svr_s_open(klass, path) - VALUE klass, path; -{ - return init_unixsock(rb_obj_alloc(klass), path, 1); -} - static VALUE unix_svr_init(sock, path) VALUE sock, path; @@ -2023,12 +1938,65 @@ sock_gethostname(obj) #endif static VALUE -sock_mkhostent(h) - struct hostent *h; +make_addrinfo(res0) + struct addrinfo *res0; { + VALUE base, ary; + struct addrinfo *res; + + if (res0 == NULL) { + rb_raise(rb_eSocket, "host not found"); + } + base = rb_ary_new(); + for (res = res0; res; res = res->ai_next) { + 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)); + rb_ary_push(base, ary); + } + return base; +} + +VALUE +sock_sockaddr(addr, len) + struct sockaddr *addr; + size_t len; +{ + return rb_str_new((char*)addr, len); +} + +static VALUE +sock_s_gethostbyname(obj, host) + VALUE obj, host; +{ + rb_secure(3); + return make_hostent(sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr); +} + +static VALUE +sock_s_gethostbyaddr(argc, argv) + int argc; + VALUE *argv; +{ + VALUE addr, type; + struct hostent *h; + struct sockaddr *sa; char **pch; VALUE ary, names; + int t = AF_INET; + rb_scan_args(argc, argv, "11", &addr, &type); + sa = (struct sockaddr*)StringValuePtr(addr); + if (!NIL_P(type)) { + t = NUM2INT(type); + } +#ifdef INET6 + else if (RSTRING(addr)->len == 16) { + t = AF_INET6; + } +#endif + h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, t); if (h == NULL) { #ifdef HAVE_HSTRERROR extern int h_errno; @@ -2056,59 +2024,6 @@ sock_mkhostent(h) return ary; } -static VALUE -mkaddrinfo(res0) - struct addrinfo *res0; -{ - VALUE base, ary; - struct addrinfo *res; - - if (res0 == NULL) { - rb_raise(rb_eSocket, "host not found"); - } - base = rb_ary_new(); - for (res = res0; res; res = res->ai_next) { - 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)); - rb_ary_push(base, ary); - } - return base; -} - -static VALUE -sock_s_gethostbyname(obj, host) - VALUE obj, host; -{ - return sock_mkhostent(sock_hostbyname(host)); -} - -static VALUE -sock_s_gethostbyaddr(argc, argv) - int argc; - VALUE *argv; -{ - VALUE addr, type; - struct hostent *h; - struct sockaddr *sa; - int t = AF_INET; - - rb_scan_args(argc, argv, "11", &addr, &type); - sa = (struct sockaddr*)StringValuePtr(addr); - if (!NIL_P(type)) { - t = NUM2INT(type); - } -#ifdef INET6 - else if (RSTRING(addr)->len == 16) { - t = AF_INET6; - } -#endif - h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, t); - - return sock_mkhostent(h); -} - static VALUE sock_s_getservbyaname(argc, argv) int argc; @@ -2206,7 +2121,7 @@ sock_s_getaddrinfo(argc, argv) rb_raise(rb_eSocket, "getaddrinfo: %s", gai_strerror(error)); } - ret = mkaddrinfo(res); + ret = make_addrinfo(res); freeaddrinfo(res); return ret; } @@ -2369,7 +2284,7 @@ sock_s_unpack_sockaddr_in(self, addr) VALUE host; sockaddr = (struct sockaddr_in*)StringValuePtr(addr); - host = mkipaddr((struct sockaddr*)sockaddr); + host = make_ipaddr((struct sockaddr*)sockaddr); OBJ_INFECT(host, addr); return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host); } diff --git a/intern.h b/intern.h index 93e6bb8d11..dacd985b74 100644 --- a/intern.h +++ b/intern.h @@ -374,7 +374,7 @@ void posix_signal _((int, RETSIGTYPE (*)(int))); #endif void rb_trap_exit _((void)); void rb_trap_exec _((void)); -char *ruby_signal_name _((int)); +const char *ruby_signal_name _((int)); /* sprintf.c */ VALUE rb_f_sprintf _((int, VALUE*)); /* string.c */