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