1 // Copyright 2009 The Go Authors. 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 5 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package syscall 8 9 import ( 10 "internal/oserror" 11 "internal/race" 12 "runtime" 13 "sync" 14 "unsafe" 15 ) 16 17 var ( 18 Stdin = 0 19 Stdout = 1 20 Stderr = 2 21 ) 22 23 const ( 24 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 25 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 26 ) 27 28 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 29 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 30 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 31 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 32 33 // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. 34 func clen(n []byte) int { 35 for i := 0; i < len(n); i++ { 36 if n[i] == 0 { 37 return i 38 } 39 } 40 return len(n) 41 } 42 43 // Mmap manager, for use by operating system-specific implementations. 44 45 type mmapper struct { 46 sync.Mutex 47 active map[*byte][]byte // active mappings; key is last byte in mapping 48 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error) 49 munmap func(addr uintptr, length uintptr) error 50 } 51 52 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 53 if length <= 0 { 54 return nil, EINVAL 55 } 56 57 // Map the requested memory. 58 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset) 59 if errno != nil { 60 return nil, errno 61 } 62 63 // Slice memory layout 64 var sl = struct { 65 addr uintptr 66 len int 67 cap int 68 }{addr, length, length} 69 70 // Use unsafe to turn sl into a []byte. 71 b := *(*[]byte)(unsafe.Pointer(&sl)) 72 73 // Register mapping in m and return it. 74 p := &b[cap(b)-1] 75 m.Lock() 76 defer m.Unlock() 77 m.active[p] = b 78 return b, nil 79 } 80 81 func (m *mmapper) Munmap(data []byte) (err error) { 82 if len(data) == 0 || len(data) != cap(data) { 83 return EINVAL 84 } 85 86 // Find the base of the mapping. 87 p := &data[cap(data)-1] 88 m.Lock() 89 defer m.Unlock() 90 b := m.active[p] 91 if b == nil || &b[0] != &data[0] { 92 return EINVAL 93 } 94 95 // Unmap the memory and update m. 96 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil { 97 return errno 98 } 99 delete(m.active, p) 100 return nil 101 } 102 103 // An Errno is an unsigned number describing an error condition. 104 // It implements the error interface. The zero Errno is by convention 105 // a non-error, so code to convert from Errno to error should use: 106 // err = nil 107 // if errno != 0 { 108 // err = errno 109 // } 110 type Errno uintptr 111 112 func (e Errno) Error() string { 113 if 0 <= int(e) && int(e) < len(errors) { 114 s := errors[e] 115 if s != "" { 116 return s 117 } 118 } 119 return "errno " + itoa(int(e)) 120 } 121 122 func (e Errno) Is(target error) bool { 123 switch target { 124 case oserror.ErrPermission: 125 return e == EACCES || e == EPERM 126 case oserror.ErrExist: 127 return e == EEXIST || e == ENOTEMPTY 128 case oserror.ErrNotExist: 129 return e == ENOENT 130 } 131 return false 132 } 133 134 func (e Errno) Temporary() bool { 135 return e == EINTR || e == EMFILE || e.Timeout() 136 } 137 138 func (e Errno) Timeout() bool { 139 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT 140 } 141 142 // Do the interface allocations only once for common 143 // Errno values. 144 var ( 145 errEAGAIN error = EAGAIN 146 errEINVAL error = EINVAL 147 errENOENT error = ENOENT 148 ) 149 150 // errnoErr returns common boxed Errno values, to prevent 151 // allocations at runtime. 152 func errnoErr(e Errno) error { 153 switch e { 154 case 0: 155 return nil 156 case EAGAIN: 157 return errEAGAIN 158 case EINVAL: 159 return errEINVAL 160 case ENOENT: 161 return errENOENT 162 } 163 return e 164 } 165 166 // A Signal is a number describing a process signal. 167 // It implements the os.Signal interface. 168 type Signal int 169 170 func (s Signal) Signal() {} 171 172 func (s Signal) String() string { 173 if 0 <= s && int(s) < len(signals) { 174 str := signals[s] 175 if str != "" { 176 return str 177 } 178 } 179 return "signal " + itoa(int(s)) 180 } 181 182 func Read(fd int, p []byte) (n int, err error) { 183 n, err = read(fd, p) 184 if race.Enabled { 185 if n > 0 { 186 race.WriteRange(unsafe.Pointer(&p[0]), n) 187 } 188 if err == nil { 189 race.Acquire(unsafe.Pointer(&ioSync)) 190 } 191 } 192 if msanenabled && n > 0 { 193 msanWrite(unsafe.Pointer(&p[0]), n) 194 } 195 return 196 } 197 198 func Write(fd int, p []byte) (n int, err error) { 199 if race.Enabled { 200 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 201 } 202 n, err = write(fd, p) 203 if race.Enabled && n > 0 { 204 race.ReadRange(unsafe.Pointer(&p[0]), n) 205 } 206 if msanenabled && n > 0 { 207 msanRead(unsafe.Pointer(&p[0]), n) 208 } 209 return 210 } 211 212 // For testing: clients can set this flag to force 213 // creation of IPv6 sockets to return EAFNOSUPPORT. 214 var SocketDisableIPv6 bool 215 216 type Sockaddr interface { 217 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs 218 } 219 220 type SockaddrInet4 struct { 221 Port int 222 Addr [4]byte 223 raw RawSockaddrInet4 224 } 225 226 type SockaddrInet6 struct { 227 Port int 228 ZoneId uint32 229 Addr [16]byte 230 raw RawSockaddrInet6 231 } 232 233 type SockaddrUnix struct { 234 Name string 235 raw RawSockaddrUnix 236 } 237 238 func Bind(fd int, sa Sockaddr) (err error) { 239 ptr, n, err := sa.sockaddr() 240 if err != nil { 241 return err 242 } 243 return bind(fd, ptr, n) 244 } 245 246 func Connect(fd int, sa Sockaddr) (err error) { 247 ptr, n, err := sa.sockaddr() 248 if err != nil { 249 return err 250 } 251 return connect(fd, ptr, n) 252 } 253 254 func Getpeername(fd int) (sa Sockaddr, err error) { 255 var rsa RawSockaddrAny 256 var len _Socklen = SizeofSockaddrAny 257 if err = getpeername(fd, &rsa, &len); err != nil { 258 return 259 } 260 return anyToSockaddr(&rsa) 261 } 262 263 func GetsockoptInt(fd, level, opt int) (value int, err error) { 264 var n int32 265 vallen := _Socklen(4) 266 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 267 return int(n), err 268 } 269 270 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 271 var rsa RawSockaddrAny 272 var len _Socklen = SizeofSockaddrAny 273 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 274 return 275 } 276 if rsa.Addr.Family != AF_UNSPEC { 277 from, err = anyToSockaddr(&rsa) 278 } 279 return 280 } 281 282 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 283 ptr, n, err := to.sockaddr() 284 if err != nil { 285 return err 286 } 287 return sendto(fd, p, flags, ptr, n) 288 } 289 290 func SetsockoptByte(fd, level, opt int, value byte) (err error) { 291 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) 292 } 293 294 func SetsockoptInt(fd, level, opt int, value int) (err error) { 295 var n = int32(value) 296 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4) 297 } 298 299 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 300 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4) 301 } 302 303 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 304 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq) 305 } 306 307 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 308 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq) 309 } 310 311 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { 312 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter) 313 } 314 315 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 316 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) 317 } 318 319 func SetsockoptString(fd, level, opt int, s string) (err error) { 320 var p unsafe.Pointer 321 if len(s) > 0 { 322 p = unsafe.Pointer(&[]byte(s)[0]) 323 } 324 return setsockopt(fd, level, opt, p, uintptr(len(s))) 325 } 326 327 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 328 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) 329 } 330 331 func Socket(domain, typ, proto int) (fd int, err error) { 332 if domain == AF_INET6 && SocketDisableIPv6 { 333 return -1, EAFNOSUPPORT 334 } 335 fd, err = socket(domain, typ, proto) 336 return 337 } 338 339 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 340 var fdx [2]int32 341 err = socketpair(domain, typ, proto, &fdx) 342 if err == nil { 343 fd[0] = int(fdx[0]) 344 fd[1] = int(fdx[1]) 345 } 346 return 347 } 348 349 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 350 if race.Enabled { 351 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 352 } 353 return sendfile(outfd, infd, offset, count) 354 } 355 356 var ioSync int64 357
View as plain text