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