syscall_unix.go (12454B)
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 unix 9 10 import ( 11 "bytes" 12 "sort" 13 "sync" 14 "syscall" 15 "unsafe" 16 17 "golang.org/x/sys/internal/unsafeheader" 18 ) 19 20 var ( 21 Stdin = 0 22 Stdout = 1 23 Stderr = 2 24 ) 25 26 // Do the interface allocations only once for common 27 // Errno values. 28 var ( 29 errEAGAIN error = syscall.EAGAIN 30 errEINVAL error = syscall.EINVAL 31 errENOENT error = syscall.ENOENT 32 ) 33 34 var ( 35 signalNameMapOnce sync.Once 36 signalNameMap map[string]syscall.Signal 37 ) 38 39 // errnoErr returns common boxed Errno values, to prevent 40 // allocations at runtime. 41 func errnoErr(e syscall.Errno) error { 42 switch e { 43 case 0: 44 return nil 45 case EAGAIN: 46 return errEAGAIN 47 case EINVAL: 48 return errEINVAL 49 case ENOENT: 50 return errENOENT 51 } 52 return e 53 } 54 55 // ErrnoName returns the error name for error number e. 56 func ErrnoName(e syscall.Errno) string { 57 i := sort.Search(len(errorList), func(i int) bool { 58 return errorList[i].num >= e 59 }) 60 if i < len(errorList) && errorList[i].num == e { 61 return errorList[i].name 62 } 63 return "" 64 } 65 66 // SignalName returns the signal name for signal number s. 67 func SignalName(s syscall.Signal) string { 68 i := sort.Search(len(signalList), func(i int) bool { 69 return signalList[i].num >= s 70 }) 71 if i < len(signalList) && signalList[i].num == s { 72 return signalList[i].name 73 } 74 return "" 75 } 76 77 // SignalNum returns the syscall.Signal for signal named s, 78 // or 0 if a signal with such name is not found. 79 // The signal name should start with "SIG". 80 func SignalNum(s string) syscall.Signal { 81 signalNameMapOnce.Do(func() { 82 signalNameMap = make(map[string]syscall.Signal, len(signalList)) 83 for _, signal := range signalList { 84 signalNameMap[signal.name] = signal.num 85 } 86 }) 87 return signalNameMap[s] 88 } 89 90 // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. 91 func clen(n []byte) int { 92 i := bytes.IndexByte(n, 0) 93 if i == -1 { 94 i = len(n) 95 } 96 return i 97 } 98 99 // Mmap manager, for use by operating system-specific implementations. 100 101 type mmapper struct { 102 sync.Mutex 103 active map[*byte][]byte // active mappings; key is last byte in mapping 104 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error) 105 munmap func(addr uintptr, length uintptr) error 106 } 107 108 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 109 if length <= 0 { 110 return nil, EINVAL 111 } 112 113 // Map the requested memory. 114 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset) 115 if errno != nil { 116 return nil, errno 117 } 118 119 // Use unsafe to convert addr into a []byte. 120 var b []byte 121 hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b)) 122 hdr.Data = unsafe.Pointer(addr) 123 hdr.Cap = length 124 hdr.Len = length 125 126 // Register mapping in m and return it. 127 p := &b[cap(b)-1] 128 m.Lock() 129 defer m.Unlock() 130 m.active[p] = b 131 return b, nil 132 } 133 134 func (m *mmapper) Munmap(data []byte) (err error) { 135 if len(data) == 0 || len(data) != cap(data) { 136 return EINVAL 137 } 138 139 // Find the base of the mapping. 140 p := &data[cap(data)-1] 141 m.Lock() 142 defer m.Unlock() 143 b := m.active[p] 144 if b == nil || &b[0] != &data[0] { 145 return EINVAL 146 } 147 148 // Unmap the memory and update m. 149 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil { 150 return errno 151 } 152 delete(m.active, p) 153 return nil 154 } 155 156 func Read(fd int, p []byte) (n int, err error) { 157 n, err = read(fd, p) 158 if raceenabled { 159 if n > 0 { 160 raceWriteRange(unsafe.Pointer(&p[0]), n) 161 } 162 if err == nil { 163 raceAcquire(unsafe.Pointer(&ioSync)) 164 } 165 } 166 return 167 } 168 169 func Write(fd int, p []byte) (n int, err error) { 170 if raceenabled { 171 raceReleaseMerge(unsafe.Pointer(&ioSync)) 172 } 173 n, err = write(fd, p) 174 if raceenabled && n > 0 { 175 raceReadRange(unsafe.Pointer(&p[0]), n) 176 } 177 return 178 } 179 180 func Pread(fd int, p []byte, offset int64) (n int, err error) { 181 n, err = pread(fd, p, offset) 182 if raceenabled { 183 if n > 0 { 184 raceWriteRange(unsafe.Pointer(&p[0]), n) 185 } 186 if err == nil { 187 raceAcquire(unsafe.Pointer(&ioSync)) 188 } 189 } 190 return 191 } 192 193 func Pwrite(fd int, p []byte, offset int64) (n int, err error) { 194 if raceenabled { 195 raceReleaseMerge(unsafe.Pointer(&ioSync)) 196 } 197 n, err = pwrite(fd, p, offset) 198 if raceenabled && n > 0 { 199 raceReadRange(unsafe.Pointer(&p[0]), n) 200 } 201 return 202 } 203 204 // For testing: clients can set this flag to force 205 // creation of IPv6 sockets to return EAFNOSUPPORT. 206 var SocketDisableIPv6 bool 207 208 // Sockaddr represents a socket address. 209 type Sockaddr interface { 210 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs 211 } 212 213 // SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets. 214 type SockaddrInet4 struct { 215 Port int 216 Addr [4]byte 217 raw RawSockaddrInet4 218 } 219 220 // SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets. 221 type SockaddrInet6 struct { 222 Port int 223 ZoneId uint32 224 Addr [16]byte 225 raw RawSockaddrInet6 226 } 227 228 // SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets. 229 type SockaddrUnix struct { 230 Name string 231 raw RawSockaddrUnix 232 } 233 234 func Bind(fd int, sa Sockaddr) (err error) { 235 ptr, n, err := sa.sockaddr() 236 if err != nil { 237 return err 238 } 239 return bind(fd, ptr, n) 240 } 241 242 func Connect(fd int, sa Sockaddr) (err error) { 243 ptr, n, err := sa.sockaddr() 244 if err != nil { 245 return err 246 } 247 return connect(fd, ptr, n) 248 } 249 250 func Getpeername(fd int) (sa Sockaddr, err error) { 251 var rsa RawSockaddrAny 252 var len _Socklen = SizeofSockaddrAny 253 if err = getpeername(fd, &rsa, &len); err != nil { 254 return 255 } 256 return anyToSockaddr(fd, &rsa) 257 } 258 259 func GetsockoptByte(fd, level, opt int) (value byte, err error) { 260 var n byte 261 vallen := _Socklen(1) 262 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 263 return n, err 264 } 265 266 func GetsockoptInt(fd, level, opt int) (value int, err error) { 267 var n int32 268 vallen := _Socklen(4) 269 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 270 return int(n), err 271 } 272 273 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { 274 vallen := _Socklen(4) 275 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 276 return value, err 277 } 278 279 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { 280 var value IPMreq 281 vallen := _Socklen(SizeofIPMreq) 282 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 283 return &value, err 284 } 285 286 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { 287 var value IPv6Mreq 288 vallen := _Socklen(SizeofIPv6Mreq) 289 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 290 return &value, err 291 } 292 293 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) { 294 var value IPv6MTUInfo 295 vallen := _Socklen(SizeofIPv6MTUInfo) 296 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 297 return &value, err 298 } 299 300 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { 301 var value ICMPv6Filter 302 vallen := _Socklen(SizeofICMPv6Filter) 303 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 304 return &value, err 305 } 306 307 func GetsockoptLinger(fd, level, opt int) (*Linger, error) { 308 var linger Linger 309 vallen := _Socklen(SizeofLinger) 310 err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen) 311 return &linger, err 312 } 313 314 func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) { 315 var tv Timeval 316 vallen := _Socklen(unsafe.Sizeof(tv)) 317 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen) 318 return &tv, err 319 } 320 321 func GetsockoptUint64(fd, level, opt int) (value uint64, err error) { 322 var n uint64 323 vallen := _Socklen(8) 324 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 325 return n, err 326 } 327 328 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 329 var rsa RawSockaddrAny 330 var len _Socklen = SizeofSockaddrAny 331 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 332 return 333 } 334 if rsa.Addr.Family != AF_UNSPEC { 335 from, err = anyToSockaddr(fd, &rsa) 336 } 337 return 338 } 339 340 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 341 var rsa RawSockaddrAny 342 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa) 343 // source address is only specified if the socket is unconnected 344 if rsa.Addr.Family != AF_UNSPEC { 345 from, err = anyToSockaddr(fd, &rsa) 346 } 347 return 348 } 349 350 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 351 _, err = SendmsgN(fd, p, oob, to, flags) 352 return 353 } 354 355 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 356 var ptr unsafe.Pointer 357 var salen _Socklen 358 if to != nil { 359 ptr, salen, err = to.sockaddr() 360 if err != nil { 361 return 0, err 362 } 363 } 364 return sendmsgN(fd, p, oob, ptr, salen, flags) 365 } 366 367 func Send(s int, buf []byte, flags int) (err error) { 368 return sendto(s, buf, flags, nil, 0) 369 } 370 371 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 372 ptr, n, err := to.sockaddr() 373 if err != nil { 374 return err 375 } 376 return sendto(fd, p, flags, ptr, n) 377 } 378 379 func SetsockoptByte(fd, level, opt int, value byte) (err error) { 380 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) 381 } 382 383 func SetsockoptInt(fd, level, opt int, value int) (err error) { 384 var n = int32(value) 385 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4) 386 } 387 388 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 389 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4) 390 } 391 392 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 393 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq) 394 } 395 396 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 397 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq) 398 } 399 400 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { 401 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter) 402 } 403 404 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 405 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) 406 } 407 408 func SetsockoptString(fd, level, opt int, s string) (err error) { 409 var p unsafe.Pointer 410 if len(s) > 0 { 411 p = unsafe.Pointer(&[]byte(s)[0]) 412 } 413 return setsockopt(fd, level, opt, p, uintptr(len(s))) 414 } 415 416 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 417 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) 418 } 419 420 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) { 421 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8) 422 } 423 424 func Socket(domain, typ, proto int) (fd int, err error) { 425 if domain == AF_INET6 && SocketDisableIPv6 { 426 return -1, EAFNOSUPPORT 427 } 428 fd, err = socket(domain, typ, proto) 429 return 430 } 431 432 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 433 var fdx [2]int32 434 err = socketpair(domain, typ, proto, &fdx) 435 if err == nil { 436 fd[0] = int(fdx[0]) 437 fd[1] = int(fdx[1]) 438 } 439 return 440 } 441 442 var ioSync int64 443 444 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) } 445 446 func SetNonblock(fd int, nonblocking bool) (err error) { 447 flag, err := fcntl(fd, F_GETFL, 0) 448 if err != nil { 449 return err 450 } 451 if nonblocking { 452 flag |= O_NONBLOCK 453 } else { 454 flag &= ^O_NONBLOCK 455 } 456 _, err = fcntl(fd, F_SETFL, flag) 457 return err 458 } 459 460 // Exec calls execve(2), which replaces the calling executable in the process 461 // tree. argv0 should be the full path to an executable ("/bin/ls") and the 462 // executable name should also be the first argument in argv (["ls", "-l"]). 463 // envv are the environment variables that should be passed to the new 464 // process (["USER=go", "PWD=/tmp"]). 465 func Exec(argv0 string, argv []string, envv []string) error { 466 return syscall.Exec(argv0, argv, envv) 467 } 468 469 // Lutimes sets the access and modification times tv on path. If path refers to 470 // a symlink, it is not dereferenced and the timestamps are set on the symlink. 471 // If tv is nil, the access and modification times are set to the current time. 472 // Otherwise tv must contain exactly 2 elements, with access time as the first 473 // element and modification time as the second element. 474 func Lutimes(path string, tv []Timeval) error { 475 if tv == nil { 476 return UtimesNanoAt(AT_FDCWD, path, nil, AT_SYMLINK_NOFOLLOW) 477 } 478 if len(tv) != 2 { 479 return EINVAL 480 } 481 ts := []Timespec{ 482 NsecToTimespec(TimevalToNsec(tv[0])), 483 NsecToTimespec(TimevalToNsec(tv[1])), 484 } 485 return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW) 486 }