etc 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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