1163953Srrs/* $NetBSD: sysconf.c,v 1.44 2023/10/25 08:19:34 simonb Exp $ */ 2166675Srrs 3163953Srrs/*- 4163953Srrs * Copyright (c) 1993 5163953Srrs * The Regents of the University of California. All rights reserved. 6163953Srrs * 7163953Srrs * This code is derived from software contributed to Berkeley by 8163953Srrs * Sean Eric Fagan of Cygnus Support. 9163953Srrs * 10163953Srrs * Redistribution and use in source and binary forms, with or without 11163953Srrs * modification, are permitted provided that the following conditions 12163953Srrs * are met: 13163953Srrs * 1. Redistributions of source code must retain the above copyright 14163953Srrs * notice, this list of conditions and the following disclaimer. 15163953Srrs * 2. Redistributions in binary form must reproduce the above copyright 16163953Srrs * notice, this list of conditions and the following disclaimer in the 17163953Srrs * documentation and/or other materials provided with the distribution. 18163953Srrs * 3. Neither the name of the University nor the names of its contributors 19163953Srrs * may be used to endorse or promote products derived from this software 20163953Srrs * without specific prior written permission. 21163953Srrs * 22163953Srrs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23163953Srrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24163953Srrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25163953Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26163953Srrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27163953Srrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28163953Srrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29163953Srrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30163953Srrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31163953Srrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32163953Srrs * SUCH DAMAGE. 33163953Srrs */ 34163953Srrs 35166086Srrs#include <sys/cdefs.h> 36163953Srrs#if defined(LIBC_SCCS) && !defined(lint) 37163953Srrs#if 0 38163953Srrsstatic char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94"; 39163953Srrs#else 40167695Srrs__RCSID("$NetBSD: sysconf.c,v 1.44 2023/10/25 08:19:34 simonb Exp $"); 41167695Srrs#endif 42167695Srrs#endif /* LIBC_SCCS and not lint */ 43167598Srrs 44163953Srrs#include "namespace.h" 45163953Srrs#include <sys/param.h> 46163953Srrs#include <sys/sysctl.h> 47163953Srrs#include <sys/time.h> 48163953Srrs#include <sys/resource.h> 49163953Srrs#include <uvm/uvm_extern.h> 50163953Srrs 51163953Srrs#include <errno.h> 52164085Srrs#include <limits.h> 53163953Srrs#include <time.h> 54163953Srrs#include <unistd.h> 55163953Srrs#include <paths.h> 56163953Srrs#include <pwd.h> 57163953Srrs 58163953Srrs#ifdef __weak_alias 59163953Srrs__weak_alias(sysconf,__sysconf) 60163953Srrs#endif 61163953Srrs 62163953Srrs/* 63163953Srrs * sysconf -- 64163953Srrs * get configurable system variables. 65163953Srrs * 66163953Srrs * XXX 67163953Srrs * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values 68163953Srrs * not change during the lifetime of the calling process. This would seem 69163953Srrs * to require that any change to system limits kill all running processes. 70163953Srrs * A workaround might be to cache the values when they are first retrieved 71163953Srrs * and then simply return the cached value on subsequent calls. This is 72163953Srrs * less useful than returning up-to-date values, however. 73163953Srrs */ 74163953Srrslong 75163953Srrssysconf(int name) 76163953Srrs{ 77163953Srrs struct rlimit rl; 78163953Srrs size_t len; 79163953Srrs uint64_t mem; 80163953Srrs int mib[CTL_MAXNAME], value; 81163953Srrs unsigned int mib_len; 82163953Srrs struct clockinfo tmpclock; 83166023Srrs struct uvmexp_sysctl uvmexp; 84166023Srrs static int clk_tck; 85166023Srrs 86166023Srrs len = sizeof(value); 87166023Srrs 88166023Srrs /* Default length of the MIB */ 89166023Srrs mib_len = 2; 90166023Srrs 91166023Srrs switch (name) { 92166023Srrs 93166023Srrs/* 1003.1 */ 94166023Srrs case _SC_ARG_MAX: 95166023Srrs mib[0] = CTL_KERN; 96166023Srrs mib[1] = KERN_ARGMAX; 97166023Srrs break; 98166023Srrs case _SC_CHILD_MAX: 99166023Srrs return (getrlimit(RLIMIT_NPROC, &rl) ? -1 : (long)rl.rlim_cur); 100166023Srrs case _O_SC_CLK_TCK: 101166023Srrs /* 102163953Srrs * For applications compiled when CLK_TCK was a compile-time 103163953Srrs * constant. 104167695Srrs */ 105163953Srrs return 100; 106163953Srrs case _SC_CLK_TCK: 107163953Srrs /* 108163953Srrs * Has to be handled specially because it returns a 109163953Srrs * struct clockinfo instead of an integer. Also, since 110163953Srrs * this might be called often by some things that 111163953Srrs * don't grok CLK_TCK can be a macro expanding to a 112163953Srrs * function, cache the value. 113163953Srrs */ 114163953Srrs if (clk_tck == 0) { 115163953Srrs mib[0] = CTL_KERN; 116163953Srrs mib[1] = KERN_CLOCKRATE; 117163953Srrs len = sizeof(struct clockinfo); 118163953Srrs clk_tck = sysctl(mib, 2, &tmpclock, &len, NULL, 0) 119163953Srrs == -1 ? -1 : tmpclock.hz; 120163953Srrs } 121163953Srrs return(clk_tck); 122163953Srrs case _SC_JOB_CONTROL: 123163953Srrs mib[0] = CTL_KERN; 124163953Srrs mib[1] = KERN_JOB_CONTROL; 125163953Srrs goto yesno; 126163953Srrs case _SC_NGROUPS_MAX: 127163953Srrs mib[0] = CTL_KERN; 128163953Srrs mib[1] = KERN_NGROUPS; 129163953Srrs break; 130163953Srrs case _SC_OPEN_MAX: 131163953Srrs return (getrlimit(RLIMIT_NOFILE, &rl) ? -1 : (long)rl.rlim_cur); 132163953Srrs case _SC_STREAM_MAX: 133163953Srrs mib[0] = CTL_USER; 134163953Srrs mib[1] = USER_STREAM_MAX; 135163953Srrs break; 136163953Srrs case _SC_TZNAME_MAX: 137163953Srrs mib[0] = CTL_USER; 138163953Srrs mib[1] = USER_TZNAME_MAX; 139163953Srrs break; 140163953Srrs case _SC_SAVED_IDS: 141163953Srrs mib[0] = CTL_KERN; 142163953Srrs mib[1] = KERN_SAVED_IDS; 143163953Srrs goto yesno; 144163953Srrs case _SC_VERSION: 145163953Srrs mib[0] = CTL_KERN; 146163953Srrs mib[1] = KERN_POSIX1; 147163953Srrs break; 148163953Srrs 149163953Srrs/* 1003.1b */ 150163953Srrs case _SC_PAGESIZE: 151163953Srrs return _getpagesize(); 152163953Srrs case _SC_FSYNC: 153163953Srrs mib[0] = CTL_KERN; 154163953Srrs mib[1] = KERN_FSYNC; 155163953Srrs goto yesno; 156163953Srrs case _SC_SYNCHRONIZED_IO: 157163953Srrs mib[0] = CTL_KERN; 158163953Srrs mib[1] = KERN_SYNCHRONIZED_IO; 159163953Srrs goto yesno; 160163953Srrs case _SC_MAPPED_FILES: 161163953Srrs mib[0] = CTL_KERN; 162163953Srrs mib[1] = KERN_MAPPED_FILES; 163163953Srrs goto yesno; 164163953Srrs case _SC_MEMLOCK: 165163953Srrs mib[0] = CTL_KERN; 166163953Srrs mib[1] = KERN_MEMLOCK; 167163953Srrs goto yesno; 168163953Srrs case _SC_MEMLOCK_RANGE: 169163953Srrs mib[0] = CTL_KERN; 170163953Srrs mib[1] = KERN_MEMLOCK_RANGE; 171163953Srrs goto yesno; 172163953Srrs case _SC_MEMORY_PROTECTION: 173163953Srrs mib[0] = CTL_KERN; 174163953Srrs mib[1] = KERN_MEMORY_PROTECTION; 175163953Srrs goto yesno; 176163953Srrs case _SC_MONOTONIC_CLOCK: 177163953Srrs mib[0] = CTL_KERN; 178163953Srrs mib[1] = KERN_MONOTONIC_CLOCK; 179163953Srrs goto yesno; 180163953Srrs case _SC_SEMAPHORES: 181163953Srrs mib[0] = CTL_KERN; 182163953Srrs mib[1] = KERN_POSIX_SEMAPHORES; 183163953Srrs goto yesno; 184163953Srrs case _SC_TIMERS: 185163953Srrs mib[0] = CTL_KERN; 186163953Srrs mib[1] = KERN_POSIX_TIMERS; 187163953Srrs goto yesno; 188163953Srrs 189163953Srrs/* 1003.1c */ 190163953Srrs case _SC_LOGIN_NAME_MAX: 191163953Srrs mib[0] = CTL_KERN; 192163953Srrs mib[1] = KERN_LOGIN_NAME_MAX; 193163953Srrs break; 194163953Srrs case _SC_THREADS: 195163953Srrs mib[0] = CTL_KERN; 196165647Srrs mib[1] = KERN_POSIX_THREADS; 197163953Srrs goto yesno; 198165220Srrs 199165220Srrs/* 1003.1j */ 200163953Srrs case _SC_BARRIERS: 201163953Srrs mib[0] = CTL_KERN; 202163953Srrs mib[1] = KERN_POSIX_BARRIERS; 203163953Srrs goto yesno; 204163953Srrs case _SC_SPIN_LOCKS: 205163953Srrs mib[0] = CTL_KERN; 206163953Srrs mib[1] = KERN_POSIX_SPIN_LOCKS; 207167695Srrs goto yesno; 208163953Srrs /* Historical; Threads option in 1003.1-2001 */ 209163953Srrs case _SC_READER_WRITER_LOCKS: 210163953Srrs mib[0] = CTL_KERN; 211163953Srrs mib[1] = KERN_POSIX_READER_WRITER_LOCKS; 212163953Srrs goto yesno; 213163953Srrs 214163953Srrs/* 1003.2 */ 215163953Srrs case _SC_BC_BASE_MAX: 216163953Srrs mib[0] = CTL_USER; 217163953Srrs mib[1] = USER_BC_BASE_MAX; 218167695Srrs break; 219163953Srrs case _SC_BC_DIM_MAX: 220163953Srrs mib[0] = CTL_USER; 221163953Srrs mib[1] = USER_BC_DIM_MAX; 222163953Srrs break; 223163953Srrs case _SC_BC_SCALE_MAX: 224163953Srrs mib[0] = CTL_USER; 225163953Srrs mib[1] = USER_BC_SCALE_MAX; 226163953Srrs break; 227163953Srrs case _SC_BC_STRING_MAX: 228163953Srrs mib[0] = CTL_USER; 229163953Srrs mib[1] = USER_BC_STRING_MAX; 230163953Srrs break; 231163953Srrs case _SC_COLL_WEIGHTS_MAX: 232163953Srrs mib[0] = CTL_USER; 233163953Srrs mib[1] = USER_COLL_WEIGHTS_MAX; 234163953Srrs break; 235167695Srrs case _SC_EXPR_NEST_MAX: 236167695Srrs mib[0] = CTL_USER; 237167695Srrs mib[1] = USER_EXPR_NEST_MAX; 238163953Srrs break; 239167695Srrs case _SC_LINE_MAX: 240163953Srrs mib[0] = CTL_USER; 241163953Srrs mib[1] = USER_LINE_MAX; 242163953Srrs break; 243163953Srrs case _SC_RE_DUP_MAX: 244163953Srrs mib[0] = CTL_USER; 245163953Srrs mib[1] = USER_RE_DUP_MAX; 246163953Srrs break; 247167695Srrs case _SC_2_VERSION: 248163953Srrs mib[0] = CTL_USER; 249163953Srrs mib[1] = USER_POSIX2_VERSION; 250167598Srrs break; 251167598Srrs case _SC_2_C_BIND: 252167598Srrs mib[0] = CTL_USER; 253167598Srrs mib[1] = USER_POSIX2_C_BIND; 254167598Srrs goto yesno; 255163953Srrs case _SC_2_C_DEV: 256163953Srrs mib[0] = CTL_USER; 257163953Srrs mib[1] = USER_POSIX2_C_DEV; 258163953Srrs goto yesno; 259163953Srrs case _SC_2_CHAR_TERM: 260163953Srrs mib[0] = CTL_USER; 261163953Srrs mib[1] = USER_POSIX2_CHAR_TERM; 262163953Srrs goto yesno; 263163953Srrs case _SC_2_FORT_DEV: 264163953Srrs mib[0] = CTL_USER; 265163953Srrs mib[1] = USER_POSIX2_FORT_DEV; 266163953Srrs goto yesno; 267163953Srrs case _SC_2_FORT_RUN: 268163953Srrs mib[0] = CTL_USER; 269163953Srrs mib[1] = USER_POSIX2_FORT_RUN; 270163953Srrs goto yesno; 271163953Srrs case _SC_2_LOCALEDEF: 272163953Srrs mib[0] = CTL_USER; 273163953Srrs mib[1] = USER_POSIX2_LOCALEDEF; 274165220Srrs goto yesno; 275163953Srrs case _SC_2_SW_DEV: 276163953Srrs mib[0] = CTL_USER; 277163953Srrs mib[1] = USER_POSIX2_SW_DEV; 278163953Srrs goto yesno; 279163953Srrs case _SC_2_UPE: 280163953Srrs mib[0] = CTL_USER; 281163953Srrs mib[1] = USER_POSIX2_UPE; 282163953Srrs goto yesno; 283163953Srrs 284163953Srrs/* XPG 4.2 */ 285163953Srrs case _SC_IOV_MAX: 286163953Srrs mib[0] = CTL_KERN; 287163953Srrs mib[1] = KERN_IOV_MAX; 288167695Srrs break; 289163953Srrs case _SC_XOPEN_SHM: 290163953Srrs mib[0] = CTL_KERN; 291163953Srrs mib[1] = KERN_SYSVIPC; 292163953Srrs mib[2] = KERN_SYSVIPC_SHM; 293163953Srrs mib_len = 3; 294163953Srrs goto yesno; 295163953Srrs 296163953Srrs/* 1003.1-2001, XSI Option Group */ 297163953Srrs case _SC_AIO_LISTIO_MAX: 298163953Srrs if (sysctlgetmibinfo("kern.aio_listio_max", &mib[0], &mib_len, 299163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 300163953Srrs return -1; 301163953Srrs break; 302163953Srrs case _SC_AIO_MAX: 303167598Srrs if (sysctlgetmibinfo("kern.aio_max", &mib[0], &mib_len, 304163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 305167598Srrs return -1; 306163953Srrs break; 307163953Srrs case _SC_ASYNCHRONOUS_IO: 308163953Srrs if (sysctlgetmibinfo("kern.posix_aio", &mib[0], &mib_len, 309163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 310163953Srrs return -1; 311163953Srrs goto yesno; 312163953Srrs case _SC_MESSAGE_PASSING: 313163953Srrs if (sysctlgetmibinfo("kern.posix_msg", &mib[0], &mib_len, 314163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 315163953Srrs return -1; 316163953Srrs goto yesno; 317163953Srrs case _SC_MQ_OPEN_MAX: 318163953Srrs if (sysctlgetmibinfo("kern.mqueue.mq_open_max", &mib[0], 319163953Srrs &mib_len, NULL, NULL, NULL, SYSCTL_VERSION)) 320163953Srrs return -1; 321163953Srrs break; 322163953Srrs case _SC_MQ_PRIO_MAX: 323163953Srrs if (sysctlgetmibinfo("kern.mqueue.mq_prio_max", &mib[0], 324163953Srrs &mib_len, NULL, NULL, NULL, SYSCTL_VERSION)) 325163953Srrs return -1; 326163953Srrs break; 327163953Srrs case _SC_PRIORITY_SCHEDULING: 328163953Srrs if (sysctlgetmibinfo("kern.posix_sched", &mib[0], &mib_len, 329163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 330163953Srrs return -1; 331163953Srrs goto yesno; 332163953Srrs case _SC_ATEXIT_MAX: 333163953Srrs mib[0] = CTL_USER; 334163953Srrs mib[1] = USER_ATEXIT_MAX; 335163953Srrs break; 336163953Srrs 337163953Srrs/* 1003.1-2001, TSF */ 338167598Srrs case _SC_GETGR_R_SIZE_MAX: 339163953Srrs return _GETGR_R_SIZE_MAX; 340163953Srrs case _SC_GETPW_R_SIZE_MAX: 341163953Srrs return _GETPW_R_SIZE_MAX; 342163953Srrs 343163953Srrs/* Unsorted */ 344163953Srrs case _SC_RTSIG_MAX: 345163953Srrs return SIGRTMAX - SIGRTMIN; 346163953Srrs case _SC_HOST_NAME_MAX: 347163953Srrs return MAXHOSTNAMELEN; 348163953Srrs case _SC_PASS_MAX: 349163953Srrs return _PASSWORD_LEN; 350163953Srrs case _SC_REGEXP: 351163953Srrs return _POSIX_REGEXP; 352163953Srrs case _SC_SHARED_MEMORY_OBJECTS: 353163953Srrs return _POSIX_SHARED_MEMORY_OBJECTS; 354163953Srrs case _SC_SHELL: 355163953Srrs return _POSIX_SHELL; 356163953Srrs case _SC_SPAWN: 357163953Srrs return _POSIX_SPAWN; 358163953Srrs case _SC_SYMLOOP_MAX: 359163953Srrs return MAXSYMLINKS; 360163953Srrs 361163953Srrsyesno: if (sysctl(mib, mib_len, &value, &len, NULL, 0) == -1) 362163953Srrs return (-1); 363163953Srrs if (value == 0) 364163953Srrs return (-1); 365163953Srrs return (value); 366163953Srrs 367163953Srrs/* Extensions */ 368163953Srrs case _SC_NPROCESSORS_CONF: 369163953Srrs mib[0] = CTL_HW; 370164085Srrs mib[1] = HW_NCPU; 371163953Srrs break; 372163953Srrs case _SC_NPROCESSORS_ONLN: 373163953Srrs mib[0] = CTL_HW; 374163953Srrs mib[1] = HW_NCPUONLINE; 375164085Srrs break; 376167598Srrs 377163953Srrs/* Linux/Solaris */ 378167598Srrs case _SC_PHYS_PAGES: 379164039Srwatson len = sizeof(mem); 380164039Srwatson mib[0] = CTL_HW; 381164039Srwatson mib[1] = HW_PHYSMEM64; 382164039Srwatson return sysctl(mib, 2, &mem, &len, NULL, 0) == -1 ? -1 : 383164039Srwatson (long)(mem / _getpagesize()); 384167598Srrs 385167598Srrs case _SC_AVPHYS_PAGES: 386163953Srrs len = sizeof(uvmexp); 387163953Srrs mib[0] = CTL_VM; 388164039Srwatson mib[1] = VM_UVMEXP2; 389163953Srrs return sysctl(mib, 2, &uvmexp, &len, NULL, 0) == -1 ? -1 : 390163953Srrs (long)(uvmexp.free); 391163953Srrs 392163953Srrs/* Native */ 393163953Srrs case _SC_SCHED_RT_TS: 394163953Srrs if (sysctlgetmibinfo("kern.sched.rtts", &mib[0], &mib_len, 395167598Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 396163953Srrs return -1; 397163953Srrs break; 398163953Srrs case _SC_SCHED_PRI_MIN: 399163953Srrs if (sysctlgetmibinfo("kern.sched.pri_min", &mib[0], &mib_len, 400163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 401164085Srrs return -1; 402163953Srrs break; 403163953Srrs case _SC_SCHED_PRI_MAX: 404163953Srrs if (sysctlgetmibinfo("kern.sched.pri_max", &mib[0], &mib_len, 405163953Srrs NULL, NULL, NULL, SYSCTL_VERSION)) 406163953Srrs return -1; 407164085Srrs break; 408164085Srrs case _SC_THREAD_DESTRUCTOR_ITERATIONS: 409164085Srrs return _POSIX_THREAD_DESTRUCTOR_ITERATIONS; 410164085Srrs case _SC_THREAD_KEYS_MAX: 411164085Srrs return _POSIX_THREAD_KEYS_MAX; 412164085Srrs case _SC_THREAD_STACK_MIN: 413164085Srrs return _getpagesize(); 414164085Srrs case _SC_THREAD_THREADS_MAX: 415164085Srrs if (sysctlgetmibinfo("kern.maxproc", &mib[0], &mib_len, 416164085Srrs NULL, NULL, NULL, SYSCTL_VERSION)) /* XXX */ 417164085Srrs return -1; 418164085Srrs goto yesno; 419164085Srrs case _SC_THREAD_ATTR_STACKADDR: 420164085Srrs return _POSIX_THREAD_ATTR_STACKADDR; 421164085Srrs case _SC_THREAD_ATTR_STACKSIZE: 422164085Srrs return _POSIX_THREAD_ATTR_STACKSIZE; 423163953Srrs case _SC_THREAD_SAFE_FUNCTIONS: 424163953Srrs return _POSIX_THREAD_SAFE_FUNCTIONS; 425163953Srrs case _SC_THREAD_PRIO_PROTECT: 426163953Srrs return _POSIX_THREAD_PRIO_PROTECT; 427163953Srrs case _SC_THREAD_PRIORITY_SCHEDULING: 428163953Srrs case _SC_THREAD_PRIO_INHERIT: 429163953Srrs case _SC_THREAD_PROCESS_SHARED: 430163953Srrs return -1; 431163953Srrs case _SC_TTY_NAME_MAX: 432163953Srrs return pathconf(_PATH_DEV, _PC_NAME_MAX); 433163953Srrs case _SC_TIMER_MAX: 434163953Srrs return _POSIX_TIMER_MAX; 435163953Srrs case _SC_SEM_NSEMS_MAX: 436163953Srrs return LONG_MAX; 437163953Srrs case _SC_CPUTIME: 438163953Srrs return _POSIX_CPUTIME; 439163953Srrs case _SC_THREAD_CPUTIME: 440163953Srrs return _POSIX_THREAD_CPUTIME; 441163953Srrs case _SC_DELAYTIMER_MAX: 442163953Srrs return _POSIX_DELAYTIMER_MAX; 443163953Srrs case _SC_SIGQUEUE_MAX: 444163953Srrs return _POSIX_SIGQUEUE_MAX; 445163953Srrs case _SC_REALTIME_SIGNALS: 446163953Srrs return 200112L; 447163953Srrs default: 448163953Srrs errno = EINVAL; 449163953Srrs return (-1); 450163953Srrs } 451163953Srrs return (sysctl(mib, mib_len, &value, &len, NULL, 0) == -1 ? -1 : value); 452163953Srrs} 453167695Srrs