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 ( 8 "golang.org/x/sys/unix" 9) 10 11const ( 12 _HOST_NAME_MAX = _MAXHOSTNAMELEN - 1 13 _LOGIN_NAME_MAX = _MAXLOGNAME 14 _SYMLOOP_MAX = _MAXSYMLINKS 15) 16 17// sysconf implements sysconf(3) as in the Darwin libc, version 1244.30.3 18// (derived from the FreeBSD libc). 19func sysconf(name int) (int64, error) { 20 switch name { 21 case SC_AIO_LISTIO_MAX: 22 fallthrough 23 case SC_AIO_MAX: 24 return sysctl32("kern.aiomax"), nil 25 case SC_AIO_PRIO_DELTA_MAX: 26 return -1, nil 27 case SC_ARG_MAX: 28 return sysctl32("kern.argmax"), nil 29 case SC_ATEXIT_MAX: 30 return _INT_MAX, nil 31 case SC_CHILD_MAX: 32 var rlim unix.Rlimit 33 if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlim); err == nil { 34 if rlim.Cur != unix.RLIM_INFINITY { 35 return int64(rlim.Cur), nil 36 } 37 } 38 return -1, nil 39 case SC_CLK_TCK: 40 return _CLK_TCK, nil 41 case SC_DELAYTIMER_MAX: 42 return -1, nil 43 case SC_GETGR_R_SIZE_MAX: 44 return 4096, nil 45 case SC_GETPW_R_SIZE_MAX: 46 return 4096, nil 47 case SC_IOV_MAX: 48 return _IOV_MAX, nil 49 case SC_MQ_OPEN_MAX: 50 return -1, nil 51 case SC_MQ_PRIO_MAX: 52 return -1, nil 53 case SC_NGROUPS_MAX: 54 return sysctl32("kern.ngroups"), nil 55 case SC_OPEN_MAX, SC_STREAM_MAX: 56 var rlim unix.Rlimit 57 if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil { 58 if rlim.Cur != unix.RLIM_INFINITY { 59 return int64(rlim.Cur), nil 60 } 61 } 62 return -1, nil 63 case SC_RTSIG_MAX: 64 return -1, nil 65 case SC_SEM_NSEMS_MAX: 66 return sysctl32("kern.sysv.semmns"), nil 67 case SC_SEM_VALUE_MAX: 68 return _POSIX_SEM_VALUE_MAX, nil 69 case SC_SIGQUEUE_MAX: 70 return -1, nil 71 case SC_THREAD_DESTRUCTOR_ITERATIONS: 72 return _PTHREAD_DESTRUCTOR_ITERATIONS, nil 73 case SC_THREAD_KEYS_MAX: 74 return _PTHREAD_KEYS_MAX, nil 75 case SC_THREAD_PRIO_INHERIT: 76 return _POSIX_THREAD_PRIO_INHERIT, nil 77 case SC_THREAD_PRIO_PROTECT: 78 return _POSIX_THREAD_PRIO_PROTECT, nil 79 case SC_THREAD_STACK_MIN: 80 return _PTHREAD_STACK_MIN, nil 81 case SC_THREAD_THREADS_MAX: 82 return -1, nil 83 case SC_TIMER_MAX: 84 return -1, nil 85 case SC_TTY_NAME_MAX: 86 // should be _PATH_DEV instead of "/" 87 return pathconf("/", _PC_NAME_MAX), nil 88 case SC_TZNAME_MAX: 89 return pathconf(_PATH_ZONEINFO, _PC_NAME_MAX), nil 90 91 case SC_IPV6: 92 if _POSIX_IPV6 == 0 { 93 fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0) 94 if err == nil && fd >= 0 { 95 unix.Close(fd) 96 return int64(200112), nil 97 } 98 return 0, nil 99 } 100 return _POSIX_IPV6, nil 101 case SC_MESSAGE_PASSING: 102 if _POSIX_MESSAGE_PASSING == 0 { 103 return yesno(sysctl32("p1003_1b.message_passing")), nil 104 } 105 return _POSIX_MESSAGE_PASSING, nil 106 case SC_PRIORITIZED_IO: 107 if _POSIX_PRIORITIZED_IO == 0 { 108 return yesno(sysctl32("p1003_1b.prioritized_io")), nil 109 } 110 return _POSIX_PRIORITIZED_IO, nil 111 case SC_PRIORITY_SCHEDULING: 112 if _POSIX_PRIORITY_SCHEDULING == 0 { 113 return yesno(sysctl32("p1003_1b.priority_scheduling")), nil 114 } 115 return _POSIX_PRIORITY_SCHEDULING, nil 116 case SC_REALTIME_SIGNALS: 117 if _POSIX_REALTIME_SIGNALS == 0 { 118 return yesno(sysctl32("p1003_1b.realtime_signals")), nil 119 } 120 return _POSIX_REALTIME_SIGNALS, nil 121 case SC_SAVED_IDS: 122 return yesno(sysctl32("kern.saved_ids")), nil 123 case SC_SEMAPHORES: 124 if _POSIX_SEMAPHORES == 0 { 125 return yesno(sysctl32("p1003_1b.semaphores")), nil 126 } 127 return _POSIX_SEMAPHORES, nil 128 case SC_SPAWN: 129 return _POSIX_SPAWN, nil 130 case SC_SPIN_LOCKS: 131 return _POSIX_SPIN_LOCKS, nil 132 case SC_SPORADIC_SERVER: 133 return _POSIX_SPORADIC_SERVER, nil 134 case SC_SS_REPL_MAX: 135 return _POSIX_SS_REPL_MAX, nil 136 case SC_SYNCHRONIZED_IO: 137 if _POSIX_SYNCHRONIZED_IO == 0 { 138 return yesno(sysctl32("p1003_1b.synchronized_io")), nil 139 } 140 return _POSIX_SYNCHRONIZED_IO, nil 141 case SC_THREAD_ATTR_STACKADDR: 142 return _POSIX_THREAD_ATTR_STACKADDR, nil 143 case SC_THREAD_ATTR_STACKSIZE: 144 return _POSIX_THREAD_ATTR_STACKSIZE, nil 145 case SC_THREAD_CPUTIME: 146 return _POSIX_THREAD_CPUTIME, nil 147 case SC_THREAD_PRIORITY_SCHEDULING: 148 return _POSIX_THREAD_PRIORITY_SCHEDULING, nil 149 case SC_THREAD_PROCESS_SHARED: 150 return _POSIX_THREAD_PROCESS_SHARED, nil 151 case SC_THREAD_SAFE_FUNCTIONS: 152 return _POSIX_THREAD_SAFE_FUNCTIONS, nil 153 case SC_THREAD_SPORADIC_SERVER: 154 return _POSIX_THREAD_SPORADIC_SERVER, nil 155 case SC_TIMERS: 156 if _POSIX_TIMERS == 0 { 157 return yesno(sysctl32("p1003_1b.timers")), nil 158 } 159 return _POSIX_TIMERS, nil 160 case SC_TRACE: 161 return _POSIX_TRACE, nil 162 case SC_TRACE_EVENT_FILTER: 163 return _POSIX_TRACE_EVENT_FILTER, nil 164 case SC_TRACE_EVENT_NAME_MAX: 165 return _POSIX_TRACE_EVENT_NAME_MAX, nil 166 case SC_TRACE_INHERIT: 167 return _POSIX_TRACE_INHERIT, nil 168 case SC_TRACE_LOG: 169 return _POSIX_TRACE_LOG, nil 170 case SC_TRACE_NAME_MAX: 171 return _POSIX_TRACE_NAME_MAX, nil 172 case SC_TRACE_SYS_MAX: 173 return _POSIX_TRACE_SYS_MAX, nil 174 case SC_TRACE_USER_EVENT_MAX: 175 return _POSIX_TRACE_USER_EVENT_MAX, nil 176 case SC_TYPED_MEMORY_OBJECTS: 177 return _POSIX_TYPED_MEMORY_OBJECTS, nil 178 case SC_VERSION: 179 // TODO(tk): darwin libc uses sysctl(CTL_KERN, KERN_POSIX1) 180 return _POSIX_VERSION, nil 181 182 case SC_V6_ILP32_OFF32: 183 if _V6_ILP32_OFF32 == 0 { 184 if unix.SizeofInt*_CHAR_BIT == 32 && 185 unix.SizeofInt == unix.SizeofLong && 186 unix.SizeofLong == unix.SizeofPtr && 187 unix.SizeofPtr == sizeofOffT { 188 return 1, nil 189 } 190 return -1, nil 191 } 192 return _V6_ILP32_OFF32, nil 193 case SC_V6_ILP32_OFFBIG: 194 if _V6_ILP32_OFFBIG == 0 { 195 if unix.SizeofInt*_CHAR_BIT == 32 && 196 unix.SizeofInt == unix.SizeofLong && 197 unix.SizeofLong == unix.SizeofPtr && 198 sizeofOffT*_CHAR_BIT >= 64 { 199 return 1, nil 200 } 201 return -1, nil 202 } 203 return _V6_ILP32_OFFBIG, nil 204 case SC_V6_LP64_OFF64: 205 if _V6_LP64_OFF64 == 0 { 206 if unix.SizeofInt*_CHAR_BIT == 32 && 207 unix.SizeofLong*_CHAR_BIT == 64 && 208 unix.SizeofLong == unix.SizeofPtr && 209 unix.SizeofPtr == sizeofOffT { 210 return 1, nil 211 } 212 return -1, nil 213 } 214 return _V6_LP64_OFF64, nil 215 case SC_V6_LPBIG_OFFBIG: 216 if _V6_LPBIG_OFFBIG == 0 { 217 if unix.SizeofInt*_CHAR_BIT >= 32 && 218 unix.SizeofLong*_CHAR_BIT >= 64 && 219 unix.SizeofPtr*_CHAR_BIT >= 64 && 220 sizeofOffT*_CHAR_BIT >= 64 { 221 return 1, nil 222 } 223 return -1, nil 224 } 225 return _V6_LPBIG_OFFBIG, nil 226 227 case SC_2_CHAR_TERM: 228 return _POSIX2_CHAR_TERM, nil 229 case SC_2_PBS, 230 SC_2_PBS_ACCOUNTING, 231 SC_2_PBS_CHECKPOINT, 232 SC_2_PBS_LOCATE, 233 SC_2_PBS_MESSAGE, 234 SC_2_PBS_TRACK: 235 return _POSIX2_PBS, nil 236 case SC_2_UPE: 237 return _POSIX2_UPE, nil 238 239 case SC_XOPEN_CRYPT: 240 return _XOPEN_CRYPT, nil 241 case SC_XOPEN_ENH_I18N: 242 return _XOPEN_ENH_I18N, nil 243 case SC_XOPEN_REALTIME: 244 return _XOPEN_REALTIME, nil 245 case SC_XOPEN_REALTIME_THREADS: 246 return _XOPEN_REALTIME_THREADS, nil 247 case SC_XOPEN_SHM: 248 return _XOPEN_SHM, nil 249 case SC_XOPEN_STREAMS: 250 return -1, nil 251 case SC_XOPEN_UNIX: 252 return _XOPEN_UNIX, nil 253 case SC_XOPEN_VERSION: 254 return _XOPEN_VERSION, nil 255 case SC_XOPEN_XCU_VERSION: 256 return _XOPEN_XCU_VERSION, nil 257 258 case SC_PHYS_PAGES: 259 return sysctl64("hw.memsize") / int64(unix.Getpagesize()), nil 260 case SC_NPROCESSORS_CONF: 261 fallthrough 262 case SC_NPROCESSORS_ONLN: 263 return sysctl32("hw.ncpu"), nil 264 } 265 266 return sysconfGeneric(name) 267} 268