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