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 9const ( 10 _HOST_NAME_MAX = _MAXHOSTNAMELEN - 1 11 _LOGIN_NAME_MAX = _MAXLOGNAME 12 _SYMLOOP_MAX = _MAXSYMLINKS 13) 14 15// sysconf implements sysconf(3) as in the FreeBSD 12 libc. 16func sysconf(name int) (int64, error) { 17 switch name { 18 case SC_AIO_LISTIO_MAX: 19 return sysctl32("p1003_1b.aio_listio_max"), nil 20 case SC_AIO_MAX: 21 return sysctl32("p1003_1b.aio_max"), nil 22 case SC_AIO_PRIO_DELTA_MAX: 23 return sysctl32("p1003_1b.aio_prio_delta_max"), nil 24 case SC_ARG_MAX: 25 return sysctl32("kern.argmax"), nil 26 case SC_ATEXIT_MAX: 27 return _ATEXIT_SIZE, nil 28 case SC_CHILD_MAX: 29 var rlim unix.Rlimit 30 if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlim); err == nil { 31 if rlim.Cur != unix.RLIM_INFINITY { 32 return rlim.Cur, nil 33 } 34 } 35 return -1, nil 36 case SC_CLK_TCK: 37 return _CLK_TCK, nil 38 case SC_DELAYTIMER_MAX: 39 return sysctl32("p1003_1b.delaytimer_max"), nil 40 case SC_GETGR_R_SIZE_MAX, SC_GETPW_R_SIZE_MAX: 41 return -1, nil 42 case SC_IOV_MAX: 43 return sysctl32("kern.iov_max"), nil 44 case SC_MQ_OPEN_MAX: 45 return yesno(sysctl32("p1003_1b.mq_open_max")), nil 46 case SC_MQ_PRIO_MAX: 47 return _MQ_PRIO_MAX, nil 48 case SC_NGROUPS_MAX: 49 return sysctl32("kern.ngroups"), nil 50 case SC_OPEN_MAX: 51 var rlim unix.Rlimit 52 if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil { 53 if rlim.Cur != unix.RLIM_INFINITY { 54 return rlim.Cur, nil 55 } 56 } 57 return -1, nil 58 case SC_RTSIG_MAX: 59 return sysctl32("p1003_1b.rtsig_max"), nil 60 case SC_SEM_NSEMS_MAX: 61 return -1, nil 62 case SC_SEM_VALUE_MAX: 63 return _SEM_VALUE_MAX, nil 64 case SC_SIGQUEUE_MAX: 65 return sysctl32("p1003_1b.sigqueue_max"), nil 66 case SC_STREAM_MAX: 67 var rlim unix.Rlimit 68 if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err != nil { 69 return -1, nil 70 } 71 if rlim.Cur == unix.RLIM_INFINITY { 72 return -1, nil 73 } 74 if rlim.Cur > _LONG_MAX { 75 return -1, unix.EOVERFLOW 76 } 77 if rlim.Cur > _SHRT_MAX { 78 return _SHRT_MAX, nil 79 } 80 return rlim.Cur, nil 81 case SC_THREAD_DESTRUCTOR_ITERATIONS: 82 return _PTHREAD_DESTRUCTOR_ITERATIONS, nil 83 case SC_THREAD_KEYS_MAX: 84 return _PTHREAD_KEYS_MAX, nil 85 case SC_THREAD_PRIO_INHERIT: 86 return _POSIX_THREAD_PRIO_INHERIT, nil 87 case SC_THREAD_PRIO_PROTECT: 88 return _POSIX_THREAD_PRIO_PROTECT, nil 89 case SC_THREAD_STACK_MIN: 90 return _PTHREAD_STACK_MIN, nil 91 case SC_THREAD_THREADS_MAX: 92 return -1, nil 93 case SC_TIMER_MAX: 94 return yesno(sysctl32("p1003_1b.timer_max")), nil 95 case SC_TTY_NAME_MAX: 96 return pathconf(_PATH_DEV, _PC_NAME_MAX), nil 97 case SC_TZNAME_MAX: 98 return pathconf(_PATH_ZONEINFO, _PC_NAME_MAX), nil 99 100 case SC_IPV6: 101 if _POSIX_IPV6 == 0 { 102 fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0) 103 if err == nil && fd >= 0 { 104 unix.Close(fd) 105 return int64(200112), nil 106 } 107 return 0, nil 108 } 109 return _POSIX_IPV6, nil 110 case SC_MESSAGE_PASSING: 111 if _POSIX_MESSAGE_PASSING == 0 { 112 return yesno(sysctl32("p1003_1b.message_passing")), nil 113 } 114 return _POSIX_MESSAGE_PASSING, nil 115 case SC_PRIORITIZED_IO: 116 if _POSIX_PRIORITIZED_IO == 0 { 117 return yesno(sysctl32("p1003_1b.prioritized_io")), nil 118 } 119 return _POSIX_PRIORITIZED_IO, nil 120 case SC_PRIORITY_SCHEDULING: 121 if _POSIX_PRIORITY_SCHEDULING == 0 { 122 return yesno(sysctl32("p1003_1b.priority_scheduling")), nil 123 } 124 return _POSIX_PRIORITY_SCHEDULING, nil 125 case SC_REALTIME_SIGNALS: 126 if _POSIX_REALTIME_SIGNALS == 0 { 127 return yesno(sysctl32("p1003_1b.realtime_signals")), nil 128 } 129 return _POSIX_REALTIME_SIGNALS, nil 130 case SC_SAVED_IDS: 131 return yesno(sysctl32("kern.saved_ids")), nil 132 case SC_SEMAPHORES: 133 if _POSIX_SEMAPHORES == 0 { 134 return yesno(sysctl32("p1003_1b.semaphores")), nil 135 } 136 return _POSIX_SEMAPHORES, nil 137 case SC_SPAWN: 138 return _POSIX_SPAWN, nil 139 case SC_SPIN_LOCKS: 140 return _POSIX_SPIN_LOCKS, nil 141 case SC_SPORADIC_SERVER: 142 return _POSIX_SPORADIC_SERVER, nil 143 case SC_SYNCHRONIZED_IO: 144 if _POSIX_SYNCHRONIZED_IO == 0 { 145 return yesno(sysctl32("p1003_1b.synchronized_io")), nil 146 } 147 return _POSIX_SYNCHRONIZED_IO, nil 148 case SC_THREAD_ATTR_STACKADDR: 149 return _POSIX_THREAD_ATTR_STACKADDR, nil 150 case SC_THREAD_ATTR_STACKSIZE: 151 return _POSIX_THREAD_ATTR_STACKSIZE, nil 152 case SC_THREAD_CPUTIME: 153 return _POSIX_THREAD_CPUTIME, nil 154 case SC_THREAD_PRIORITY_SCHEDULING: 155 return _POSIX_THREAD_PRIORITY_SCHEDULING, nil 156 case SC_THREAD_PROCESS_SHARED: 157 return _POSIX_THREAD_PROCESS_SHARED, nil 158 case SC_THREAD_SAFE_FUNCTIONS: 159 return _POSIX_THREAD_SAFE_FUNCTIONS, nil 160 case SC_TIMERS: 161 if _POSIX_TIMERS == 0 { 162 return yesno(sysctl32("p1003_1b.timers")), nil 163 } 164 return _POSIX_TIMERS, nil 165 case SC_TRACE: 166 return _POSIX_TRACE, nil 167 case SC_TYPED_MEMORY_OBJECTS: 168 return _POSIX_TYPED_MEMORY_OBJECTS, nil 169 case SC_VERSION: 170 // TODO(tk): FreeBSD libc uses sysctl(CTL_KERN, KERN_POSIX1) 171 return _POSIX_VERSION, nil 172 173 /* TODO(tk): these need GOARCH-dependent integer size checks 174 case SC_V6_ILP32_OFF32: 175 return _V6_ILP32_OFF32, nil 176 case SC_V6_ILP32_OFFBIG: 177 return _V6_ILP32_OFFBIG, nil 178 case SC_V6_LP64_OFF64: 179 return _V6_LP64_OFF64, nil 180 case SC_V6_LPBIG_OFFBIG: 181 return _V6_LPBIG_OFFBIG, nil 182 */ 183 184 case SC_2_CHAR_TERM: 185 return _POSIX2_CHAR_TERM, nil 186 case SC_2_PBS, 187 SC_2_PBS_ACCOUNTING, 188 SC_2_PBS_CHECKPOINT, 189 SC_2_PBS_LOCATE, 190 SC_2_PBS_MESSAGE, 191 SC_2_PBS_TRACK: 192 return _POSIX2_PBS, nil 193 case SC_2_UPE: 194 return _POSIX2_UPE, nil 195 196 case SC_XOPEN_CRYPT: 197 return _XOPEN_CRYPT, nil 198 case SC_XOPEN_ENH_I18N: 199 return _XOPEN_ENH_I18N, nil 200 case SC_XOPEN_REALTIME: 201 return _XOPEN_REALTIME, nil 202 case SC_XOPEN_REALTIME_THREADS: 203 return _XOPEN_REALTIME_THREADS, nil 204 case SC_XOPEN_SHM: 205 return _XOPEN_SHM, nil 206 case SC_XOPEN_STREAMS: 207 return -1, nil 208 case SC_XOPEN_UNIX: 209 return _XOPEN_UNIX, nil 210 211 case SC_PHYS_PAGES: 212 if val, err := unix.SysctlUint64("hw.availpages"); err == nil { 213 return int64(val), nil 214 } 215 return -1, nil 216 case SC_NPROCESSORS_CONF: 217 fallthrough 218 case SC_NPROCESSORS_ONLN: 219 if val, err := unix.SysctlUint32("hw.ncpu"); err == nil { 220 return int64(val), nil 221 } 222 return -1, nil 223 } 224 225 return sysconfGeneric(name) 226} 227