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