summaryrefslogtreecommitdiff
path: root/ext/etc
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-17 15:55:49 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-17 15:55:49 +0000
commit47d55a02a332633a75847d819cab3241f7060289 (patch)
treee8c2c0d712cdeb26cec78443189b165fa056f00a /ext/etc
parent28cf7a6d6f105b500fd2e83291fbecc9dac2473d (diff)
* 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
Diffstat (limited to 'ext/etc')
-rw-r--r--ext/etc/etc.c96
1 files changed, 84 insertions, 12 deletions
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index cb850f6..d0d28c0 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
}