* 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
This commit is contained in:
matz 2003-10-01 13:41:35 +00:00
Родитель cbb7a67c32
Коммит 969f4d4c68
7 изменённых файлов: 277 добавлений и 271 удалений

Просмотреть файл

@ -9,6 +9,13 @@ Wed Oct 1 20:36:49 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* MANIFEST: add wince/mkconfig_wce.rb.
Wed Oct 1 17:22:33 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <nobu@ruby-lang.org>
* eval.c (rb_load): Object scope had priority over required file
@ -32,6 +39,11 @@ Wed Oct 01 08:02:52 2003 Takaaki Uematsu <uema2x@jcom.home.ne.jp>
* wince/time_wce.c (time): add zero check.
Tue Sep 30 16:11:05 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* 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 <akr@m17n.org>
* process.c (pst_inspect): describe stopped process "stopped".

Просмотреть файл

@ -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) $<

4
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;

Просмотреть файл

@ -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",

Просмотреть файл

@ -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

Просмотреть файл

@ -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, "<any>") == 0)) {
make_inetaddr(INADDR_ANY, hbuf, len);
}
else if (name[0] == '<' && strcmp(name, "<broadcast>") == 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, "<any>") == 0)) {
mkinetaddr(INADDR_ANY, hbuf, sizeof(hbuf));
}
else if (name[0] == '<' && strcmp(name, "<broadcast>") == 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);
}

Просмотреть файл

@ -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 */