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