Project

General

Profile

Actions

Feature #1155

closed

Etc.each_passwd, each_group

Added by nobu (Nobuyoshi Nakada) about 16 years ago. Updated about 14 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-dev:37999]

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

Actions #1

Updated by matz (Yukihiro Matsumoto) about 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 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

Actions #2

Updated by nobu (Nobuyoshi Nakada) about 16 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r22377.
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0