sysconf.c revision 1.32 1 /* $NetBSD: sysconf.c,v 1.32 2008/06/25 11:46:12 ad Exp $ */
2
3 /*-
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Sean Eric Fagan of Cygnus Support.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #if defined(LIBC_SCCS) && !defined(lint)
37 #if 0
38 static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
39 #else
40 __RCSID("$NetBSD: sysconf.c,v 1.32 2008/06/25 11:46:12 ad Exp $");
41 #endif
42 #endif /* LIBC_SCCS and not lint */
43
44 #include "namespace.h"
45 #include <sys/param.h>
46 #include <sys/sysctl.h>
47 #include <sys/time.h>
48 #include <sys/resource.h>
49
50 #include <errno.h>
51 #include <limits.h>
52 #include <time.h>
53 #include <unistd.h>
54 #include <paths.h>
55
56 #ifdef __weak_alias
57 __weak_alias(sysconf,__sysconf)
58 #endif
59
60 /*
61 * sysconf --
62 * get configurable system variables.
63 *
64 * XXX
65 * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values
66 * not change during the lifetime of the calling process. This would seem
67 * to require that any change to system limits kill all running processes.
68 * A workaround might be to cache the values when they are first retrieved
69 * and then simply return the cached value on subsequent calls. This is
70 * less useful than returning up-to-date values, however.
71 */
72 long
73 sysconf(int name)
74 {
75 struct rlimit rl;
76 size_t len;
77 int mib[CTL_MAXNAME], value;
78 unsigned int mib_len;
79 struct clockinfo tmpclock;
80 static int clk_tck;
81
82 len = sizeof(value);
83
84 /* Default length of the MIB */
85 mib_len = 2;
86
87 switch (name) {
88
89 /* 1003.1 */
90 case _SC_ARG_MAX:
91 mib[0] = CTL_KERN;
92 mib[1] = KERN_ARGMAX;
93 break;
94 case _SC_CHILD_MAX:
95 return (getrlimit(RLIMIT_NPROC, &rl) ? -1 : (long)rl.rlim_cur);
96 case _O_SC_CLK_TCK:
97 /*
98 * For applications compiled when CLK_TCK was a compile-time
99 * constant.
100 */
101 return 100;
102 case _SC_CLK_TCK:
103 /*
104 * Has to be handled specially because it returns a
105 * struct clockinfo instead of an integer. Also, since
106 * this might be called often by some things that
107 * don't grok CLK_TCK can be a macro expanding to a
108 * function, cache the value.
109 */
110 if (clk_tck == 0) {
111 mib[0] = CTL_KERN;
112 mib[1] = KERN_CLOCKRATE;
113 len = sizeof(struct clockinfo);
114 clk_tck = sysctl(mib, 2, &tmpclock, &len, NULL, 0)
115 == -1 ? -1 : tmpclock.hz;
116 }
117 return(clk_tck);
118 case _SC_JOB_CONTROL:
119 mib[0] = CTL_KERN;
120 mib[1] = KERN_JOB_CONTROL;
121 goto yesno;
122 case _SC_NGROUPS_MAX:
123 mib[0] = CTL_KERN;
124 mib[1] = KERN_NGROUPS;
125 break;
126 case _SC_OPEN_MAX:
127 return (getrlimit(RLIMIT_NOFILE, &rl) ? -1 : (long)rl.rlim_cur);
128 case _SC_STREAM_MAX:
129 mib[0] = CTL_USER;
130 mib[1] = USER_STREAM_MAX;
131 break;
132 case _SC_TZNAME_MAX:
133 mib[0] = CTL_USER;
134 mib[1] = USER_TZNAME_MAX;
135 break;
136 case _SC_SAVED_IDS:
137 mib[0] = CTL_KERN;
138 mib[1] = KERN_SAVED_IDS;
139 goto yesno;
140 case _SC_VERSION:
141 mib[0] = CTL_KERN;
142 mib[1] = KERN_POSIX1;
143 break;
144
145 /* 1003.1b */
146 case _SC_PAGESIZE:
147 return _getpagesize();
148 case _SC_FSYNC:
149 mib[0] = CTL_KERN;
150 mib[1] = KERN_FSYNC;
151 goto yesno;
152 case _SC_SYNCHRONIZED_IO:
153 mib[0] = CTL_KERN;
154 mib[1] = KERN_SYNCHRONIZED_IO;
155 goto yesno;
156 case _SC_MAPPED_FILES:
157 mib[0] = CTL_KERN;
158 mib[1] = KERN_MAPPED_FILES;
159 goto yesno;
160 case _SC_MEMLOCK:
161 mib[0] = CTL_KERN;
162 mib[1] = KERN_MEMLOCK;
163 goto yesno;
164 case _SC_MEMLOCK_RANGE:
165 mib[0] = CTL_KERN;
166 mib[1] = KERN_MEMLOCK_RANGE;
167 goto yesno;
168 case _SC_MEMORY_PROTECTION:
169 mib[0] = CTL_KERN;
170 mib[1] = KERN_MEMORY_PROTECTION;
171 goto yesno;
172 case _SC_MONOTONIC_CLOCK:
173 mib[0] = CTL_KERN;
174 mib[1] = KERN_MONOTONIC_CLOCK;
175 goto yesno;
176 case _SC_SEMAPHORES:
177 mib[0] = CTL_KERN;
178 mib[1] = KERN_POSIX_SEMAPHORES;
179 goto yesno;
180 case _SC_TIMERS:
181 mib[0] = CTL_KERN;
182 mib[1] = KERN_POSIX_TIMERS;
183 goto yesno;
184
185 /* 1003.1c */
186 case _SC_LOGIN_NAME_MAX:
187 mib[0] = CTL_KERN;
188 mib[1] = KERN_LOGIN_NAME_MAX;
189 break;
190 case _SC_THREADS:
191 mib[0] = CTL_KERN;
192 mib[1] = KERN_POSIX_THREADS;
193 goto yesno;
194
195 /* 1003.1j */
196 case _SC_BARRIERS:
197 mib[0] = CTL_KERN;
198 mib[1] = KERN_POSIX_BARRIERS;
199 goto yesno;
200 case _SC_SPIN_LOCKS:
201 mib[0] = CTL_KERN;
202 mib[1] = KERN_POSIX_SPIN_LOCKS;
203 goto yesno;
204 /* Historical; Threads option in 1003.1-2001 */
205 case _SC_READER_WRITER_LOCKS:
206 mib[0] = CTL_KERN;
207 mib[1] = KERN_POSIX_READER_WRITER_LOCKS;
208 goto yesno;
209
210 /* 1003.2 */
211 case _SC_BC_BASE_MAX:
212 mib[0] = CTL_USER;
213 mib[1] = USER_BC_BASE_MAX;
214 break;
215 case _SC_BC_DIM_MAX:
216 mib[0] = CTL_USER;
217 mib[1] = USER_BC_DIM_MAX;
218 break;
219 case _SC_BC_SCALE_MAX:
220 mib[0] = CTL_USER;
221 mib[1] = USER_BC_SCALE_MAX;
222 break;
223 case _SC_BC_STRING_MAX:
224 mib[0] = CTL_USER;
225 mib[1] = USER_BC_STRING_MAX;
226 break;
227 case _SC_COLL_WEIGHTS_MAX:
228 mib[0] = CTL_USER;
229 mib[1] = USER_COLL_WEIGHTS_MAX;
230 break;
231 case _SC_EXPR_NEST_MAX:
232 mib[0] = CTL_USER;
233 mib[1] = USER_EXPR_NEST_MAX;
234 break;
235 case _SC_LINE_MAX:
236 mib[0] = CTL_USER;
237 mib[1] = USER_LINE_MAX;
238 break;
239 case _SC_RE_DUP_MAX:
240 mib[0] = CTL_USER;
241 mib[1] = USER_RE_DUP_MAX;
242 break;
243 case _SC_2_VERSION:
244 mib[0] = CTL_USER;
245 mib[1] = USER_POSIX2_VERSION;
246 break;
247 case _SC_2_C_BIND:
248 mib[0] = CTL_USER;
249 mib[1] = USER_POSIX2_C_BIND;
250 goto yesno;
251 case _SC_2_C_DEV:
252 mib[0] = CTL_USER;
253 mib[1] = USER_POSIX2_C_DEV;
254 goto yesno;
255 case _SC_2_CHAR_TERM:
256 mib[0] = CTL_USER;
257 mib[1] = USER_POSIX2_CHAR_TERM;
258 goto yesno;
259 case _SC_2_FORT_DEV:
260 mib[0] = CTL_USER;
261 mib[1] = USER_POSIX2_FORT_DEV;
262 goto yesno;
263 case _SC_2_FORT_RUN:
264 mib[0] = CTL_USER;
265 mib[1] = USER_POSIX2_FORT_RUN;
266 goto yesno;
267 case _SC_2_LOCALEDEF:
268 mib[0] = CTL_USER;
269 mib[1] = USER_POSIX2_LOCALEDEF;
270 goto yesno;
271 case _SC_2_SW_DEV:
272 mib[0] = CTL_USER;
273 mib[1] = USER_POSIX2_SW_DEV;
274 goto yesno;
275 case _SC_2_UPE:
276 mib[0] = CTL_USER;
277 mib[1] = USER_POSIX2_UPE;
278 goto yesno;
279
280 /* XPG 4.2 */
281 case _SC_IOV_MAX:
282 mib[0] = CTL_KERN;
283 mib[1] = KERN_IOV_MAX;
284 break;
285 case _SC_XOPEN_SHM:
286 mib[0] = CTL_KERN;
287 mib[1] = KERN_SYSVIPC;
288 mib[2] = KERN_SYSVIPC_SHM;
289 mib_len = 3;
290 goto yesno;
291
292 /* 1003.1-2001, XSI Option Group */
293 case _SC_AIO_LISTIO_MAX:
294 if (sysctlgetmibinfo("kern.aio_listio_max", &mib[0], &mib_len,
295 NULL, NULL, NULL, SYSCTL_VERSION))
296 return -1;
297 break;
298 case _SC_AIO_MAX:
299 if (sysctlgetmibinfo("kern.aio_max", &mib[0], &mib_len,
300 NULL, NULL, NULL, SYSCTL_VERSION))
301 return -1;
302 break;
303 case _SC_ASYNCHRONOUS_IO:
304 if (sysctlgetmibinfo("kern.posix_aio", &mib[0], &mib_len,
305 NULL, NULL, NULL, SYSCTL_VERSION))
306 return -1;
307 goto yesno;
308 case _SC_MESSAGE_PASSING:
309 if (sysctlgetmibinfo("kern.posix_msg", &mib[0], &mib_len,
310 NULL, NULL, NULL, SYSCTL_VERSION))
311 return -1;
312 goto yesno;
313 case _SC_MQ_OPEN_MAX:
314 if (sysctlgetmibinfo("kern.mqueue.mq_open_max", &mib[0],
315 &mib_len, NULL, NULL, NULL, SYSCTL_VERSION))
316 return -1;
317 break;
318 case _SC_MQ_PRIO_MAX:
319 if (sysctlgetmibinfo("kern.mqueue.mq_prio_max", &mib[0],
320 &mib_len, NULL, NULL, NULL, SYSCTL_VERSION))
321 return -1;
322 break;
323 case _SC_PRIORITY_SCHEDULING:
324 if (sysctlgetmibinfo("kern.posix_sched", &mib[0], &mib_len,
325 NULL, NULL, NULL, SYSCTL_VERSION))
326 return -1;
327 goto yesno;
328 case _SC_ATEXIT_MAX:
329 mib[0] = CTL_USER;
330 mib[1] = USER_ATEXIT_MAX;
331 break;
332
333 /* 1003.1-2001, TSF */
334 case _SC_GETGR_R_SIZE_MAX:
335 return _GETGR_R_SIZE_MAX;
336 case _SC_GETPW_R_SIZE_MAX:
337 return _GETPW_R_SIZE_MAX;
338
339 yesno: if (sysctl(mib, mib_len, &value, &len, NULL, 0) == -1)
340 return (-1);
341 if (value == 0)
342 return (-1);
343 return (value);
344 /*NOTREACHED*/
345 break;
346
347 /* Extensions */
348 case _SC_NPROCESSORS_CONF:
349 mib[0] = CTL_HW;
350 mib[1] = HW_NCPU;
351 break;
352 case _SC_NPROCESSORS_ONLN:
353 mib[0] = CTL_HW;
354 mib[1] = HW_NCPUONLINE;
355 break;
356
357 /* Native */
358 case _SC_SCHED_RT_TS:
359 if (sysctlgetmibinfo("kern.sched.rtts", &mib[0], &mib_len,
360 NULL, NULL, NULL, SYSCTL_VERSION))
361 return -1;
362 break;
363 case _SC_SCHED_PRI_MIN:
364 if (sysctlgetmibinfo("kern.sched.pri_min", &mib[0], &mib_len,
365 NULL, NULL, NULL, SYSCTL_VERSION))
366 return -1;
367 break;
368 case _SC_SCHED_PRI_MAX:
369 if (sysctlgetmibinfo("kern.sched.pri_max", &mib[0], &mib_len,
370 NULL, NULL, NULL, SYSCTL_VERSION))
371 return -1;
372 break;
373 case _SC_THREAD_DESTRUCTOR_ITERATIONS:
374 return _POSIX_THREAD_DESTRUCTOR_ITERATIONS;
375 case _SC_THREAD_KEYS_MAX:
376 return _POSIX_THREAD_KEYS_MAX;
377 case _SC_THREAD_STACK_MIN:
378 return _getpagesize();
379 case _SC_THREAD_THREADS_MAX:
380 if (sysctlgetmibinfo("kern.maxproc", &mib[0], &mib_len,
381 NULL, NULL, NULL, SYSCTL_VERSION)) /* XXX */
382 return -1;
383 goto yesno;
384 case _SC_THREAD_ATTR_STACKADDR:
385 return _POSIX_THREAD_ATTR_STACKADDR;
386 case _SC_THREAD_ATTR_STACKSIZE:
387 return _POSIX_THREAD_ATTR_STACKSIZE;
388 case _SC_THREAD_SAFE_FUNCTIONS:
389 return _POSIX_THREAD_SAFE_FUNCTIONS;
390 case _SC_THREAD_PRIORITY_SCHEDULING:
391 case _SC_THREAD_PRIO_INHERIT:
392 case _SC_THREAD_PRIO_PROTECT:
393 case _SC_THREAD_PROCESS_SHARED:
394 return -1;
395 case _SC_TTY_NAME_MAX:
396 return pathconf(_PATH_DEV, _PC_NAME_MAX);
397 default:
398 errno = EINVAL;
399 return (-1);
400 }
401 return (sysctl(mib, mib_len, &value, &len, NULL, 0) == -1 ? -1 : value);
402 }
403