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