Project

General

Profile

Feature #9842 ยป sysconf-confstr-fpathconf.patch

akr (Akira Tanaka), 05/16/2014 01:22 PM

View differences:

.gitignore
110 110
/ext/dl/callback/callback-*.c
111 111
/ext/dl/callback/callback.c
112 112

  
113
# /ext/etc/
114
/ext/etc/constdefs.h
115

  
113 116
# /ext/rbconfig/
114 117
/ext/rbconfig/sizeof/sizes.c
115 118

  
ext/etc/depend
1
etc.o : etc.c $(HDRS) $(ruby_headers) \
1
etc.o : etc.c constdefs.h $(HDRS) $(ruby_headers) \
2 2
  $(hdrdir)/ruby/encoding.h \
3 3
  $(hdrdir)/ruby/oniguruma.h
4

  
5
constdefs.h : $(srcdir)/mkconstants.rb
6
	@echo "generating constant definitions"
7
	@$(RUBY) $(srcdir)/mkconstants.rb -o constdefs.h
8

  
ext/etc/etc.c
9 9

  
10 10
#include "ruby.h"
11 11
#include "ruby/encoding.h"
12
#include "ruby/io.h"
12 13

  
13 14
#include <sys/types.h>
14 15
#ifdef HAVE_UNISTD_H
......
23 24
#include <grp.h>
24 25
#endif
25 26

  
27
#include <errno.h>
28

  
26 29
static VALUE sPasswd;
27 30
#ifdef HAVE_GETGRENT
28 31
static VALUE sGroup;
......
40 43
#endif
41 44
char *getlogin();
42 45

  
46
#include "constdefs.h"
47

  
43 48
/* call-seq:
44 49
 *	getlogin	->  String
45 50
 *
......
636 641
    return tmpdir;
637 642
}
638 643

  
644
#ifdef HAVE_SYSCONF
645
/*
646
 * Returns system configuration variable using sysconf().
647
 *
648
 * _name_ should be a constant undef <code>Etc</code> which begins with <code>SC_</code>.
649
 *
650
 * The return value is an integer or nil.
651
 * nil means indefinite limit.  (sysconf() returns -1 but errno is not set.)
652
 *
653
 *   Etc.sysconf(Etc::SC_ARG_MAX) #=> 2097152
654
 *
655
 *   # Number of processors.
656
 *   # It is not standardized.
657
 *   Etc.sysconf(Etc::SC_NPROCESSORS_ONLN) #=> 4
658
 *
659
 */
660
static VALUE
661
etc_sysconf(VALUE obj, VALUE arg)
662
{
663
    int name;
664
    long ret;
665

  
666
    name = NUM2INT(arg);
667

  
668
    errno = 0;
669
    ret = sysconf(name);
670
    if (ret == -1) {
671
        if (errno == 0) /* no limit */
672
            return Qnil;
673
        rb_sys_fail("sysconf");
674
    }
675
    return LONG2NUM(ret);
676
}
677
#else
678
#define etc_sysconf rb_f_notimplement
679
#endif
680

  
681
#ifdef HAVE_CONFSTR
682
/*
683
 * Returns system configuration variable using confstr().
684
 *
685
 * _name_ should be a constant undef <code>Etc</code> which begins with <code>CS_</code>.
686
 *
687
 * The return value is a string or nil.
688
 * nil means no configuration-defined value.  (confstr() returns 0 but errno is not set.)
689
 *
690
 *   Etc.confstr(Etc::CS_PATH) #=> "/bin:/usr/bin"
691
 *
692
 *   # GNU/Linux
693
 *   Etc.confstr(Etc::CS_GNU_LIBC_VERSION) #=> "glibc 2.18"
694
 *   Etc.confstr(Etc::CS_GNU_LIBPTHREAD_VERSION) #=> "NPTL 2.18"
695
 *
696
 */
