From 47d55a02a332633a75847d819cab3241f7060289 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 17 Feb 2009 15:55:49 +0000 Subject: * ext/etc/etc.c (Etc::Passwd.each, Etc::Group.each): new methods. [ruby-dev:37999] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22377 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 ++++ ext/etc/etc.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- version.h | 4 +-- 3 files changed, 91 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index c7d63ecc4c..27f272a3ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Feb 18 00:55:47 2009 Nobuyoshi Nakada + + * ext/etc/etc.c (Etc::Passwd.each, Etc::Group.each): new methods. + [ruby-dev:37999] + Tue Feb 17 23:25:01 2009 Tanaka Akira * ext/socket/ancdata.c (bsock_sendmsg_internal): make the padding diff --git a/ext/etc/etc.c b/ext/etc/etc.c index cb850f6987..d0d28c0d72 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -186,6 +186,16 @@ passwd_iterate(void) endpwent(); return Qnil; } + +static void +each_passwd(void) +{ + if (passwd_blocking) { + rb_raise(rb_eRuntimeError, "parallel passwd iteration"); + } + passwd_blocking = Qtrue; + rb_ensure(passwd_iterate, 0, passwd_ensure, 0); +} #endif /* Provides a convenient Ruby iterator which executes a block for each entry @@ -211,19 +221,43 @@ etc_passwd(VALUE obj) rb_secure(4); if (rb_block_given_p()) { - if (passwd_blocking) { - rb_raise(rb_eRuntimeError, "parallel passwd iteration"); - } - passwd_blocking = Qtrue; - rb_ensure(passwd_iterate, 0, passwd_ensure, 0); + each_passwd(); } - if (pw = getpwent()) { + else if (pw = getpwent()) { return setup_passwd(pw); } #endif return Qnil; } +/* Iterates for each entry in the /etc/passwd file if a block is given. + * If no block is given, returns the enumerator. + * + * The code block is passed an Struct::Passwd struct; see getpwent above for + * details. + * + * Example: + * + * require 'etc' + * + * Etc::Passwd.each {|u| + * puts u.name + " = " + u.gecos + * } + * + * Etc::Passwd.collect {|u| u.gecos} + * Etc::Passwd.collect {|u| u.gecos} + * + */ +static VALUE +etc_each_passwd(VALUE obj) +{ +#ifdef HAVE_GETPWENT + RETURN_ENUMERATOR(obj, 0, 0); + each_passwd(); +#endif + return obj; +} + /* Resets the process of reading the /etc/passwd file, so that the next call * to getpwent will return the first entry again. */ @@ -390,6 +424,16 @@ group_iterate(void) endgrent(); return Qnil; } + +static void +each_group(void) +{ + if (group_blocking) { + rb_raise(rb_eRuntimeError, "parallel group iteration"); + } + group_blocking = Qtrue; + rb_ensure(group_iterate, 0, group_ensure, 0); +} #endif /* Provides a convenient Ruby iterator which executes a block for each entry @@ -415,19 +459,43 @@ etc_group(VALUE obj) rb_secure(4); if (rb_block_given_p()) { - if (group_blocking) { - rb_raise(rb_eRuntimeError, "parallel group iteration"); - } - group_blocking = Qtrue; - rb_ensure(group_iterate, 0, group_ensure, 0); + each_group(); } - if (grp = getgrent()) { + else if (grp = getgrent()) { return setup_group(grp); } #endif return Qnil; } +/* Iterates for each entry in the /etc/group file if a block is given. + * If no block is given, returns the enumerator. + * + * The code block is passed an Struct::Group struct; see getpwent above for + * details. + * + * Example: + * + * require 'etc' + * + * Etc::Group.each {|g| + * puts g.name + ": " + g.mem.join(', ') + * } + * + * Etc::Group.collect {|g| g.name} + * Etc::Group.select {|g| !g.mem.empty?} + * + */ +static VALUE +etc_each_group(VALUE obj) +{ +#ifdef HAVE_GETPWENT + RETURN_ENUMERATOR(obj, 0, 0); + each_group(); +#endif + return obj; +} + /* Resets the process of reading the /etc/group file, so that the next call * to getgrent will return the first entry again. */ @@ -538,6 +606,8 @@ Init_etc(void) #endif NULL); rb_define_const(mEtc, "Passwd", sPasswd); + rb_extend_object(sPasswd, rb_mEnumerable); + rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0); #ifdef HAVE_GETGRENT sGroup = rb_struct_define("Group", "name", @@ -547,5 +617,7 @@ Init_etc(void) "gid", "mem", NULL); rb_define_const(mEtc, "Group", sGroup); + rb_extend_object(sGroup, rb_mEnumerable); + rb_define_singleton_method(sGroup, "each", etc_each_group, 0); #endif } diff --git a/version.h b/version.h index 10736b756e..a6d7e0f3fe 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #define RUBY_VERSION "1.9.2" -#define RUBY_RELEASE_DATE "2009-02-17" +#define RUBY_RELEASE_DATE "2009-02-18" #define RUBY_PATCHLEVEL -1 #define RUBY_BRANCH_NAME "trunk" @@ -8,7 +8,7 @@ #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_YEAR 2009 #define RUBY_RELEASE_MONTH 2 -#define RUBY_RELEASE_DAY 17 +#define RUBY_RELEASE_DAY 18 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; -- cgit v1.2.3