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