ext/etc/etc.c in etc-1.1.0 vs ext/etc/etc.c in etc-1.2.0
- old
+ new
@@ -50,14 +50,38 @@
#ifndef _WIN32
char *getenv();
#endif
char *getlogin();
-#define RUBY_ETC_VERSION "1.1.0"
+#define RUBY_ETC_VERSION "1.2.0"
+#ifdef HAVE_RB_DEPRECATE_CONSTANT
+void rb_deprecate_constant(VALUE mod, const char *name);
+#else
+# define rb_deprecate_constant(mod,name) ((void)(mod),(void)(name))
+#endif
+
#include "constdefs.h"
+#ifdef HAVE_RB_EXT_RACTOR_SAFE
+#include "ruby/thread_native.h"
+#else
+/* Implement rb_native_mutex_x using an int */
+typedef int rb_nativethread_lock_t;
+static int rb_native_mutex_trylock(int *mutex) {
+ if (*mutex) {
+ return 1;
+ }
+ *mutex = 1;
+ return 0;
+}
+static void rb_native_mutex_unlock(int *mutex) {
+ *mutex = 0;
+}
+#define rb_native_mutex_initialize rb_native_mutex_unlock
+#endif
+
/* call-seq:
* getlogin -> String
*
* Returns the short user name of the currently logged in user.
* Unfortunately, it is often rather easy to fool ::getlogin.
@@ -117,10 +141,16 @@
return rb_filesystem_str_new_cstr(str);
}
#endif
#ifdef HAVE_GETPWENT
+# ifdef __APPLE__
+# define PW_TIME2VAL(t) INT2NUM((int)(t))
+# else
+# define PW_TIME2VAL(t) TIMET2NUM(t)
+# endif
+
static VALUE
setup_passwd(struct passwd *pwd)
{
if (pwd == 0) rb_sys_fail("/etc/passwd");
return rb_struct_new(sPasswd,
@@ -134,11 +164,11 @@
safe_setup_locale_str(pwd->pw_gecos),
#endif
safe_setup_filesystem_str(pwd->pw_dir),
safe_setup_filesystem_str(pwd->pw_shell),
#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
- INT2NUM(pwd->pw_change),
+ PW_TIME2VAL(pwd->pw_change),
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_QUOTA
INT2NUM(pwd->pw_quota),
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_AGE
@@ -149,11 +179,11 @@
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_COMMENT
safe_setup_locale_str(pwd->pw_comment),
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
- INT2NUM(pwd->pw_expire),
+ PW_TIME2VAL(pwd->pw_expire),
#endif
0 /*dummy*/
);
}
#endif
@@ -226,16 +256,16 @@
return Qnil;
#endif
}
#ifdef HAVE_GETPWENT
-static int passwd_blocking = 0;
+static rb_nativethread_lock_t passwd_blocking;
static VALUE
passwd_ensure(VALUE _)
{
endpwent();
- passwd_blocking = (int)Qfalse;
+ rb_native_mutex_unlock(&passwd_blocking);
return Qnil;
}
static VALUE
passwd_iterate(VALUE _)
@@ -250,14 +280,13 @@
}
static void
each_passwd(void)
{
- if (passwd_blocking) {
+ if (rb_native_mutex_trylock(&passwd_blocking)) {
rb_raise(rb_eRuntimeError, "parallel passwd iteration");
}
- passwd_blocking = (int)Qtrue;
rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
}
#endif
/* call-seq:
@@ -469,16 +498,16 @@
return Qnil;
#endif
}
#ifdef HAVE_GETGRENT
-static int group_blocking = 0;
+static rb_nativethread_lock_t group_blocking;
static VALUE
group_ensure(VALUE _)
{
endgrent();
- group_blocking = (int)Qfalse;
+ rb_native_mutex_unlock(&group_blocking);
return Qnil;
}
static VALUE
@@ -494,14 +523,13 @@
}
static void
each_group(void)
{
- if (group_blocking) {
+ if (rb_native_mutex_trylock(&group_blocking)) {
rb_raise(rb_eRuntimeError, "parallel group iteration");
}
- group_blocking = (int)Qtrue;
rb_ensure(group_iterate, 0, group_ensure, 0);
}
#endif
/* Provides a convenient Ruby iterator which executes a block for each entry
@@ -1062,10 +1090,13 @@
void
Init_etc(void)
{
VALUE mEtc;
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
+ RB_EXT_RACTOR_SAFE(true);
+ #endif
mEtc = rb_define_module("Etc");
rb_define_const(mEtc, "VERSION", rb_str_new_cstr(RUBY_ETC_VERSION));
init_constants(mEtc);
rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
@@ -1163,14 +1194,18 @@
* account expiration time(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_EXPIRE+
*/
rb_define_const(mEtc, "Passwd", sPasswd);
#endif
rb_define_const(rb_cStruct, "Passwd", sPasswd); /* deprecated name */
+ rb_deprecate_constant(rb_cStruct, "Passwd");
rb_extend_object(sPasswd, rb_mEnumerable);
rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0);
-
+#ifdef HAVE_GETPWENT
+ rb_native_mutex_initialize(&passwd_blocking);
+#endif
#ifdef HAVE_GETGRENT
+ rb_native_mutex_initialize(&group_blocking);
sGroup = rb_struct_define_under(mEtc, "Group", "name",
#ifdef HAVE_STRUCT_GROUP_GR_PASSWD
"passwd",
#endif
"gid", "mem", NULL);
@@ -1198,9 +1233,10 @@
* members of the group.
*/
rb_define_const(mEtc, "Group", sGroup);
#endif
rb_define_const(rb_cStruct, "Group", sGroup); /* deprecated name */
+ rb_deprecate_constant(rb_cStruct, "Group");
rb_extend_object(sGroup, rb_mEnumerable);
rb_define_singleton_method(sGroup, "each", etc_each_group, 0);
#endif
}