github.com/bir3/gocompiler@v0.9.2202/src/xvendor/golang.org/x/sys/unix/syscall_bsd.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 darwin || dragonfly || freebsd || netbsd || openbsd 6 7 // BSD system call wrappers shared by *BSD based systems 8 // including OS X (Darwin) and FreeBSD. Like the other 9 // syscall_*.go files it is compiled as Go code but also 10 // used as input to mksyscall which parses the //sys 11 // lines and generates system call stubs. 12 13 package unix 14 15 import ( 16 "runtime" 17 "syscall" 18 "unsafe" 19 ) 20 21 const ImplementsGetwd = true 22 23 func Getwd() (string, error) { 24 var buf [PathMax]byte 25 _, err := Getcwd(buf[0:]) 26 if err != nil { 27 return "", err 28 } 29 n := clen(buf[:]) 30 if n < 1 { 31 return "", EINVAL 32 } 33 return string(buf[:n]), nil 34 } 35 36 /* 37 * Wrapped 38 */ 39 40 //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error) 41 //sysnb setgroups(ngid int, gid *_Gid_t) (err error) 42 43 func Getgroups() (gids []int, err error) { 44 n, err := getgroups(0, nil) 45 if err != nil { 46 return nil, err 47 } 48 if n == 0 { 49 return nil, nil 50 } 51 52 // Sanity check group count. Max is 16 on BSD. 53 if n < 0 || n > 1000 { 54 return nil, EINVAL 55 } 56 57 a := make([]_Gid_t, n) 58 n, err = getgroups(n, &a[0]) 59 if err != nil { 60 return nil, err 61 } 62 gids = make([]int, n) 63 for i, v := range a[0:n] { 64 gids[i] = int(v) 65 } 66 return 67 } 68 69 func Setgroups(gids []int) (err error) { 70 if len(gids) == 0 { 71 return setgroups(0, nil) 72 } 73 74 a := make([]_Gid_t, len(gids)) 75 for i, v := range gids { 76 a[i] = _Gid_t(v) 77 } 78 return setgroups(len(a), &a[0]) 79 } 80 81 // Wait status is 7 bits at bottom, either 0 (exited), 82 // 0x7F (stopped), or a signal number that caused an exit. 83 // The 0x80 bit is whether there was a core dump. 84 // An extra number (exit code, signal causing a stop) 85 // is in the high bits. 86 87 type WaitStatus uint32 88 89 const ( 90 mask = 0x7F 91 core = 0x80 92 shift = 8 93 94 exited = 0 95 killed = 9 96 stopped = 0x7F 97 ) 98 99 func (w WaitStatus) Exited() bool { return w&mask == exited } 100 101 func (w WaitStatus) ExitStatus() int { 102 if w&mask != exited { 103 return -1 104 } 105 return int(w >> shift) 106 } 107 108 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 } 109 110 func (w WaitStatus) Signal() syscall.Signal { 111 sig := syscall.Signal(w & mask) 112 if sig == stopped || sig == 0 { 113 return -1 114 } 115 return sig 116 } 117 118 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 119 120 func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP } 121 122 func (w WaitStatus) Killed() bool { return w&mask == killed && syscall.Signal(w>>shift) != SIGKILL } 123 124 func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP } 125 126 func (w WaitStatus) StopSignal() syscall.Signal { 127 if !w.Stopped() { 128 return -1 129 } 130 return syscall.Signal(w>>shift) & 0xFF 131 } 132 133 func (w WaitStatus) TrapCause() int { return -1 } 134 135 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 136 137 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 138 var status _C_int 139 wpid, err = wait4(pid, &status, options, rusage) 140 if wstatus != nil { 141 *wstatus = WaitStatus(status) 142 } 143 return 144 } 145 146 //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) 147 //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) 148 //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) 149 //sysnb socket(domain int, typ int, proto int) (fd int, err error) 150 //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) 151 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) 152 //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) 153 //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) 154 //sys Shutdown(s int, how int) (err error) 155 156 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 157 if sa.Port < 0 || sa.Port > 0xFFFF { 158 return nil, 0, EINVAL 159 } 160 sa.raw.Len = SizeofSockaddrInet4 161 sa.raw.Family = AF_INET 162 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 163 p[0] = byte(sa.Port >> 8) 164 p[1] = byte(sa.Port) 165 sa.raw.Addr = sa.Addr 166 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil 167 } 168 169 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 170 if sa.Port < 0 || sa.Port > 0xFFFF { 171 return nil, 0, EINVAL 172 } 173 sa.raw.Len = SizeofSockaddrInet6 174 sa.raw.Family = AF_INET6 175 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 176 p[0] = byte(sa.Port >> 8) 177 p[1] = byte(sa.Port) 178 sa.raw.Scope_id = sa.ZoneId 179 sa.raw.Addr = sa.Addr 180 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil 181 } 182 183 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 184 name := sa.Name 185 n := len(name) 186 if n >= len(sa.raw.Path) || n == 0 { 187 return nil, 0, EINVAL 188 } 189 sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL 190 sa.raw.Family = AF_UNIX 191 for i := 0; i < n; i++ { 192 sa.raw.Path[i] = int8(name[i]) 193 } 194 return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil 195 } 196 197 func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { 198 if sa.Index == 0 { 199 return nil, 0, EINVAL 200 } 201 sa.raw.Len = sa.Len 202 sa.raw.Family = AF_LINK 203 sa.raw.Index = sa.Index 204 sa.raw.Type = sa.Type 205 sa.raw.Nlen = sa.Nlen 206 sa.raw.Alen = sa.Alen 207 sa.raw.Slen = sa.Slen 208 sa.raw.Data = sa.Data 209 return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil 210 } 211 212 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { 213 switch rsa.Addr.Family { 214 case AF_LINK: 215 pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) 216 sa := new(SockaddrDatalink) 217 sa.Len = pp.Len 218 sa.Family = pp.Family 219 sa.Index = pp.Index 220 sa.Type = pp.Type 221 sa.Nlen = pp.Nlen 222 sa.Alen = pp.Alen 223 sa.Slen = pp.Slen 224 sa.Data = pp.Data 225 return sa, nil 226 227 case AF_UNIX: 228 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 229 if pp.Len < 2 || pp.Len > SizeofSockaddrUnix { 230 return nil, EINVAL 231 } 232 sa := new(SockaddrUnix) 233 234 // Some BSDs include the trailing NUL in the length, whereas 235 // others do not. Work around this by subtracting the leading 236 // family and len. The path is then scanned to see if a NUL 237 // terminator still exists within the length. 238 n := int(pp.Len) - 2 // subtract leading Family, Len 239 for i := 0; i < n; i++ { 240 if pp.Path[i] == 0 { 241 // found early NUL; assume Len included the NUL 242 // or was overestimating. 243 n = i 244 break 245 } 246 } 247 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) 248 return sa, nil 249 250 case AF_INET: 251 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 252 sa := new(SockaddrInet4) 253 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 254 sa.Port = int(p[0])<<8 + int(p[1]) 255 sa.Addr = pp.Addr 256 return sa, nil 257 258 case AF_INET6: 259 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 260 sa := new(SockaddrInet6) 261 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 262 sa.Port = int(p[0])<<8 + int(p[1]) 263 sa.ZoneId = pp.Scope_id 264 sa.Addr = pp.Addr 265 return sa, nil 266 } 267 return anyToSockaddrGOOS(fd, rsa) 268 } 269 270 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 271 var rsa RawSockaddrAny 272 var len _Socklen = SizeofSockaddrAny 273 nfd, err = accept(fd, &rsa, &len) 274 if err != nil { 275 return 276 } 277 if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 { 278 // Accepted socket has no address. 279 // This is likely due to a bug in xnu kernels, 280 // where instead of ECONNABORTED error socket 281 // is accepted, but has no address. 282 Close(nfd) 283 return 0, nil, ECONNABORTED 284 } 285 sa, err = anyToSockaddr(fd, &rsa) 286 if err != nil { 287 Close(nfd) 288 nfd = 0 289 } 290 return 291 } 292 293 func Getsockname(fd int) (sa Sockaddr, err error) { 294 var rsa RawSockaddrAny 295 var len _Socklen = SizeofSockaddrAny 296 if err = getsockname(fd, &rsa, &len); err != nil { 297 return 298 } 299 // TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be 300 // reported upstream. 301 if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 { 302 rsa.Addr.Family = AF_UNIX 303 rsa.Addr.Len = SizeofSockaddrUnix 304 } 305 return anyToSockaddr(fd, &rsa) 306 } 307 308 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) 309 310 // GetsockoptString returns the string value of the socket option opt for the 311 // socket associated with fd at the given socket level. 312 func GetsockoptString(fd, level, opt int) (string, error) { 313 buf := make([]byte, 256) 314 vallen := _Socklen(len(buf)) 315 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 316 if err != nil { 317 return "", err 318 } 319 return ByteSliceToString(buf[:vallen]), nil 320 } 321 322 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) 323 //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) 324 //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) 325 326 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { 327 var msg Msghdr 328 msg.Name = (*byte)(unsafe.Pointer(rsa)) 329 msg.Namelen = uint32(SizeofSockaddrAny) 330 var dummy byte 331 if len(oob) > 0 { 332 // receive at least one normal byte 333 if emptyIovecs(iov) { 334 var iova [1]Iovec 335 iova[0].Base = &dummy 336 iova[0].SetLen(1) 337 iov = iova[:] 338 } 339 msg.Control = (*byte)(unsafe.Pointer(&oob[0])) 340 msg.SetControllen(len(oob)) 341 } 342 if len(iov) > 0 { 343 msg.Iov = &iov[0] 344 msg.SetIovlen(len(iov)) 345 } 346 if n, err = recvmsg(fd, &msg, flags); err != nil { 347 return 348 } 349 oobn = int(msg.Controllen) 350 recvflags = int(msg.Flags) 351 return 352 } 353 354 //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) 355 356 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { 357 var msg Msghdr 358 msg.Name = (*byte)(unsafe.Pointer(ptr)) 359 msg.Namelen = uint32(salen) 360 var dummy byte 361 var empty bool 362 if len(oob) > 0 { 363 // send at least one normal byte 364 empty = emptyIovecs(iov) 365 if empty { 366 var iova [1]Iovec 367 iova[0].Base = &dummy 368 iova[0].SetLen(1) 369 iov = iova[:] 370 } 371 msg.Control = (*byte)(unsafe.Pointer(&oob[0])) 372 msg.SetControllen(len(oob)) 373 } 374 if len(iov) > 0 { 375 msg.Iov = &iov[0] 376 msg.SetIovlen(len(iov)) 377 } 378 if n, err = sendmsg(fd, &msg, flags); err != nil { 379 return 0, err 380 } 381 if len(oob) > 0 && empty { 382 n = 0 383 } 384 return n, nil 385 } 386 387 //sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) 388 389 func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) { 390 var change, event unsafe.Pointer 391 if len(changes) > 0 { 392 change = unsafe.Pointer(&changes[0]) 393 } 394 if len(events) > 0 { 395 event = unsafe.Pointer(&events[0]) 396 } 397 return kevent(kq, change, len(changes), event, len(events), timeout) 398 } 399 400 // sysctlmib translates name to mib number and appends any additional args. 401 func sysctlmib(name string, args ...int) ([]_C_int, error) { 402 // Translate name to mib number. 403 mib, err := nametomib(name) 404 if err != nil { 405 return nil, err 406 } 407 408 for _, a := range args { 409 mib = append(mib, _C_int(a)) 410 } 411 412 return mib, nil 413 } 414 415 func Sysctl(name string) (string, error) { 416 return SysctlArgs(name) 417 } 418 419 func SysctlArgs(name string, args ...int) (string, error) { 420 buf, err := SysctlRaw(name, args...) 421 if err != nil { 422 return "", err 423 } 424 n := len(buf) 425 426 // Throw away terminating NUL. 427 if n > 0 && buf[n-1] == '\x00' { 428 n-- 429 } 430 return string(buf[0:n]), nil 431 } 432 433 func SysctlUint32(name string) (uint32, error) { 434 return SysctlUint32Args(name) 435 } 436 437 func SysctlUint32Args(name string, args ...int) (uint32, error) { 438 mib, err := sysctlmib(name, args...) 439 if err != nil { 440 return 0, err 441 } 442 443 n := uintptr(4) 444 buf := make([]byte, 4) 445 if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { 446 return 0, err 447 } 448 if n != 4 { 449 return 0, EIO 450 } 451 return *(*uint32)(unsafe.Pointer(&buf[0])), nil 452 } 453 454 func SysctlUint64(name string, args ...int) (uint64, error) { 455 mib, err := sysctlmib(name, args...) 456 if err != nil { 457 return 0, err 458 } 459 460 n := uintptr(8) 461 buf := make([]byte, 8) 462 if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { 463 return 0, err 464 } 465 if n != 8 { 466 return 0, EIO 467 } 468 return *(*uint64)(unsafe.Pointer(&buf[0])), nil 469 } 470 471 func SysctlRaw(name string, args ...int) ([]byte, error) { 472 mib, err := sysctlmib(name, args...) 473 if err != nil { 474 return nil, err 475 } 476 477 // Find size. 478 n := uintptr(0) 479 if err := sysctl(mib, nil, &n, nil, 0); err != nil { 480 return nil, err 481 } 482 if n == 0 { 483 return nil, nil 484 } 485 486 // Read into buffer of that size. 487 buf := make([]byte, n) 488 if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { 489 return nil, err 490 } 491 492 // The actual call may return less than the original reported required 493 // size so ensure we deal with that. 494 return buf[:n], nil 495 } 496 497 func SysctlClockinfo(name string) (*Clockinfo, error) { 498 mib, err := sysctlmib(name) 499 if err != nil { 500 return nil, err 501 } 502 503 n := uintptr(SizeofClockinfo) 504 var ci Clockinfo 505 if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { 506 return nil, err 507 } 508 if n != SizeofClockinfo { 509 return nil, EIO 510 } 511 return &ci, nil 512 } 513 514 func SysctlTimeval(name string) (*Timeval, error) { 515 mib, err := sysctlmib(name) 516 if err != nil { 517 return nil, err 518 } 519 520 var tv Timeval 521 n := uintptr(unsafe.Sizeof(tv)) 522 if err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil { 523 return nil, err 524 } 525 if n != unsafe.Sizeof(tv) { 526 return nil, EIO 527 } 528 return &tv, nil 529 } 530 531 //sys utimes(path string, timeval *[2]Timeval) (err error) 532 533 func Utimes(path string, tv []Timeval) error { 534 if tv == nil { 535 return utimes(path, nil) 536 } 537 if len(tv) != 2 { 538 return EINVAL 539 } 540 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 541 } 542 543 func UtimesNano(path string, ts []Timespec) error { 544 if ts == nil { 545 err := utimensat(AT_FDCWD, path, nil, 0) 546 if err != ENOSYS { 547 return err 548 } 549 return utimes(path, nil) 550 } 551 if len(ts) != 2 { 552 return EINVAL 553 } 554 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 555 if err != ENOSYS { 556 return err 557 } 558 // Not as efficient as it could be because Timespec and 559 // Timeval have different types in the different OSes 560 tv := [2]Timeval{ 561 NsecToTimeval(TimespecToNsec(ts[0])), 562 NsecToTimeval(TimespecToNsec(ts[1])), 563 } 564 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 565 } 566 567 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { 568 if ts == nil { 569 return utimensat(dirfd, path, nil, flags) 570 } 571 if len(ts) != 2 { 572 return EINVAL 573 } 574 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) 575 } 576 577 //sys futimes(fd int, timeval *[2]Timeval) (err error) 578 579 func Futimes(fd int, tv []Timeval) error { 580 if tv == nil { 581 return futimes(fd, nil) 582 } 583 if len(tv) != 2 { 584 return EINVAL 585 } 586 return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 587 } 588 589 //sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) 590 591 func Poll(fds []PollFd, timeout int) (n int, err error) { 592 if len(fds) == 0 { 593 return poll(nil, 0, timeout) 594 } 595 return poll(&fds[0], len(fds), timeout) 596 } 597 598 // TODO: wrap 599 // Acct(name nil-string) (err error) 600 // Gethostuuid(uuid *byte, timeout *Timespec) (err error) 601 // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) 602 603 //sys Madvise(b []byte, behav int) (err error) 604 //sys Mlock(b []byte) (err error) 605 //sys Mlockall(flags int) (err error) 606 //sys Mprotect(b []byte, prot int) (err error) 607 //sys Msync(b []byte, flags int) (err error) 608 //sys Munlock(b []byte) (err error) 609 //sys Munlockall() (err error)