697
static VALUE
698
etc_confstr(VALUE obj, VALUE arg)
699
{
700
    int name;
701
    char localbuf[128], *buf = localbuf;
702
    size_t bufsize = sizeof(localbuf), ret;
703
    VALUE tmp;
704

  
705
    name = NUM2INT(arg);
706

  
707
    errno = 0;
708
    ret = confstr(name, buf, bufsize);
709
    if (bufsize < ret) {
710
        bufsize = ret;
711
        buf = ALLOCV_N(char, tmp, bufsize);
712
        errno = 0;
713
        ret = confstr(name, buf, bufsize);
714
    }
715
    if (bufsize < ret)
716
        rb_bug("required buffer size for confstr() changed dynamically.");
717
    if (ret == 0) {
718
        if (errno == 0) /* no configuration-defined value */
719
            return Qnil;
720
        rb_sys_fail("confstr");
721
    }
722
    return rb_str_new_cstr(buf);
723
}
724
#else
725
#define etc_confstr rb_f_notimplement
726
#endif
727

  
728
#ifdef HAVE_FPATHCONF
729
/*
730
 * Returns pathname configuration variable using fpathconf().
731
 *
732
 * _name_ should be a constant undef <code>Etc</code> which begins with <code>PC_</code>.
733
 *
734
 * The return value is an integer or nil.
735
 * nil means indefinite limit.  (fpathconf() returns -1 but errno is not set.)
736
 *
737
 *   open("/") {|f| p f.pathconf(Etc::PC_NAME_MAX) } #=> 255
738
 *
739
 */
740
static VALUE
741
io_pathconf(VALUE io, VALUE arg)
742
{
743
    int name;
744
    long ret;
745
    rb_io_t *fptr;
746

  
747
    name = NUM2INT(arg);
748

  
749
    GetOpenFile(io, fptr);
750

  
751
    errno = 0;
752
    ret = fpathconf(fptr->fd, name);
753
    if (ret == -1) {
754
        if (errno == 0) /* no limit */
755
            return Qnil;
756
        rb_sys_fail("fpathconf");
757
    }
758
    return LONG2NUM(ret);
759
}
760
#else
761
#define io_pathconf rb_f_notimplement
762
#endif
763

  
639 764
/*
640 765
 * The Etc module provides access to information typically stored in
641 766
 * files in the /etc directory on Unix systems.
......
668 793
    VALUE mEtc;
669 794

  
670 795
    mEtc = rb_define_module("Etc");
796
    init_constants(mEtc);
797

  
671 798
    rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
672 799

  
673 800
    rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1);
......
686 813
    rb_define_module_function(mEtc, "sysconfdir", etc_sysconfdir, 0);
687 814
    rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0);
688 815

  
816
    rb_define_module_function(mEtc, "sysconf", etc_sysconf, 1);
817
    rb_define_module_function(mEtc, "confstr", etc_confstr, 1);
818
    rb_define_method(rb_cIO, "pathconf", io_pathconf, 1);
819

  
689 820
    sPasswd =  rb_struct_define_under(mEtc, "Passwd",
690 821
				      "name",
691 822
#ifdef HAVE_STRUCT_PASSWD_PW_PASSWD
ext/etc/extconf.rb
7 7
sysconfdir = RbConfig.expand(RbConfig::CONFIG["sysconfdir"].dup, "prefix"=>"", "DESTDIR"=>"")
8 8
$defs.push("-DSYSCONFDIR=#{Shellwords.escape(sysconfdir.dump)}")
9 9

  
10
have_func("sysconf")
11
have_func("confstr")
12
have_func("fpathconf")
13

  
10 14
have_struct_member('struct passwd', 'pw_gecos', 'pwd.h')
11 15
have_struct_member('struct passwd', 'pw_change', 'pwd.h')
12 16
have_struct_member('struct passwd', 'pw_quota', 'pwd.h')
ext/etc/mkconstants.rb
1
require 'optparse'
2
require 'erb'
3

  
4
C_ESC = {
5
  "\\" => "\\\\",
6
  '"' => '\"',
7
  "\n" => '\n',
8
}
9

  
10
0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
11
0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
12
C_ESC_PAT = Regexp.union(*C_ESC.keys)
13

  
14
def c_str(str)
15
  '"' + str.gsub(C_ESC_PAT) {|s| C_ESC[s]} + '"'
16
end
17

  
18
opt = OptionParser.new
19

  
20
opt.def_option('-h', 'help') {
21
  puts opt
22
  exit 0
23
}
24

  
25
opt_o = nil
26
opt.def_option('-o FILE', 'specify output file') {|filename|
27
  opt_o = filename
28
}
29

  
30
opt_H = nil
31
opt.def_option('-H FILE', 'specify output header file') {|filename|
32
  opt_H = filename
33
}
34

  
35
opt.parse!
36

  
37
h = {}
38
COMMENTS = Hash.new { |h, name| h[name] = name }
39

  
40
DATA.each_line {|s|
41
  next if /\A\s*(\#|\z)/ =~ s
42
  name, default_value, comment = s.chomp.split(/\s+/, 3)
43

  
44
  default_value = nil if default_value == 'nil'
45

  
46
  if h.has_key? name
47
    warn "#{$.}: warning: duplicate name: #{name}"
48
    next
49
  end
50
  h[name] = default_value
51
  COMMENTS[name] = comment
52
}
53
DEFS = h.to_a
54

  
55
def each_const
56
  DEFS.each {|name, default_value|
57
    yield name, default_value
58
  }
59
end
60

  
61
def each_name(pat)
62
  DEFS.each {|name, default_value|
63
    next if pat !~ name
64
    yield name
65
  }
66
end
67

  
68
ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_decls")
69
% each_const {|name, default_value|
70
#if !defined(<%=name%>)
71
# if defined(HAVE_CONST_<%=name.upcase%>)
72
#  define <%=name%> <%=name%>
73
%if default_value
74
# else
75
#  define <%=name%> <%=default_value%>
76
%end
77
# endif
78
#endif
79
% }
80
EOS
81

  
82
ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
83
% each_const {|name, default_value|
84
#if defined(<%=name%>)
85
    /* <%= COMMENTS[name] %> */
