etc 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ require 'mkmf'
3
+
4
+ headers = []
5
+ %w[sys/utsname.h].each {|h|
6
+ if have_header(h, headers)
7
+ headers << h
8
+ end
9
+ }
10
+ have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4
11
+ have_func("uname((struct utsname *)NULL)", headers)
12
+ have_func("getlogin")
13
+ have_func("getpwent")
14
+ have_func("getgrent")
15
+ sysconfdir = RbConfig.expand(RbConfig::CONFIG["sysconfdir"].dup, "prefix"=>"", "DESTDIR"=>"")
16
+ $defs.push("-DSYSCONFDIR=#{Shellwords.escape(sysconfdir.dump)}")
17
+
18
+ have_func("sysconf")
19
+ have_func("confstr")
20
+ have_func("fpathconf")
21
+
22
+ have_struct_member('struct passwd', 'pw_gecos', 'pwd.h')
23
+ have_struct_member('struct passwd', 'pw_change', 'pwd.h')
24
+ have_struct_member('struct passwd', 'pw_quota', 'pwd.h')
25
+ if have_struct_member('struct passwd', 'pw_age', 'pwd.h')
26
+ case what_type?('struct passwd', 'pw_age', 'pwd.h')
27
+ when "string"
28
+ f = "safe_setup_str"
29
+ when "long long"
30
+ f = "LL2NUM"
31
+ else
32
+ f = "INT2NUM"
33
+ end
34
+ $defs.push("-DPW_AGE2VAL="+f)
35
+ end
36
+ have_struct_member('struct passwd', 'pw_class', 'pwd.h')
37
+ have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin/ === RUBY_PLATFORM
38
+ have_struct_member('struct passwd', 'pw_expire', 'pwd.h')
39
+ have_struct_member('struct passwd', 'pw_passwd', 'pwd.h')
40
+ have_struct_member('struct group', 'gr_passwd', 'grp.h')
41
+
42
+ $distcleanfiles << "constdefs.h"
43
+
44
+ create_makefile("etc")
@@ -0,0 +1,332 @@
1
+ # frozen_string_literal: true
2
+ require 'optparse'
3
+ require 'erb'
4
+
5
+ C_ESC = {
6
+ "\\" => "\\\\",
7
+ '"' => '\"',
8
+ "\n" => '\n',
9
+ }
10
+
11
+ 0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
12
+ 0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
13
+ C_ESC_PAT = Regexp.union(*C_ESC.keys)
14
+
15
+ def c_str(str)
16
+ '"' + str.gsub(C_ESC_PAT) {|s| C_ESC[s]} + '"'
17
+ end
18
+
19
+ opt = OptionParser.new
20
+
21
+ opt.def_option('-h', 'help') {
22
+ puts opt
23
+ exit 0
24
+ }
25
+
26
+ opt_o = nil
27
+ opt.def_option('-o FILE', 'specify output file') {|filename|
28
+ opt_o = filename
29
+ }
30
+
31
+ opt_H = nil
32
+ opt.def_option('-H FILE', 'specify output header file') {|filename|
33
+ opt_H = filename
34
+ }
35
+
36
+ opt.parse!
37
+
38
+ h = {}
39
+ COMMENTS = {}
40
+
41
+ DATA.each_line {|s|
42
+ next if /\A\s*(\#|\z)/ =~ s
43
+ name, default_value, comment = s.chomp.split(/\s+/, 3)
44
+
45
+ default_value = nil if default_value == 'nil'
46
+
47
+ if h.has_key? name
48
+ warn "#{$.}: warning: duplicate name: #{name}"
49
+ next
50
+ end
51
+ h[name] = default_value
52
+ COMMENTS[name] = comment if comment
53
+ }
54
+ DEFS = h.to_a
55
+
56
+ def each_const
57
+ DEFS.each {|name, default_value|
58
+ yield name, default_value
59
+ }
60
+ end
61
+
62
+ def each_name(pat)
63
+ DEFS.each {|name, default_value|
64
+ next if pat !~ name
65
+ yield name
66
+ }
67
+ end
68
+
69
+ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
70
+ % each_const {|name, default_value|
71
+ #if !defined(<%=name%>)
72
+ # if defined(HAVE_CONST_<%=name.upcase%>)
73
+ # define <%=name%> <%=name%>
74
+ %if default_value
75
+ # else
76
+ # define <%=name%> <%=default_value%>
77
+ %end
78
+ # endif
79
+ #endif
80
+ % }
81
+ EOS
82
+
83
+ ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
84
+ % each_const {|name, default_value|
85
+ #if defined(<%=name%>)
86
+ % if comment = COMMENTS[name]
87
+ /* <%=comment%> */
88
+ % end
89
+ rb_define_const(mod, <%=c_str name.sub(/\A_*/, '')%>, INTEGER2NUM(<%=name%>));
90
+ #endif
91
+ % }
92
+ EOS
93
+
94
+ header_result = ERB.new(<<'EOS', nil, '%').result(binding)
95
+ /* autogenerated file */
96
+
97
+ <%= gen_const_decls %>
98
+ EOS
99
+
100
+ result = ERB.new(<<'EOS', nil, '%').result(binding)
101
+ /* autogenerated file */
102
+
103
+ #ifdef HAVE_LONG_LONG
104
+ #define INTEGER2NUM(n) \
105
+ (FIXNUM_MAX < (n) ? ULL2NUM(n) : \
106
+ FIXNUM_MIN > (LONG_LONG)(n) ? LL2NUM(n) : \
107
+ LONG2FIX(n))
108
+ #else
109
+ #define INTEGER2NUM(n) \
110
+ (FIXNUM_MAX < (n) ? ULONG2NUM(n) : \
111
+ FIXNUM_MIN > (long)(n) ? LONG2NUM(n) : \
112
+ LONG2FIX(n))
113
+ #endif
114
+
115
+ static void
116
+ init_constants(VALUE mod)
117
+ {
118
+ <%= gen_const_defs %>
119
+ }
120
+ EOS
121
+
122
+ if opt_H
123
+ File.open(opt_H, 'w') {|f|
124
+ f << header_result
125
+ }
126
+ else
127
+ result = header_result + result
128
+ end
129
+
130
+ if opt_o
131
+ File.open(opt_o, 'w') {|f|
132
+ f << result
133
+ }
134
+ else
135
+ $stdout << result
136
+ end
137
+
138
+ __END__
139
+ # SUSv4
140
+ _SC_AIO_LISTIO_MAX
141
+ _SC_AIO_MAX
142
+ _SC_AIO_PRIO_DELTA_MAX
143
+ _SC_ARG_MAX
144
+ _SC_ATEXIT_MAX
145
+ _SC_BC_BASE_MAX
146
+ _SC_BC_DIM_MAX
147
+ _SC_BC_SCALE_MAX
148
+ _SC_BC_STRING_MAX
149
+ _SC_CHILD_MAX
150
+ _SC_CLK_TCK
151
+ _SC_COLL_WEIGHTS_MAX
152
+ _SC_DELAYTIMER_MAX
153
+ _SC_EXPR_NEST_MAX
154
+ _SC_HOST_NAME_MAX
155
+ _SC_IOV_MAX
156
+ _SC_LINE_MAX
157
+ _SC_LOGIN_NAME_MAX
158
+ _SC_NGROUPS_MAX
159
+ _SC_GETGR_R_SIZE_MAX
160
+ _SC_GETPW_R_SIZE_MAX
161
+ _SC_MQ_OPEN_MAX
162
+ _SC_MQ_PRIO_MAX
163
+ _SC_OPEN_MAX
164
+ _SC_ADVISORY_INFO
165
+ _SC_BARRIERS
166
+ _SC_ASYNCHRONOUS_IO
167
+ _SC_CLOCK_SELECTION
168
+ _SC_CPUTIME
169
+ _SC_FSYNC
170
+ _SC_IPV6
171
+ _SC_JOB_CONTROL
172
+ _SC_MAPPED_FILES
173
+ _SC_MEMLOCK
174
+ _SC_MEMLOCK_RANGE
175
+ _SC_MEMORY_PROTECTION
176
+ _SC_MESSAGE_PASSING
177
+ _SC_MONOTONIC_CLOCK
178
+ _SC_PRIORITIZED_IO
179
+ _SC_PRIORITY_SCHEDULING
180
+ _SC_RAW_SOCKETS
181
+ _SC_READER_WRITER_LOCKS
182
+ _SC_REALTIME_SIGNALS
183
+ _SC_REGEXP
184
+ _SC_SAVED_IDS
185
+ _SC_SEMAPHORES
186
+ _SC_SHARED_MEMORY_OBJECTS
187
+ _SC_SHELL
188
+ _SC_SPAWN
189
+ _SC_SPIN_LOCKS
190
+ _SC_SPORADIC_SERVER
191
+ _SC_SS_REPL_MAX
192
+ _SC_SYNCHRONIZED_IO
193
+ _SC_THREAD_ATTR_STACKADDR
194
+ _SC_THREAD_ATTR_STACKSIZE
195
+ _SC_THREAD_CPUTIME
196
+ _SC_THREAD_PRIO_INHERIT
197
+ _SC_THREAD_PRIO_PROTECT
198
+ _SC_THREAD_PRIORITY_SCHEDULING
199
+ _SC_THREAD_PROCESS_SHARED
200
+ _SC_THREAD_ROBUST_PRIO_INHERIT
201
+ _SC_THREAD_ROBUST_PRIO_PROTECT
202
+ _SC_THREAD_SAFE_FUNCTIONS
203
+ _SC_THREAD_SPORADIC_SERVER
204
+ _SC_THREADS
205
+ _SC_TIMEOUTS
206
+ _SC_TIMERS
207
+ _SC_TRACE
208
+ _SC_TRACE_EVENT_FILTER
209
+ _SC_TRACE_EVENT_NAME_MAX
210
+ _SC_TRACE_INHERIT
211
+ _SC_TRACE_LOG
212
+ _SC_TRACE_NAME_MAX
213
+ _SC_TRACE_SYS_MAX
214
+ _SC_TRACE_USER_EVENT_MAX
215
+ _SC_TYPED_MEMORY_OBJECTS
216
+ _SC_VERSION
217
+ _SC_V7_ILP32_OFF32
218
+ _SC_V7_ILP32_OFFBIG
219
+ _SC_V7_LP64_OFF64
220
+ _SC_V7_LPBIG_OFFBIG
221
+ _SC_V6_ILP32_OFF32
222
+ _SC_V6_ILP32_OFFBIG
223
+ _SC_V6_LP64_OFF64
224
+ _SC_V6_LPBIG_OFFBIG
225
+ _SC_2_C_BIND
226
+ _SC_2_C_DEV
227
+ _SC_2_CHAR_TERM
228
+ _SC_2_FORT_DEV
229
+ _SC_2_FORT_RUN
230
+ _SC_2_LOCALEDEF
231
+ _SC_2_PBS
232
+ _SC_2_PBS_ACCOUNTING
233
+ _SC_2_PBS_CHECKPOINT
234
+ _SC_2_PBS_LOCATE
235
+ _SC_2_PBS_MESSAGE
236
+ _SC_2_PBS_TRACK
237
+ _SC_2_SW_DEV
238
+ _SC_2_UPE
239
+ _SC_2_VERSION
240
+ _SC_PAGE_SIZE
241
+ _SC_PAGESIZE
242
+ _SC_THREAD_DESTRUCTOR_ITERATIONS
243
+ _SC_THREAD_KEYS_MAX
244
+ _SC_THREAD_STACK_MIN
245
+ _SC_THREAD_THREADS_MAX
246
+ _SC_RE_DUP_MAX
247
+ _SC_RTSIG_MAX
248
+ _SC_SEM_NSEMS_MAX
249
+ _SC_SEM_VALUE_MAX
250
+ _SC_SIGQUEUE_MAX
251
+ _SC_STREAM_MAX
252
+ _SC_SYMLOOP_MAX
253
+ _SC_TIMER_MAX
254
+ _SC_TTY_NAME_MAX
255
+ _SC_TZNAME_MAX
256
+ _SC_XOPEN_CRYPT
257
+ _SC_XOPEN_ENH_I18N
258
+ _SC_XOPEN_REALTIME
259
+ _SC_XOPEN_REALTIME_THREADS
260
+ _SC_XOPEN_SHM
261
+ _SC_XOPEN_STREAMS
262
+ _SC_XOPEN_UNIX
263
+ _SC_XOPEN_UUCP
264
+ _SC_XOPEN_VERSION
265
+
266
+ # non-standard
267
+ _SC_PHYS_PAGES
268
+ _SC_AVPHYS_PAGES
269
+ _SC_NPROCESSORS_CONF
270
+ _SC_NPROCESSORS_ONLN
271
+ _SC_CPUSET_SIZE
272
+
273
+ # SUSv4
274
+ _CS_PATH
275
+ _CS_POSIX_V7_ILP32_OFF32_CFLAGS
276
+ _CS_POSIX_V7_ILP32_OFF32_LDFLAGS
277
+ _CS_POSIX_V7_ILP32_OFF32_LIBS
278
+ _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS
279
+ _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS
280
+ _CS_POSIX_V7_ILP32_OFFBIG_LIBS
281
+ _CS_POSIX_V7_LP64_OFF64_CFLAGS
282
+ _CS_POSIX_V7_LP64_OFF64_LDFLAGS
283
+ _CS_POSIX_V7_LP64_OFF64_LIBS
284
+ _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS
285
+ _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS
286
+ _CS_POSIX_V7_LPBIG_OFFBIG_LIBS
287
+ _CS_POSIX_V7_THREADS_CFLAGS
288
+ _CS_POSIX_V7_THREADS_LDFLAGS
289
+ _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS
290
+ _CS_V7_ENV
291
+ _CS_POSIX_V6_ILP32_OFF32_CFLAGS
292
+ _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
293
+ _CS_POSIX_V6_ILP32_OFF32_LIBS
294
+ _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
295
+ _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
296
+ _CS_POSIX_V6_ILP32_OFFBIG_LIBS
297
+ _CS_POSIX_V6_LP64_OFF64_CFLAGS
298
+ _CS_POSIX_V6_LP64_OFF64_LDFLAGS
299
+ _CS_POSIX_V6_LP64_OFF64_LIBS
300
+ _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
301
+ _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
302
+ _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
303
+ _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS
304
+ _CS_V6_ENV
305
+
306
+ # non-standard
307
+ _CS_GNU_LIBC_VERSION
308
+ _CS_GNU_LIBPTHREAD_VERSION
309
+
310
+ # SUSv4
311
+ _PC_FILESIZEBITS
312
+ _PC_LINK_MAX
313
+ _PC_MAX_CANON
314
+ _PC_MAX_INPUT
315
+ _PC_NAME_MAX
316
+ _PC_PATH_MAX
317
+ _PC_PIPE_BUF
318
+ _PC_2_SYMLINKS
319
+ _PC_ALLOC_SIZE_MIN
320
+ _PC_REC_INCR_XFER_SIZE
321
+ _PC_REC_MAX_XFER_SIZE
322
+ _PC_REC_MIN_XFER_SIZE
323
+ _PC_REC_XFER_ALIGN
324
+ _PC_SYMLINK_MAX
325
+ _PC_CHOWN_RESTRICTED
326
+ _PC_NO_TRUNC
327
+ _PC_VDISABLE
328
+ _PC_ASYNC_IO
329
+ _PC_PRIO_IO
330
+ _PC_SYNC_IO
331
+ _PC_TIMESTAMP_RESOLUTION
332
+
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+ require "test/unit"
3
+ require "etc"
4
+
5
+ class TestEtc < Test::Unit::TestCase
6
+ def test_getlogin
7
+ s = Etc.getlogin
8
+ return if s == nil
9
+ assert(s.is_a?(String), "getlogin must return a String or nil")
10
+ assert_predicate(s, :valid_encoding?, "login name should be a valid string")
11
+ end
12
+
13
+ def test_passwd
14
+ Etc.passwd do |s|
15
+ assert_instance_of(String, s.name)
16
+ assert_instance_of(String, s.passwd) if s.respond_to?(:passwd)
17
+ assert_kind_of(Integer, s.uid)
18
+ assert_kind_of(Integer, s.gid)
19
+ assert_instance_of(String, s.gecos) if s.respond_to?(:gecos)
20
+ assert_instance_of(String, s.dir)
21
+ assert_instance_of(String, s.shell)
22
+ assert_kind_of(Integer, s.change) if s.respond_to?(:change)
23
+ assert_kind_of(Integer, s.quota) if s.respond_to?(:quota)
24
+ assert(s.age.is_a?(Integer) || s.age.is_a?(String)) if s.respond_to?(:age)
25
+ assert_instance_of(String, s.uclass) if s.respond_to?(:uclass)
26
+ assert_instance_of(String, s.comment) if s.respond_to?(:comment)
27
+ assert_kind_of(Integer, s.expire) if s.respond_to?(:expire)
28
+ end
29
+
30
+ Etc.passwd { assert_raise(RuntimeError) { Etc.passwd { } }; break }
31
+ end
32
+
33
+ def test_getpwuid
34
+ # password database is not unique on UID, and which entry will be
35
+ # returned by getpwuid() is not specified.
36
+ passwd = Hash.new {[]}
37
+ # on MacOSX, same entries are returned from /etc/passwd and Open
38
+ # Directory.
39
+ Etc.passwd {|s| passwd[s.uid] |= [s]}
40
+ passwd.each_pair do |uid, s|
41
+ assert_include(s, Etc.getpwuid(uid))
42
+ end
43
+ s = passwd[Process.euid]
44
+ unless s.empty?
45
+ assert_include(s, Etc.getpwuid)
46
+ end
47
+ end
48
+
49
+ def test_getpwnam
50
+ passwd = {}
51
+ Etc.passwd do |s|
52
+ passwd[s.name] ||= s unless /\A\+/ =~ s.name
53
+ end
54
+ passwd.each_value do |s|
55
+ assert_equal(s, Etc.getpwnam(s.name))
56
+ end
57
+ end
58
+
59
+ def test_passwd_with_low_level_api
60
+ a = []
61
+ Etc.passwd {|s| a << s }
62
+ b = []
63
+ Etc.setpwent
64
+ while s = Etc.getpwent
65
+ b << s
66
+ end
67
+ Etc.endpwent
68
+ assert_equal(a, b)
69
+ end
70
+
71
+ def test_group
72
+ Etc.group do |s|
73
+ assert_instance_of(String, s.name)
74
+ assert_instance_of(String, s.passwd) if s.respond_to?(:passwd)
75
+ assert_kind_of(Integer, s.gid)
76
+ end
77
+
78
+ Etc.group { assert_raise(RuntimeError) { Etc.group { } }; break }
79
+ end
80
+
81
+ def test_getgrgid
82
+ # group database is not unique on GID, and which entry will be
83
+ # returned by getgrgid() is not specified.
84
+ groups = Hash.new {[]}
85
+ # on MacOSX, same entries are returned from /etc/group and Open
86
+ # Directory.
87
+ Etc.group {|s| groups[s.gid] |= [[s.name, s.gid]]}
88
+ groups.each_pair do |gid, s|
89
+ g = Etc.getgrgid(gid)
90
+ assert_include(s, [g.name, g.gid])
91
+ end
92
+ s = groups[Process.egid]
93
+ unless s.empty?
94
+ g = Etc.getgrgid
95
+ assert_include(s, [g.name, g.gid])
96
+ end
97
+ end
98
+
99
+ def test_getgrnam
100
+ groups = {}
101
+ Etc.group do |s|
102
+ groups[s.name] ||= s.gid unless /\A\+/ =~ s.name
103
+ end
104
+ groups.each_pair do |n, s|
105
+ assert_equal(s, Etc.getgrnam(n).gid)
106
+ end
107
+ end
108
+
109
+ def test_group_with_low_level_api
110
+ a = []
111
+ Etc.group {|s| a << s }
112
+ b = []
113
+ Etc.setgrent
114
+ while s = Etc.getgrent
115
+ b << s
116
+ end
117
+ Etc.endgrent
118
+ assert_equal(a, b)
119
+ end
120
+
121
+ def test_uname
122
+ begin
123
+ uname = Etc.uname
124
+ rescue NotImplementedError
125
+ return
126
+ end
127
+ assert_kind_of(Hash, uname)
128
+ [:sysname, :nodename, :release, :version, :machine].each {|sym|
129
+ assert_operator(uname, :has_key?, sym)
130
+ assert_kind_of(String, uname[sym])
131
+ }
132
+ end
133
+
134
+ def test_sysconf
135
+ begin
136
+ Etc.sysconf
137
+ rescue NotImplementedError
138
+ return
139
+ rescue ArgumentError
140
+ end
141
+ assert_kind_of(Integer, Etc.sysconf(Etc::SC_CLK_TCK))
142
+ end if defined?(Etc::SC_CLK_TCK)
143
+
144
+ def test_confstr
145
+ begin
146
+ Etc.confstr
147
+ rescue NotImplementedError
148
+ return
149
+ rescue ArgumentError
150
+ end
151
+ assert_kind_of(String, Etc.confstr(Etc::CS_PATH))
152
+ end if defined?(Etc::CS_PATH)
153
+
154
+ def test_pathconf
155
+ begin
156
+ Etc.confstr
157
+ rescue NotImplementedError
158
+ return
159
+ rescue ArgumentError
160
+ end
161
+ IO.pipe {|r, w|
162
+ val = w.pathconf(Etc::PC_PIPE_BUF)
163
+ assert(val.nil? || val.kind_of?(Integer))
164
+ }
165
+ end if defined?(Etc::PC_PIPE_BUF)
166
+
167
+ def test_nprocessors
168
+ n = Etc.nprocessors
169
+ assert_operator(1, :<=, n)
170
+ end
171
+
172
+ end