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