Feature #1155
closedEtc.each_passwd, each_group
Description
=begin
なかだです。
Etc.each_passwdやEtc.each_groupというものを思いつきました。
また、別名としてEtc::Passwd.eachやEtc.::Group.eachも。
パスワードを設定していないユーザ名のリスト¶
Etc::Passwd.find_all {|u| u.passwd == ""}.map(&:name)
とか。
Index: ext/etc/etc.c¶
--- ext/etc/etc.c	(revision 22104)
+++ ext/etc/etc.c	(working copy)
@@ -187,4 +187,14 @@ passwd_iterate(void)
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
@@ -212,11 +222,7 @@ 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);
 }
 @@ -225,4 +231,32 @@ etc_passwd(VALUE obj)
 }
+/* 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.each_passwd {|u|
 
- 
- 
- 
puts u.name + " = " + u.gecos
 
- 
- 
- 
}
 
- 
- 
- 
- 
Etc.each_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.
 @@ -391,4 +425,14 @@ group_iterate(void)
 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
@@ -416,11 +460,7 @@ 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);
 }
 @@ -429,4 +469,32 @@ etc_group(VALUE obj)
 }
+/* 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.each_group {|g|
 
- 
- 
- 
puts g.name + ": " + g.mem.join(', ')
 
- 
- 
- 
}
 
- 
- 
- 
- 
Etc.each_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.
 @@ -505,8 +573,10 @@ Init_etc(void)
 rb_define_module_function(mEtc, "getpwent", etc_getpwent, 0);
 rb_define_module_function(mEtc, "passwd", etc_passwd, 0);
- 
rb_define_module_function(mEtc, "each_passwd", etc_each_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, "each_group", etc_each_group, 0); 
 rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0);
 rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
 @@ -539,4 +609,6 @@ Init_etc(void)
 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
@@ -548,4 +620,6 @@ Init_etc(void)
  rb_define_const(mEtc, "Group", sGroup);
- rb_extend_object(sGroup, rb_mEnumerable);
- rb_define_singleton_method(sGroup, "each", etc_each_group, 0);
 #endif
 }
 
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦
=end
        
           Updated by matz (Yukihiro Matsumoto) over 16 years ago
          Updated by matz (Yukihiro Matsumoto) over 16 years ago
          
          
        
        
      
      =begin
まつもと ゆきひろです
In message "Re: [ruby-dev:37999] [Feature:1.9] Etc.each_passwd, each_group"
on Fri, 13 Feb 2009 22:30:01 +0900, Nobuyoshi Nakada nobu@ruby-lang.org writes:
|Etc.each_passwdやEtc.each_groupというものを思いつきました。
互換性を気にしなければ、Etc.passwdがeach_passwdとして動作す
べきではないかと感じました。
|また、別名としてEtc::Passwd.eachやEtc.::Group.eachも。
|
|  # パスワードを設定していないユーザ名のリスト
|  Etc::Passwd.find_all {|u| u.passwd == ""}.map(&:name)
|
|とか。
こっちは賛成します。
=end
        
           Updated by nobu (Nobuyoshi Nakada) over 16 years ago
          Updated by nobu (Nobuyoshi Nakada) over 16 years ago
          
          
        
        
      
      - Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r22377.
=end