86
    rb_define_const(mod, <%=c_str name.sub(/\A_*/, '')%>, INTEGER2NUM(<%=name%>));
87
#endif
88
% }
89
EOS
90

  
91
header_result = ERB.new(<<'EOS', nil, '%').result(binding)
92
/* autogenerated file */
93

  
94
<%= gen_const_decls %>
95
EOS
96

  
97
result = ERB.new(<<'EOS', nil, '%').result(binding)
98
/* autogenerated file */
99

  
100
#ifdef HAVE_LONG_LONG
101
#define INTEGER2NUM(n) \
102
    (FIXNUM_MAX < (n) ? ULL2NUM(n) : \
103
     FIXNUM_MIN > (LONG_LONG)(n) ? LL2NUM(n) : \
104
     LONG2FIX(n))
105
#else
106
#define INTEGER2NUM(n) \
107
    (FIXNUM_MAX < (n) ? ULONG2NUM(n) : \
108
     FIXNUM_MIN > (long)(n) ? LONG2NUM(n) : \
109
     LONG2FIX(n))
110
#endif
111

  
112
static void
113
init_constants(VALUE mod)
114
{
115
<%= gen_const_defs %>
116
}
117
EOS
118

  
119
if opt_H
120
  File.open(opt_H, 'w') {|f|
121
    f << header_result
122
  }
123
else
124
  result = header_result + result
125
end
126

  
127
if opt_o
128
  File.open(opt_o, 'w') {|f|
129
    f << result
130
  }
131
else
132
  $stdout << result
