1// Copyright 2018 Tobias Klauser. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package sysconf 6 7import "golang.org/x/sys/unix" 8 9// sysconf implements sysconf(3) as in the OpenBSD 6.3 libc. 10func sysconf(name int) (int64, error) { 11 switch name { 12 case SC_AIO_LISTIO_MAX, 13 SC_AIO_MAX, 14 SC_AIO_PRIO_DELTA_MAX: 15 return -1, nil 16 case SC_ARG_MAX: 17 return sysctl32("kern.argmax"), nil 18 case SC_ATEXIT_MAX: 19 return -1, nil 20 case SC_CHILD_MAX: 21 var rlim unix.Rlimit 22 if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlim); err == nil { 23 if rlim.Cur != unix.RLIM_INFINITY { 24 return int64(rlim.Cur), nil 25 } 26 } 27 return -1, nil 28 case SC_CLK_TCK: 29 return _CLK_TCK, nil 30 case SC_DELAYTIMER_MAX: 31 return -1, nil 32 case SC_GETGR_R_SIZE_MAX: 33 return _GR_BUF_LEN, nil 34 case SC_GETPW_R_SIZE_MAX: 35 return _PW_BUF_LEN, nil 36 case SC_IOV_MAX: 37 return _IOV_MAX, nil 38 case SC_LOGIN_NAME_MAX: 39 return _LOGIN_NAME_MAX, nil 40 case SC_NGROUPS_MAX: 41 return sysctl32("kern.ngroups"), nil 42 case SC_OPEN_MAX: 43 var rlim unix.Rlimit 44 if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil { 45 if rlim.Cur != unix.RLIM_INFINITY { 46 return int64(rlim.Cur), nil 47 } 48 } 49 return -1, nil 50 case SC_SEM_NSEMS_MAX: 51 return -1, nil 52 case SC_SEM_VALUE_MAX: 53 return _SEM_VALUE_MAX, nil 54 case SC_SIGQUEUE_MAX: 55 return -1, nil 56 case SC_STREAM_MAX: 57 var rlim unix.Rlimit 58 if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil { 59 if rlim.Cur != unix.RLIM_INFINITY { 60 if rlim.Cur > _SHRT_MAX { 61 return _SHRT_MAX, nil 62 } 63 return int64(rlim.Cur), nil 64 } 65 } 66 return -1, nil 67 case SC_THREAD_DESTRUCTOR_ITERATIONS: 68 return _PTHREAD_DESTRUCTOR_ITERATIONS, nil 69 case SC_THREAD_KEYS_MAX: 70 return _PTHREAD_KEYS_MAX, nil 71 case SC_THREAD_STACK_MIN: 72 return _PTHREAD_STACK_MIN, nil 73 case SC_THREAD_THREADS_MAX: 74 return -1, nil 75 case SC_TIMER_MAX: 76 return -1, nil 77 case SC_TTY_NAME_MAX: 78 return _TTY_NAME_MAX, nil 79 case SC_TZNAME_MAX: 80 return _NAME_MAX, nil 81 82 case SC_BARRIERS: 83 return _POSIX_BARRIERS, nil 84 case SC_FSYNC: 85 return _POSIX_FSYNC, nil 86 case SC_IPV6: 87 if _POSIX_IPV6 == 0 { 88 fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0) 89 if err == nil && fd >= 0 { 90 unix.Close(fd) 91 return int64(200112), nil 92 } 93 return 0, nil 94 } 95 return _POSIX_IPV6, nil 96 case SC_JOB_CONTROL: 97 return _POSIX_JOB_CONTROL, nil 98 case SC_MAPPED_FILES: 99 return _POSIX_MAPPED_FILES, nil 100 case SC_MONOTONIC_CLOCK: 101 return _POSIX_MONOTONIC_CLOCK, nil 102 case SC_SAVED_IDS: 103 return _POSIX_SAVED_IDS, nil 104 case SC_SEMAPHORES: 105 return _POSIX_SEMAPHORES, nil 106 case SC_SPAWN: 107 return _POSIX_SPAWN, nil 108 case SC_SPIN_LOCKS: 109 return _POSIX_SPIN_LOCKS, nil 110 case SC_SPORADIC_SERVER: 111 return _POSIX_SPORADIC_SERVER, nil 112 case SC_SYNCHRONIZED_IO: 113 return _POSIX_SYNCHRONIZED_IO, nil 114 case SC_THREAD_ATTR_STACKADDR: 115 return _POSIX_THREAD_ATTR_STACKADDR, nil 116 case SC_THREAD_ATTR_STACKSIZE: 117 return _POSIX_THREAD_ATTR_STACKSIZE, nil 118 case SC_THREAD_CPUTIME: 119 return _POSIX_THREAD_CPUTIME, nil 120 case SC_THREAD_PRIO_INHERIT: 121 return _POSIX_THREAD_PRIO_INHERIT, nil 122 case SC_THREAD_PRIO_PROTECT: 123 return _POSIX_THREAD_PRIO_PROTECT, nil 124 case SC_THREAD_PRIORITY_SCHEDULING: 125 return _POSIX_THREAD_PRIORITY_SCHEDULING, nil 126 case SC_THREAD_PROCESS_SHARED: 127 return _POSIX_THREAD_PROCESS_SHARED, nil 128 case SC_THREAD_ROBUST_PRIO_INHERIT: 129 return _POSIX_THREAD_ROBUST_PRIO_INHERIT, nil 130 case SC_THREAD_ROBUST_PRIO_PROTECT: 131 return _POSIX_THREAD_ROBUST_PRIO_PROTECT, nil 132 case SC_THREAD_SAFE_FUNCTIONS: 133 return _POSIX_THREAD_SAFE_FUNCTIONS, nil 134 case SC_THREAD_SPORADIC_SERVER: 135 return _POSIX_THREAD_SPORADIC_SERVER, nil 136 case SC_THREADS: 137 return _POSIX_THREADS, nil 138 case SC_TIMEOUTS: 139 return _POSIX_TIMEOUTS, nil 140 case SC_TIMERS: 141 return _POSIX_TIMERS, nil 142 case SC_TRACE, 143 SC_TRACE_EVENT_FILTER, 144 SC_TRACE_EVENT_NAME_MAX, 145 SC_TRACE_INHERIT, 146 SC_TRACE_LOG: 147 return _POSIX_TRACE, nil 148 case SC_TYPED_MEMORY_OBJECTS: 149 return _POSIX_TYPED_MEMORY_OBJECTS, nil 150 151 case SC_V7_ILP32_OFF32: 152 return _POSIX_V7_ILP32_OFF32, nil 153 case SC_V7_ILP32_OFFBIG: 154 if _POSIX_V7_ILP32_OFFBIG == 0 { 155 if unix.SizeofInt*_CHAR_BIT == 32 && 156 unix.SizeofLong*_CHAR_BIT == 32 && 157 unix.SizeofPtr*_CHAR_BIT == 32 && 158 sizeofOffT*_CHAR_BIT >= 64 { 159 return 1, nil 160 } 161 return -1, nil 162 } 163 return _POSIX_V7_ILP32_OFFBIG, nil 164 case SC_V7_LP64_OFF64: 165 if _POSIX_V7_LP64_OFF64 == 0 { 166 if unix.SizeofInt*_CHAR_BIT == 32 && 167 unix.SizeofLong*_CHAR_BIT == 64 && 168 unix.SizeofPtr*_CHAR_BIT == 64 && 169 sizeofOffT*_CHAR_BIT == 64 { 170 return 1, nil 171 } 172 return -1, nil 173 } 174 return _POSIX_V7_LP64_OFF64, nil 175 case SC_V7_LPBIG_OFFBIG: 176 if _POSIX_V7_LPBIG_OFFBIG == 0 { 177 if unix.SizeofInt*_CHAR_BIT >= 32 && 178 unix.SizeofLong*_CHAR_BIT >= 64 && 179 unix.SizeofPtr*_CHAR_BIT >= 64 && 180 sizeofOffT*_CHAR_BIT >= 64 { 181 return 1, nil 182 } 183 return -1, nil 184 } 185 return _POSIX_V7_LPBIG_OFFBIG, nil 186 187 case SC_V6_ILP32_OFF32: 188 return _POSIX_V6_ILP32_OFF32, nil 189 case SC_V6_ILP32_OFFBIG: 190 if _POSIX_V6_ILP32_OFFBIG == 0 { 191 if unix.SizeofInt*_CHAR_BIT == 32 && 192 unix.SizeofLong*_CHAR_BIT == 32 && 193 unix.SizeofPtr*_CHAR_BIT == 32 && 194 sizeofOffT*_CHAR_BIT >= 64 { 195 return 1, nil 196 } 197 return -1, nil 198 } 199 return _POSIX_V6_ILP32_OFFBIG, nil 200 case SC_V6_LP64_OFF64: 201 if _POSIX_V6_LP64_OFF64 == 0 { 202 if unix.SizeofInt*_CHAR_BIT == 32 && 203 unix.SizeofLong*_CHAR_BIT == 64 && 204 unix.SizeofPtr*_CHAR_BIT == 64 && 205 sizeofOffT*_CHAR_BIT == 64 { 206 return 1, nil 207 } 208 return -1, nil 209 } 210 return _POSIX_V6_LP64_OFF64, nil 211 case SC_V6_LPBIG_OFFBIG: 212 if _POSIX_V6_LPBIG_OFFBIG == 0 { 213 if unix.SizeofInt*_CHAR_BIT >= 32 && 214 unix.SizeofLong*_CHAR_BIT >= 64 && 215 unix.SizeofPtr*_CHAR_BIT >= 64 && 216 sizeofOffT*_CHAR_BIT >= 64 { 217 return 1, nil 218 } 219 return -1, nil 220 } 221 return _POSIX_V6_LPBIG_OFFBIG, nil 222 223 case SC_2_CHAR_TERM: 224 return _POSIX2_CHAR_TERM, nil 225 case SC_2_PBS, 226 SC_2_PBS_ACCOUNTING, 227 SC_2_PBS_CHECKPOINT, 228 SC_2_PBS_LOCATE, 229 SC_2_PBS_MESSAGE, 230 SC_2_PBS_TRACK: 231 return _POSIX2_PBS, nil 232 case SC_2_UPE: 233 return _POSIX2_UPE, nil 234 case SC_2_VERSION: 235 return _POSIX2_VERSION, nil 236 237 case SC_XOPEN_CRYPT: 238 return _XOPEN_CRYPT, nil 239 case SC_XOPEN_ENH_I18N: 240 return _XOPEN_ENH_I18N, nil 241 case SC_XOPEN_REALTIME: 242 return _XOPEN_REALTIME, nil 243 case SC_XOPEN_REALTIME_THREADS: 244 return _XOPEN_REALTIME_THREADS, nil 245 case SC_XOPEN_SHM: 246 return _XOPEN_SHM, nil 247 case SC_XOPEN_STREAMS: 248 return _XOPEN_STREAMS, nil 249 case SC_XOPEN_UNIX: 250 return _XOPEN_UNIX, nil 251 case SC_XOPEN_UUCP: 252 return _XOPEN_UUCP, nil 253 254 case SC_AVPHYS_PAGES: 255 if uvm, err := unix.SysctlUvmexp("vm.uvmexp"); err == nil { 256 return int64(uvm.Free), nil 257 } 258 return -1, nil 259 case SC_PHYS_PAGES: 260 return sysctl64("hw.physmem") / int64(unix.Getpagesize()), nil 261 case SC_NPROCESSORS_CONF: 262 return sysctl32("hw.ncpu"), nil 263 case SC_NPROCESSORS_ONLN: 264 if val, err := unix.SysctlUint32("hw.ncpuonline"); err == nil { 265 return int64(val), nil 266 } 267 return sysctl32("hw.ncpu"), nil 268 } 269 270 return sysconfGeneric(name) 271} 272