diff options
Diffstat (limited to 'ext/etc')
-rw-r--r-- | ext/etc/.document | 2 | ||||
-rw-r--r-- | ext/etc/depend | 5 | ||||
-rw-r--r-- | ext/etc/etc.c | 216 | ||||
-rw-r--r-- | ext/etc/extconf.rb | 14 | ||||
-rw-r--r-- | ext/etc/mkconstants.rb | 32 |
5 files changed, 175 insertions, 94 deletions
diff --git a/ext/etc/.document b/ext/etc/.document new file mode 100644 index 0000000000..9bbea23b92 --- /dev/null +++ b/ext/etc/.document @@ -0,0 +1,2 @@ +etc.c +constdefs.h diff --git a/ext/etc/depend b/ext/etc/depend index 9c2de2ba96..675699b129 100644 --- a/ext/etc/depend +++ b/ext/etc/depend @@ -20,6 +20,7 @@ etc.o: $(hdrdir)/ruby/backward/2/stdarg.h etc.o: $(hdrdir)/ruby/defines.h etc.o: $(hdrdir)/ruby/encoding.h etc.o: $(hdrdir)/ruby/intern.h +etc.o: $(hdrdir)/ruby/internal/abi.h etc.o: $(hdrdir)/ruby/internal/anyargs.h etc.o: $(hdrdir)/ruby/internal/arithmetic.h etc.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -57,6 +58,7 @@ etc.o: $(hdrdir)/ruby/internal/attr/noexcept.h etc.o: $(hdrdir)/ruby/internal/attr/noinline.h etc.o: $(hdrdir)/ruby/internal/attr/nonnull.h etc.o: $(hdrdir)/ruby/internal/attr/noreturn.h +etc.o: $(hdrdir)/ruby/internal/attr/packed_struct.h etc.o: $(hdrdir)/ruby/internal/attr/pure.h etc.o: $(hdrdir)/ruby/internal/attr/restrict.h etc.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -125,7 +127,6 @@ etc.o: $(hdrdir)/ruby/internal/intern/enumerator.h etc.o: $(hdrdir)/ruby/internal/intern/error.h etc.o: $(hdrdir)/ruby/internal/intern/eval.h etc.o: $(hdrdir)/ruby/internal/intern/file.h -etc.o: $(hdrdir)/ruby/internal/intern/gc.h etc.o: $(hdrdir)/ruby/internal/intern/hash.h etc.o: $(hdrdir)/ruby/internal/intern/io.h etc.o: $(hdrdir)/ruby/internal/intern/load.h @@ -156,12 +157,12 @@ etc.o: $(hdrdir)/ruby/internal/memory.h etc.o: $(hdrdir)/ruby/internal/method.h etc.o: $(hdrdir)/ruby/internal/module.h etc.o: $(hdrdir)/ruby/internal/newobj.h -etc.o: $(hdrdir)/ruby/internal/rgengc.h etc.o: $(hdrdir)/ruby/internal/scan_args.h etc.o: $(hdrdir)/ruby/internal/special_consts.h etc.o: $(hdrdir)/ruby/internal/static_assert.h etc.o: $(hdrdir)/ruby/internal/stdalign.h etc.o: $(hdrdir)/ruby/internal/stdbool.h +etc.o: $(hdrdir)/ruby/internal/stdckdint.h etc.o: $(hdrdir)/ruby/internal/symbol.h etc.o: $(hdrdir)/ruby/internal/value.h etc.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 9a691d6e34..fcbd1af1b5 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -47,12 +47,16 @@ static VALUE sGroup; #define HAVE_UNAME 1 #endif -#ifndef _WIN32 -char *getenv(); +#ifdef STDC_HEADERS +# include <stdlib.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif #endif -char *getlogin(); +RUBY_EXTERN char *getlogin(void); -#define RUBY_ETC_VERSION "1.4.0" +#define RUBY_ETC_VERSION "1.4.3" #ifdef HAVE_RB_DEPRECATE_CONSTANT void rb_deprecate_constant(VALUE mod, const char *name); @@ -62,6 +66,17 @@ void rb_deprecate_constant(VALUE mod, const char *name); #include "constdefs.h" +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + #ifdef HAVE_RUBY_ATOMIC_H # include "ruby/atomic.h" #else @@ -188,9 +203,10 @@ setup_passwd(struct passwd *pwd) #endif /* call-seq: - * getpwuid(uid) -> Passwd + * getpwuid(uid) -> Etc::Passwd * - * Returns the /etc/passwd information for the user with the given integer +uid+. + * Returns the <tt>/etc/passwd</tt> information for the user with the given + * integer +uid+. * * The information is returned as a Passwd struct. * @@ -199,7 +215,7 @@ setup_passwd(struct passwd *pwd) * * See the unix manpage for <code>getpwuid(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getpwuid(0) * #=> #<struct Etc::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash"> @@ -227,16 +243,16 @@ etc_getpwuid(int argc, VALUE *argv, VALUE obj) } /* call-seq: - * getpwnam(name) -> Passwd + * getpwnam(name) -> Etc::Passwd * - * Returns the /etc/passwd information for the user with specified login - * +name+. + * Returns the <tt>/etc/passwd</tt> information for the user with specified + * login +name+. * * The information is returned as a Passwd struct. * * See the unix manpage for <code>getpwnam(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getpwnam('root') * #=> #<struct Etc::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash"> @@ -291,17 +307,17 @@ each_passwd(void) #endif /* call-seq: - * Etc.passwd { |struct| block } -> Passwd - * Etc.passwd -> Passwd + * passwd { |struct| block } + * passwd -> Etc::Passwd * * Provides a convenient Ruby iterator which executes a block for each entry - * in the /etc/passwd file. + * in the <tt>/etc/passwd</tt> file. * * The code block is passed an Passwd struct. * * See ::getpwent above for details. * - * Example: + * *Example:* * * require 'etc' * @@ -327,18 +343,19 @@ etc_passwd(VALUE obj) } /* call-seq: - * Etc::Passwd.each { |struct| block } -> Passwd + * Etc::Passwd.each { |struct| block } -> Etc::Passwd * Etc::Passwd.each -> Enumerator * - * Iterates for each entry in the /etc/passwd file if a block is given. + * Iterates for each entry in the <tt>/etc/passwd</tt> file if a block is + * given. * * If no block is given, returns the Enumerator. * * The code block is passed an Passwd struct. * - * See ::getpwent above for details. + * See Etc.getpwent above for details. * - * Example: + * *Example:* * * require 'etc' * @@ -360,8 +377,11 @@ etc_each_passwd(VALUE obj) return obj; } -/* Resets the process of reading the /etc/passwd file, so that the next call - * to ::getpwent will return the first entry again. +/* call-seq: + * setpwent + * + * Resets the process of reading the <tt>/etc/passwd</tt> file, so that the + * next call to ::getpwent will return the first entry again. */ static VALUE etc_setpwent(VALUE obj) @@ -372,8 +392,11 @@ etc_setpwent(VALUE obj) return Qnil; } -/* Ends the process of scanning through the /etc/passwd file begun with - * ::getpwent, and closes the file. +/* call-seq: + * endpwent + * + * Ends the process of scanning through the <tt>/etc/passwd</tt> file begun + * with ::getpwent, and closes the file. */ static VALUE etc_endpwent(VALUE obj) @@ -384,7 +407,10 @@ etc_endpwent(VALUE obj) return Qnil; } -/* Returns an entry from the /etc/passwd file. +/* call-seq: + * getpwent -> Etc::Passwd + * + * Returns an entry from the <tt>/etc/passwd</tt> file. * * The first time it is called it opens the file and returns the first entry; * each successive call returns the next entry, or +nil+ if the end of the file @@ -432,16 +458,16 @@ setup_group(struct group *grp) #endif /* call-seq: - * getgrgid(group_id) -> Group + * getgrgid(group_id) -> Etc::Group * * Returns information about the group with specified integer +group_id+, - * as found in /etc/group. + * as found in <tt>/etc/group</tt>. * * The information is returned as a Group struct. * * See the unix manpage for <code>getgrgid(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getgrgid(100) * #=> #<struct Etc::Group name="users", passwd="x", gid=100, mem=["meta", "root"]> @@ -470,16 +496,16 @@ etc_getgrgid(int argc, VALUE *argv, VALUE obj) } /* call-seq: - * getgrnam(name) -> Group + * getgrnam(name) -> Etc::Group * * Returns information about the group with specified +name+, as found in - * /etc/group. + * <tt>/etc/group</tt>. * * The information is returned as a Group struct. * * See the unix manpage for <code>getgrnam(3)</code> for more detail. * - * === Example: + * *Example:* * * Etc.getgrnam('users') * #=> #<struct Etc::Group name="users", passwd="x", gid=100, mem=["meta", "root"]> @@ -512,7 +538,6 @@ group_ensure(VALUE _) return Qnil; } - static VALUE group_iterate(VALUE _) { @@ -535,14 +560,18 @@ each_group(void) } #endif -/* Provides a convenient Ruby iterator which executes a block for each entry - * in the /etc/group file. +/* call-seq: + * group { |struct| block } + * group -> Etc::Group + * + * Provides a convenient Ruby iterator which executes a block for each entry + * in the <tt>/etc/group</tt> file. * * The code block is passed an Group struct. * * See ::getgrent above for details. * - * Example: + * *Example:* * * require 'etc' * @@ -569,16 +598,17 @@ etc_group(VALUE obj) #ifdef HAVE_GETGRENT /* call-seq: - * Etc::Group.each { |group| block } -> obj + * Etc::Group.each { |group| block } -> Etc::Group * Etc::Group.each -> Enumerator * - * Iterates for each entry in the /etc/group file if a block is given. + * Iterates for each entry in the <tt>/etc/group</tt> file if a block is + * given. * * If no block is given, returns the Enumerator. * * The code block is passed a Group struct. * - * Example: + * *Example:* * * require 'etc' * @@ -599,8 +629,11 @@ etc_each_group(VALUE obj) } #endif -/* Resets the process of reading the /etc/group file, so that the next call - * to ::getgrent will return the first entry again. +/* call-seq: + * setgrent + * + * Resets the process of reading the <tt>/etc/group</tt> file, so that the + * next call to ::getgrent will return the first entry again. */ static VALUE etc_setgrent(VALUE obj) @@ -611,8 +644,11 @@ etc_setgrent(VALUE obj) return Qnil; } -/* Ends the process of scanning through the /etc/group file begun by - * ::getgrent, and closes the file. +/* call-seq: + * endgrent + * + * Ends the process of scanning through the <tt>/etc/group</tt> file begun + * by ::getgrent, and closes the file. */ static VALUE etc_endgrent(VALUE obj) @@ -623,7 +659,10 @@ etc_endgrent(VALUE obj) return Qnil; } -/* Returns an entry from the /etc/group file. +/* call-seq: + * getgrent -> Etc::Group + * + * Returns an entry from the <tt>/etc/group</tt> file. * * The first time it is called it opens the file and returns the first entry; * each successive call returns the next entry, or +nil+ if the end of the file @@ -654,12 +693,16 @@ UINT rb_w32_system_tmpdir(WCHAR *path, UINT len); VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc); #endif -/* +/* call-seq: + * sysconfdir -> String + * * Returns system configuration directory. * - * This is typically "/etc", but is modified by the prefix used when Ruby was - * compiled. For example, if Ruby is built and installed in /usr/local, - * returns "/usr/local/etc" on other platforms than Windows. + * This is typically <code>"/etc"</code>, but is modified by the prefix used + * when Ruby was compiled. For example, if Ruby is built and installed in + * <tt>/usr/local</tt>, returns <code>"/usr/local/etc"</code> on other + * platforms than Windows. + * * On Windows, this always returns the directory provided by the system. */ static VALUE @@ -672,7 +715,9 @@ etc_sysconfdir(VALUE obj) #endif } -/* +/* call-seq: + * systmpdir -> String + * * Returns system temporary directory; typically "/tmp". */ static VALUE @@ -716,13 +761,15 @@ etc_systmpdir(VALUE _) } #ifdef HAVE_UNAME -/* +/* call-seq: + * uname -> hash + * * Returns the system information obtained by uname system call. * * The return value is a hash which has 5 keys at least: * :sysname, :nodename, :release, :version, :machine * - * Example: + * *Example:* * * require 'etc' * require 'pp' @@ -832,7 +879,9 @@ etc_uname(VALUE obj) #endif #ifdef HAVE_SYSCONF -/* +/* call-seq: + * sysconf(name) -> Integer + * * Returns system configuration variable using sysconf(). * * _name_ should be a constant under <code>Etc</code> which begins with <code>SC_</code>. @@ -866,7 +915,9 @@ etc_sysconf(VALUE obj, VALUE arg) #endif #ifdef HAVE_CONFSTR -/* +/* call-seq: + * confstr(name) -> String + * * Returns system configuration variable using confstr(). * * _name_ should be a constant under <code>Etc</code> which begins with <code>CS_</code>. @@ -913,7 +964,9 @@ etc_confstr(VALUE obj, VALUE arg) #endif #ifdef HAVE_FPATHCONF -/* +/* call-seq: + * pathconf(name) -> Integer + * * Returns pathname configuration variable using fpathconf(). * * _name_ should be a constant under <code>Etc</code> which begins with <code>PC_</code>. @@ -932,14 +985,11 @@ io_pathconf(VALUE io, VALUE arg) { int name; long ret; - rb_io_t *fptr; name = NUM2INT(arg); - GetOpenFile(io, fptr); - errno = 0; - ret = fpathconf(fptr->fd, name); + ret = fpathconf(rb_io_descriptor(io), name); if (ret == -1) { if (errno == 0) /* no limit */ return Qnil; @@ -1008,7 +1058,9 @@ etc_nprocessors_affin(void) } #endif -/* +/* call-seq: + * nprocessors -> Integer + * * Returns the number of online processors. * * The result is intended as the number of processes to @@ -1018,7 +1070,7 @@ etc_nprocessors_affin(void) * - sched_getaffinity(): Linux * - sysconf(_SC_NPROCESSORS_ONLN): GNU/Linux, NetBSD, FreeBSD, OpenBSD, DragonFly BSD, OpenIndiana, Mac OS X, AIX * - * Example: + * *Example:* * * require 'etc' * p Etc.nprocessors #=> 4 @@ -1027,7 +1079,7 @@ etc_nprocessors_affin(void) * process is bound to specific cpus. This is intended for getting better * parallel processing. * - * Example: (Linux) + * *Example:* (Linux) * * linux$ taskset 0x3 ./ruby -retc -e "p Etc.nprocessors" #=> 2 * @@ -1067,16 +1119,17 @@ etc_nprocessors(VALUE obj) /* * The Etc module provides access to information typically stored in - * files in the /etc directory on Unix systems. + * files in the <tt>/etc</tt> directory on Unix systems. * * The information accessible consists of the information found in the - * /etc/passwd and /etc/group files, plus information about the system's - * temporary directory (/tmp) and configuration directory (/etc). + * <tt>/etc/passwd</tt> and <tt>/etc/group</tt> files, plus information + * about the system's temporary directory (<tt>/tmp</tt>) and configuration + * directory (<tt>/etc</tt>). * * The Etc module provides a more reliable way to access information about * the logged in user than environment variables such as +$USER+. * - * == Example: + * *Example:* * * require 'etc' * @@ -1096,10 +1149,11 @@ Init_etc(void) { VALUE mEtc; - #ifdef HAVE_RB_EXT_RACTOR_SAFE - RB_EXT_RACTOR_SAFE(true); - #endif +#ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(true); +#endif mEtc = rb_define_module("Etc"); + /* The version */ rb_define_const(mEtc, "VERSION", rb_str_new_cstr(RUBY_ETC_VERSION)); init_constants(mEtc); @@ -1159,14 +1213,17 @@ Init_etc(void) NULL); #if 0 /* - * Passwd is a Struct that contains the following members: + * Passwd is a placeholder Struct for user database on Unix systems. + * + * === The struct contains the following members * * name:: * contains the short login name of the user as a String. * passwd:: * contains the encrypted password of the user as a String. - * an 'x' is returned if shadow passwords are in use. An '*' is returned - * if the user cannot log in using a password. + * an <code>'x'</code> is returned if shadow passwords are in + * use. An <code>'*'</code> is returned if the user cannot + * log in using a password. * uid:: * contains the integer user ID (uid) of the user. * gid:: @@ -1176,25 +1233,24 @@ Init_etc(void) * shell:: * contains the path to the login shell of the user as a String. * - * === The following members below are optional, and must be compiled with special flags: + * === The following members below are system-dependent * * gecos:: * contains a longer String description of the user, such as * a full name. Some Unix systems provide structured information in the * gecos field, but this is system-dependent. - * must be compiled with +HAVE_STRUCT_PASSWD_PW_GECOS+ * change:: - * password change time(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_CHANGE+ + * password change time(integer). * quota:: - * quota value(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_QUOTA+ + * quota value(integer). * age:: - * password age(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_AGE+ + * password age(integer). * class:: - * user access class(string) must be compiled with +HAVE_STRUCT_PASSWD_PW_CLASS+ + * user access class(string). * comment:: - * comment(string) must be compiled with +HAVE_STRUCT_PASSWD_PW_COMMENT+ + * comment(string). * expire:: - * account expiration time(integer) must be compiled with +HAVE_STRUCT_PASSWD_PW_EXPIRE+ + * account expiration time(integer). */ sPasswd = rb_define_class_under(mEtc, "Passwd", rb_cStruct); #endif @@ -1210,9 +1266,9 @@ Init_etc(void) #if 0 /* - * Group is a Struct that is only available when compiled with +HAVE_GETGRENT+. + * Group is a placeholder Struct for user group database on Unix systems. * - * The struct contains the following members: + * === The struct contains the following members * * name:: * contains the name of the group as a String. @@ -1221,7 +1277,7 @@ Init_etc(void) * returned if password access to the group is not available; an empty * string is returned if no password is needed to obtain membership of * the group. - * Must be compiled with +HAVE_STRUCT_GROUP_GR_PASSWD+. + * This is system-dependent. * gid:: * contains the group's numeric ID as an integer. * mem:: diff --git a/ext/etc/extconf.rb b/ext/etc/extconf.rb index 159b1614b7..2e28d58037 100644 --- a/ext/etc/extconf.rb +++ b/ext/etc/extconf.rb @@ -43,13 +43,23 @@ have_struct_member('struct group', 'gr_passwd', 'grp.h') # for https://github.com/ruby/etc srcdir = File.expand_path("..", __FILE__) -if !File.exist?("#{srcdir}/depend") - %x[#{RbConfig.ruby} #{srcdir}/mkconstants.rb -o #{srcdir}/constdefs.h] +constdefs = "#{srcdir}/constdefs.h" +if !File.exist?(constdefs) + ruby = RbConfig.ruby + if File.file?(ruby) + ruby = [ruby] + else + require "shellwords" + ruby = Shellwords.split(ruby) + end + system(*ruby, "#{srcdir}/mkconstants.rb", "-o", constdefs) end # TODO: remove when dropping 2.7 support, as exported since 3.0 have_func('rb_deprecate_constant(Qnil, "None")') +have_func("rb_io_descriptor") + $distcleanfiles << "constdefs.h" create_makefile("etc") diff --git a/ext/etc/mkconstants.rb b/ext/etc/mkconstants.rb index a752d64519..a766560a8a 100644 --- a/ext/etc/mkconstants.rb +++ b/ext/etc/mkconstants.rb @@ -35,6 +35,12 @@ opt.def_option('-H FILE', 'specify output header file') {|filename| opt.parse! +CONST_PREFIXES = { + 'SC' => 'for Etc.sysconf; See <tt>man sysconf</tt>', + 'CS' => 'for Etc.confstr; See <tt>man constr</tt>', + 'PC' => 'for IO#pathconf; See <tt>man fpathconf</tt>', +} + h = {} COMMENTS = {} @@ -49,6 +55,13 @@ DATA.each_line {|s| next end h[name] = default_value + if additional = CONST_PREFIXES[name[/\A_([A-Z]+)_/, 1]] + if comment&.match(/\w\z/) + comment << " " << additional + else + (comment ||= String.new) << " " << additional.sub(/\A\w/) {$&.upcase} + end + end COMMENTS[name] = comment if comment } DEFS = h.to_a @@ -66,15 +79,11 @@ def each_name(pat) } end -erb_new = lambda do |src, safe, trim| - if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ - ERB.new(src, trim_mode: trim) - else - ERB.new(src, safe, trim) - end +erb_new = lambda do |src, trim| + ERB.new(src, trim_mode: trim) end -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_decls") % each_const {|name, default_value| #if !defined(<%=name%>) # if defined(HAVE_CONST_<%=name.upcase%>) @@ -88,7 +97,7 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_decls") % } EOS -erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") +erb_new.call(<<'EOS', '%').def_method(Object, "gen_const_defs") % each_const {|name, default_value| #if defined(<%=name%>) % if comment = COMMENTS[name] @@ -99,13 +108,13 @@ erb_new.call(<<'EOS', nil, '%').def_method(Object, "gen_const_defs") % } EOS -header_result = erb_new.call(<<'EOS', nil, '%').result(binding) +header_result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ <%= gen_const_decls %> EOS -result = erb_new.call(<<'EOS', nil, '%').result(binding) +result = erb_new.call(<<'EOS', '%').result(binding) /* autogenerated file */ #ifdef HAVE_LONG_LONG @@ -123,6 +132,9 @@ result = erb_new.call(<<'EOS', nil, '%').result(binding) static void init_constants(VALUE mod) { +#if 0 + mod = rb_define_module("Etc"); +#endif <%= gen_const_defs %> } EOS |