133
end
134

  
135
__END__
136
# SUSv4
137
_SC_AIO_LISTIO_MAX
138
_SC_AIO_MAX
139
_SC_AIO_PRIO_DELTA_MAX
140
_SC_ARG_MAX
141
_SC_ATEXIT_MAX
142
_SC_BC_BASE_MAX
143
_SC_BC_DIM_MAX
144
_SC_BC_SCALE_MAX
145
_SC_BC_STRING_MAX
146
_SC_CHILD_MAX
147
_SC_CLK_TCK
148
_SC_COLL_WEIGHTS_MAX
149
_SC_DELAYTIMER_MAX
150
_SC_EXPR_NEST_MAX
151
_SC_HOST_NAME_MAX
152
_SC_IOV_MAX
153
_SC_LINE_MAX
154
_SC_LOGIN_NAME_MAX
155
_SC_NGROUPS_MAX
156
_SC_GETGR_R_SIZE_MAX
157
_SC_GETPW_R_SIZE_MAX
158
_SC_MQ_OPEN_MAX
159
_SC_MQ_PRIO_MAX
160
_SC_OPEN_MAX
161
_SC_ADVISORY_INFO
162
_SC_BARRIERS
163
_SC_ASYNCHRONOUS_IO
164
_SC_CLOCK_SELECTION
165
_SC_CPUTIME
166
_SC_FSYNC
167
_SC_IPV6
168
_SC_JOB_CONTROL
169
_SC_MAPPED_FILES
170
_SC_MEMLOCK
171
_SC_MEMLOCK_RANGE
172
_SC_MEMORY_PROTECTION
173
_SC_MESSAGE_PASSING
174
_SC_MONOTONIC_CLOCK
175
_SC_PRIORITIZED_IO
176
_SC_PRIORITY_SCHEDULING
177
_SC_RAW_SOCKETS
178
_SC_READER_WRITER_LOCKS
179
_SC_REALTIME_SIGNALS
180
_SC_REGEXP
181
_SC_SAVED_IDS
182
_SC_SEMAPHORES
183
_SC_SHARED_MEMORY_OBJECTS
184
_SC_SHELL
185
_SC_SPAWN
186
_SC_SPIN_LOCKS
187
_SC_SPORADIC_SERVER
188
_SC_SS_REPL_MAX
189
_SC_SYNCHRONIZED_IO
190
_SC_THREAD_ATTR_STACKADDR
191
_SC_THREAD_ATTR_STACKSIZE
192
_SC_THREAD_CPUTIME
193
_SC_THREAD_PRIO_INHERIT
194
_SC_THREAD_PRIO_PROTECT
195
_SC_THREAD_PRIORITY_SCHEDULING
196
_SC_THREAD_PROCESS_SHARED
197
_SC_THREAD_ROBUST_PRIO_INHERIT
198
_SC_THREAD_ROBUST_PRIO_PROTECT
199
_SC_THREAD_SAFE_FUNCTIONS
200
_SC_THREAD_SPORADIC_SERVER
201
_SC_THREADS
202
_SC_TIMEOUTS
203
_SC_TIMERS
204
_SC_TRACE
205
_SC_TRACE_EVENT_FILTER
206
_SC_TRACE_EVENT_NAME_MAX
207
_SC_TRACE_INHERIT
208
_SC_TRACE_LOG
209
_SC_TRACE_NAME_MAX
210
_SC_TRACE_SYS_MAX
211
_SC_TRACE_USER_EVENT_MAX
212
_SC_TYPED_MEMORY_OBJECTS
213
_SC_VERSION
214
_SC_V7_ILP32_OFF32
215
_SC_V7_ILP32_OFFBIG
216
_SC_V7_LP64_OFF64
217
_SC_V7_LPBIG_OFFBIG
218
_SC_V6_ILP32_OFF32
219
_SC_V6_ILP32_OFFBIG
220
_SC_V6_LP64_OFF64
221
_SC_V6_LPBIG_OFFBIG
222
_SC_2_C_BIND
223
_SC_2_C_DEV
224
_SC_2_CHAR_TERM
225
_SC_2_FORT_DEV
226
_SC_2_FORT_RUN
227
_SC_2_LOCALEDEF
228
_SC_2_PBS
229
_SC_2_PBS_ACCOUNTING
230
_SC_2_PBS_CHECKPOINT
231
_SC_2_PBS_LOCATE
232
_SC_2_PBS_MESSAGE
233
_SC_2_PBS_TRACK
234
_SC_2_SW_DEV
235
_SC_2_UPE
236
_SC_2_VERSION
237
_SC_PAGE_SIZE
238
_SC_PAGESIZE
239
_SC_THREAD_DESTRUCTOR_ITERATIONS
240
_SC_THREAD_KEYS_MAX
241
_SC_THREAD_STACK_MIN
242
_SC_THREAD_THREADS_MAX
243
_SC_RE_DUP_MAX
244
_SC_RTSIG_MAX
245
_SC_SEM_NSEMS_MAX
246
_SC_SEM_VALUE_MAX
247
_SC_SIGQUEUE_MAX
248
_SC_STREAM_MAX
249
_SC_SYMLOOP_MAX
250
_SC_TIMER_MAX
251
_SC_TTY_NAME_MAX
252
_SC_TZNAME_MAX
253
_SC_XOPEN_CRYPT
254
_SC_XOPEN_ENH_I18N
255
_SC_XOPEN_REALTIME
256
_SC_XOPEN_REALTIME_THREADS
257
_SC_XOPEN_SHM
258
_SC_XOPEN_STREAMS
259
_SC_XOPEN_UNIX
260
_SC_XOPEN_UUCP
261
_SC_XOPEN_VERSION
262

  
263
# non-standard
264
_SC_PHYS_PAGES
265
_SC_AVPHYS_PAGES
266
_SC_NPROCESSORS_CONF
267
_SC_NPROCESSORS_ONLN
268
_SC_CPUSET_SIZE
269

  
270
# SUSv4
271
_CS_PATH
272
_CS_POSIX_V7_ILP32_OFF32_CFLAGS
273
_CS_POSIX_V7_ILP32_OFF32_LDFLAGS
274
_CS_POSIX_V7_ILP32_OFF32_LIBS
275
_CS_POSIX_V7_ILP32_OFFBIG_CFLAGS
276
_CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS
277
_CS_POSIX_V7_ILP32_OFFBIG_LIBS
278
_CS_POSIX_V7_LP64_OFF64_CFLAGS
279
_CS_POSIX_V7_LP64_OFF64_LDFLAGS
280
_CS_POSIX_V7_LP64_OFF64_LIBS
281
_CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS
282
_CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS
283
_CS_POSIX_V7_LPBIG_OFFBIG_LIBS
284
_CS_POSIX_V7_THREADS_CFLAGS
285
_CS_POSIX_V7_THREADS_LDFLAGS
286
_CS_POSIX_V7_WIDTH_RESTRICTED_ENVS
287
_CS_V7_ENV
288
_CS_POSIX_V6_ILP32_OFF32_CFLAGS
289
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS
290
_CS_POSIX_V6_ILP32_OFF32_LIBS
291
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
292
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
293
_CS_POSIX_V6_ILP32_OFFBIG_LIBS
294
_CS_POSIX_V6_LP64_OFF64_CFLAGS
295
_CS_POSIX_V6_LP64_OFF64_LDFLAGS
296
_CS_POSIX_V6_LP64_OFF64_LIBS
297
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
298
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
299
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS
300
_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS
301
_CS_V6_ENV
302

  
303
# non-standard
304
_CS_GNU_LIBC_VERSION
305
_CS_GNU_LIBPTHREAD_VERSION
306

  
307
# SUSv4
308
_PC_FILESIZEBITS
309
_PC_LINK_MAX
310
_PC_MAX_CANON
311
_PC_MAX_INPUT
312
_PC_NAME_MAX
313
_PC_PATH_MAX
314
_PC_PIPE_BUF
315
_PC_2_SYMLINKS
316
_PC_ALLOC_SIZE_MIN
317
_PC_REC_INCR_XFER_SIZE
318
_PC_REC_MAX_XFER_SIZE
319
_PC_REC_MIN_XFER_SIZE
320
_PC_REC_XFER_ALIGN
321
_PC_SYMLINK_MAX
322
_PC_CHOWN_RESTRICTED
323
_PC_NO_TRUNC
324
_PC_VDISABLE
325
_PC_ASYNC_IO
326
_PC_PRIO_IO
327
_PC_SYNC_IO
328
_PC_TIMESTAMP_RESOLUTION
329