github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/syscall/syscall_linux.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 // Linux system calls. 6 // This file is compiled as ordinary Go code, 7 // but it is also input to mksyscall, 8 // which parses the //sys lines and generates system call stubs. 9 // Note that sometimes we use a lowercase //sys name and 10 // wrap it in our own nicer implementation. 11 12 package syscall 13 14 import ( 15 "internal/itoa" 16 "unsafe" 17 ) 18 19 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) 20 21 /* 22 * Wrapped 23 */ 24 25 func Access(path string, mode uint32) (err error) { 26 return Faccessat(_AT_FDCWD, path, mode, 0) 27 } 28 29 func Chmod(path string, mode uint32) (err error) { 30 return Fchmodat(_AT_FDCWD, path, mode, 0) 31 } 32 33 func Chown(path string, uid int, gid int) (err error) { 34 return Fchownat(_AT_FDCWD, path, uid, gid, 0) 35 } 36 37 func Creat(path string, mode uint32) (fd int, err error) { 38 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 39 } 40 41 func isGroupMember(gid int) bool { 42 groups, err := Getgroups() 43 if err != nil { 44 return false 45 } 46 47 for _, g := range groups { 48 if g == gid { 49 return true 50 } 51 } 52 return false 53 } 54 55 //sys faccessat(dirfd int, path string, mode uint32) (err error) 56 57 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { 58 if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 { 59 return EINVAL 60 } 61 62 // The Linux kernel faccessat system call does not take any flags. 63 // The glibc faccessat implements the flags itself; see 64 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD 65 // Because people naturally expect syscall.Faccessat to act 66 // like C faccessat, we do the same. 67 68 if flags == 0 { 69 return faccessat(dirfd, path, mode) 70 } 71 72 var st Stat_t 73 if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil { 74 return err 75 } 76 77 mode &= 7 78 if mode == 0 { 79 return nil 80 } 81 82 var uid int 83 if flags&_AT_EACCESS != 0 { 84 uid = Geteuid() 85 } else { 86 uid = Getuid() 87 } 88 89 if uid == 0 { 90 if mode&1 == 0 { 91 // Root can read and write any file. 92 return nil 93 } 94 if st.Mode&0111 != 0 { 95 // Root can execute any file that anybody can execute. 96 return nil 97 } 98 return EACCES 99 } 100 101 var fmode uint32 102 if uint32(uid) == st.Uid { 103 fmode = (st.Mode >> 6) & 7 104 } else { 105 var gid int 106 if flags&_AT_EACCESS != 0 { 107 gid = Getegid() 108 } else { 109 gid = Getgid() 110 } 111 112 if uint32(gid) == st.Gid || isGroupMember(gid) { 113 fmode = (st.Mode >> 3) & 7 114 } else { 115 fmode = st.Mode & 7 116 } 117 } 118 119 if fmode&mode == mode { 120 return nil 121 } 122 123 return EACCES 124 } 125 126 //sys fchmodat(dirfd int, path string, mode uint32) (err error) 127 128 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { 129 // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior 130 // and check the flags. Otherwise the mode would be applied to the symlink 131 // destination which is not what the user expects. 132 if flags&^_AT_SYMLINK_NOFOLLOW != 0 { 133 return EINVAL 134 } else if flags&_AT_SYMLINK_NOFOLLOW != 0 { 135 return EOPNOTSUPP 136 } 137 return fchmodat(dirfd, path, mode) 138 } 139 140 //sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) 141 142 func Link(oldpath string, newpath string) (err error) { 143 return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0) 144 } 145 146 func Mkdir(path string, mode uint32) (err error) { 147 return Mkdirat(_AT_FDCWD, path, mode) 148 } 149 150 func Mknod(path string, mode uint32, dev int) (err error) { 151 return Mknodat(_AT_FDCWD, path, mode, dev) 152 } 153 154 func Open(path string, mode int, perm uint32) (fd int, err error) { 155 return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm) 156 } 157 158 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) 159 160 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { 161 return openat(dirfd, path, flags|O_LARGEFILE, mode) 162 } 163 164 //sys readlinkat(dirfd int, path string, buf []byte) (n int, err error) 165 166 func Readlink(path string, buf []byte) (n int, err error) { 167 return readlinkat(_AT_FDCWD, path, buf) 168 } 169 170 func Rename(oldpath string, newpath string) (err error) { 171 return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath) 172 } 173 174 func Rmdir(path string) error { 175 return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR) 176 } 177 178 //sys symlinkat(oldpath string, newdirfd int, newpath string) (err error) 179 180 func Symlink(oldpath string, newpath string) (err error) { 181 return symlinkat(oldpath, _AT_FDCWD, newpath) 182 } 183 184 func Unlink(path string) error { 185 return unlinkat(_AT_FDCWD, path, 0) 186 } 187 188 //sys unlinkat(dirfd int, path string, flags int) (err error) 189 190 func Unlinkat(dirfd int, path string) error { 191 return unlinkat(dirfd, path, 0) 192 } 193 194 func Utimes(path string, tv []Timeval) (err error) { 195 if len(tv) != 2 { 196 return EINVAL 197 } 198 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 199 } 200 201 //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) 202 203 func UtimesNano(path string, ts []Timespec) (err error) { 204 if len(ts) != 2 { 205 return EINVAL 206 } 207 err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 208 if err != ENOSYS { 209 return err 210 } 211 // If the utimensat syscall isn't available (utimensat was added to Linux 212 // in 2.6.22, Released, 8 July 2007) then fall back to utimes 213 var tv [2]Timeval 214 for i := 0; i < 2; i++ { 215 tv[i].Sec = ts[i].Sec 216 tv[i].Usec = ts[i].Nsec / 1000 217 } 218 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 219 } 220 221 func Futimesat(dirfd int, path string, tv []Timeval) (err error) { 222 if len(tv) != 2 { 223 return EINVAL 224 } 225 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 226 } 227 228 func Futimes(fd int, tv []Timeval) (err error) { 229 // Believe it or not, this is the best we can do on Linux 230 // (and is what glibc does). 231 return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv) 232 } 233 234 const ImplementsGetwd = true 235 236 //sys Getcwd(buf []byte) (n int, err error) 237 238 func Getwd() (wd string, err error) { 239 var buf [PathMax]byte 240 n, err := Getcwd(buf[0:]) 241 if err != nil { 242 return "", err 243 } 244 // Getcwd returns the number of bytes written to buf, including the NUL. 245 if n < 1 || n > len(buf) || buf[n-1] != 0 { 246 return "", EINVAL 247 } 248 return string(buf[0 : n-1]), nil 249 } 250 251 func Getgroups() (gids []int, err error) { 252 n, err := getgroups(0, nil) 253 if err != nil { 254 return nil, err 255 } 256 if n == 0 { 257 return nil, nil 258 } 259 260 // Sanity check group count. Max is 1<<16 on Linux. 261 if n < 0 || n > 1<<20 { 262 return nil, EINVAL 263 } 264 265 a := make([]_Gid_t, n) 266 n, err = getgroups(n, &a[0]) 267 if err != nil { 268 return nil, err 269 } 270 gids = make([]int, n) 271 for i, v := range a[0:n] { 272 gids[i] = int(v) 273 } 274 return 275 } 276 277 var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked. 278 279 func Setgroups(gids []int) (err error) { 280 n := uintptr(len(gids)) 281 if n == 0 { 282 if cgo_libc_setgroups == nil { 283 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 { 284 err = errnoErr(e1) 285 } 286 return 287 } 288 if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 { 289 err = errnoErr(Errno(ret)) 290 } 291 return 292 } 293 294 a := make([]_Gid_t, len(gids)) 295 for i, v := range gids { 296 a[i] = _Gid_t(v) 297 } 298 if cgo_libc_setgroups == nil { 299 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 { 300 err = errnoErr(e1) 301 } 302 return 303 } 304 if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 { 305 err = errnoErr(Errno(ret)) 306 } 307 return 308 } 309 310 type WaitStatus uint32 311 312 // Wait status is 7 bits at bottom, either 0 (exited), 313 // 0x7F (stopped), or a signal number that caused an exit. 314 // The 0x80 bit is whether there was a core dump. 315 // An extra number (exit code, signal causing a stop) 316 // is in the high bits. At least that's the idea. 317 // There are various irregularities. For example, the 318 // "continued" status is 0xFFFF, distinguishing itself 319 // from stopped via the core dump bit. 320 321 const ( 322 mask = 0x7F 323 core = 0x80 324 exited = 0x00 325 stopped = 0x7F 326 shift = 8 327 ) 328 329 func (w WaitStatus) Exited() bool { return w&mask == exited } 330 331 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 332 333 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 334 335 func (w WaitStatus) Continued() bool { return w == 0xFFFF } 336 337 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 338 339 func (w WaitStatus) ExitStatus() int { 340 if !w.Exited() { 341 return -1 342 } 343 return int(w>>shift) & 0xFF 344 } 345 346 func (w WaitStatus) Signal() Signal { 347 if !w.Signaled() { 348 return -1 349 } 350 return Signal(w & mask) 351 } 352 353 func (w WaitStatus) StopSignal() Signal { 354 if !w.Stopped() { 355 return -1 356 } 357 return Signal(w>>shift) & 0xFF 358 } 359 360 func (w WaitStatus) TrapCause() int { 361 if w.StopSignal() != SIGTRAP { 362 return -1 363 } 364 return int(w>>shift) >> 8 365 } 366 367 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 368 369 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 370 var status _C_int 371 wpid, err = wait4(pid, &status, options, rusage) 372 if wstatus != nil { 373 *wstatus = WaitStatus(status) 374 } 375 return 376 } 377 378 func Mkfifo(path string, mode uint32) (err error) { 379 return Mknod(path, mode|S_IFIFO, 0) 380 } 381 382 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 383 if sa.Port < 0 || sa.Port > 0xFFFF { 384 return nil, 0, EINVAL 385 } 386 sa.raw.Family = AF_INET 387 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 388 p[0] = byte(sa.Port >> 8) 389 p[1] = byte(sa.Port) 390 for i := 0; i < len(sa.Addr); i++ { 391 sa.raw.Addr[i] = sa.Addr[i] 392 } 393 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 394 } 395 396 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 397 if sa.Port < 0 || sa.Port > 0xFFFF { 398 return nil, 0, EINVAL 399 } 400 sa.raw.Family = AF_INET6 401 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 402 p[0] = byte(sa.Port >> 8) 403 p[1] = byte(sa.Port) 404 sa.raw.Scope_id = sa.ZoneId 405 for i := 0; i < len(sa.Addr); i++ { 406 sa.raw.Addr[i] = sa.Addr[i] 407 } 408 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 409 } 410 411 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 412 name := sa.Name 413 n := len(name) 414 if n > len(sa.raw.Path) { 415 return nil, 0, EINVAL 416 } 417 if n == len(sa.raw.Path) && name[0] != '@' { 418 return nil, 0, EINVAL 419 } 420 sa.raw.Family = AF_UNIX 421 for i := 0; i < n; i++ { 422 sa.raw.Path[i] = int8(name[i]) 423 } 424 // length is family (uint16), name, NUL. 425 sl := _Socklen(2) 426 if n > 0 { 427 sl += _Socklen(n) + 1 428 } 429 if sa.raw.Path[0] == '@' { 430 sa.raw.Path[0] = 0 431 // Don't count trailing NUL for abstract address. 432 sl-- 433 } 434 435 return unsafe.Pointer(&sa.raw), sl, nil 436 } 437 438 type SockaddrLinklayer struct { 439 Protocol uint16 440 Ifindex int 441 Hatype uint16 442 Pkttype uint8 443 Halen uint8 444 Addr [8]byte 445 raw RawSockaddrLinklayer 446 } 447 448 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { 449 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 450 return nil, 0, EINVAL 451 } 452 sa.raw.Family = AF_PACKET 453 sa.raw.Protocol = sa.Protocol 454 sa.raw.Ifindex = int32(sa.Ifindex) 455 sa.raw.Hatype = sa.Hatype 456 sa.raw.Pkttype = sa.Pkttype 457 sa.raw.Halen = sa.Halen 458 for i := 0; i < len(sa.Addr); i++ { 459 sa.raw.Addr[i] = sa.Addr[i] 460 } 461 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil 462 } 463 464 type SockaddrNetlink struct { 465 Family uint16 466 Pad uint16 467 Pid uint32 468 Groups uint32 469 raw RawSockaddrNetlink 470 } 471 472 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { 473 sa.raw.Family = AF_NETLINK 474 sa.raw.Pad = sa.Pad 475 sa.raw.Pid = sa.Pid 476 sa.raw.Groups = sa.Groups 477 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil 478 } 479 480 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { 481 switch rsa.Addr.Family { 482 case AF_NETLINK: 483 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 484 sa := new(SockaddrNetlink) 485 sa.Family = pp.Family 486 sa.Pad = pp.Pad 487 sa.Pid = pp.Pid 488 sa.Groups = pp.Groups 489 return sa, nil 490 491 case AF_PACKET: 492 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 493 sa := new(SockaddrLinklayer) 494 sa.Protocol = pp.Protocol 495 sa.Ifindex = int(pp.Ifindex) 496 sa.Hatype = pp.Hatype 497 sa.Pkttype = pp.Pkttype 498 sa.Halen = pp.Halen 499 for i := 0; i < len(sa.Addr); i++ { 500 sa.Addr[i] = pp.Addr[i] 501 } 502 return sa, nil 503 504 case AF_UNIX: 505 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 506 sa := new(SockaddrUnix) 507 if pp.Path[0] == 0 { 508 // "Abstract" Unix domain socket. 509 // Rewrite leading NUL as @ for textual display. 510 // (This is the standard convention.) 511 // Not friendly to overwrite in place, 512 // but the callers below don't care. 513 pp.Path[0] = '@' 514 } 515 516 // Assume path ends at NUL. 517 // This is not technically the Linux semantics for 518 // abstract Unix domain sockets--they are supposed 519 // to be uninterpreted fixed-size binary blobs--but 520 // everyone uses this convention. 521 n := 0 522 for n < len(pp.Path) && pp.Path[n] != 0 { 523 n++ 524 } 525 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 526 sa.Name = string(bytes) 527 return sa, nil 528 529 case AF_INET: 530 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 531 sa := new(SockaddrInet4) 532 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 533 sa.Port = int(p[0])<<8 + int(p[1]) 534 for i := 0; i < len(sa.Addr); i++ { 535 sa.Addr[i] = pp.Addr[i] 536 } 537 return sa, nil 538 539 case AF_INET6: 540 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 541 sa := new(SockaddrInet6) 542 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 543 sa.Port = int(p[0])<<8 + int(p[1]) 544 sa.ZoneId = pp.Scope_id 545 for i := 0; i < len(sa.Addr); i++ { 546 sa.Addr[i] = pp.Addr[i] 547 } 548 return sa, nil 549 } 550 return nil, EAFNOSUPPORT 551 } 552 553 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 554 var rsa RawSockaddrAny 555 var len _Socklen = SizeofSockaddrAny 556 // Try accept4 first for Android, then try accept for kernel older than 2.6.28 557 nfd, err = accept4(fd, &rsa, &len, 0) 558 if err == ENOSYS { 559 nfd, err = accept(fd, &rsa, &len) 560 } 561 if err != nil { 562 return 563 } 564 sa, err = anyToSockaddr(&rsa) 565 if err != nil { 566 Close(nfd) 567 nfd = 0 568 } 569 return 570 } 571 572 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { 573 var rsa RawSockaddrAny 574 var len _Socklen = SizeofSockaddrAny 575 nfd, err = accept4(fd, &rsa, &len, flags) 576 if err != nil { 577 return 578 } 579 if len > SizeofSockaddrAny { 580 panic("RawSockaddrAny too small") 581 } 582 sa, err = anyToSockaddr(&rsa) 583 if err != nil { 584 Close(nfd) 585 nfd = 0 586 } 587 return 588 } 589 590 func Getsockname(fd int) (sa Sockaddr, err error) { 591 var rsa RawSockaddrAny 592 var len _Socklen = SizeofSockaddrAny 593 if err = getsockname(fd, &rsa, &len); err != nil { 594 return 595 } 596 return anyToSockaddr(&rsa) 597 } 598 599 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { 600 vallen := _Socklen(4) 601 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 602 return value, err 603 } 604 605 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { 606 var value IPMreq 607 vallen := _Socklen(SizeofIPMreq) 608 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 609 return &value, err 610 } 611 612 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 613 var value IPMreqn 614 vallen := _Socklen(SizeofIPMreqn) 615 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 616 return &value, err 617 } 618 619 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { 620 var value IPv6Mreq 621 vallen := _Socklen(SizeofIPv6Mreq) 622 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 623 return &value, err 624 } 625 626 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) { 627 var value IPv6MTUInfo 628 vallen := _Socklen(SizeofIPv6MTUInfo) 629 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 630 return &value, err 631 } 632 633 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { 634 var value ICMPv6Filter 635 vallen := _Socklen(SizeofICMPv6Filter) 636 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 637 return &value, err 638 } 639 640 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { 641 var value Ucred 642 vallen := _Socklen(SizeofUcred) 643 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 644 return &value, err 645 } 646 647 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 648 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 649 } 650 651 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 652 var msg Msghdr 653 var rsa RawSockaddrAny 654 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 655 msg.Namelen = uint32(SizeofSockaddrAny) 656 var iov Iovec 657 if len(p) > 0 { 658 iov.Base = &p[0] 659 iov.SetLen(len(p)) 660 } 661 var dummy byte 662 if len(oob) > 0 { 663 if len(p) == 0 { 664 var sockType int 665 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 666 if err != nil { 667 return 668 } 669 // receive at least one normal byte 670 if sockType != SOCK_DGRAM { 671 iov.Base = &dummy 672 iov.SetLen(1) 673 } 674 } 675 msg.Control = &oob[0] 676 msg.SetControllen(len(oob)) 677 } 678 msg.Iov = &iov 679 msg.Iovlen = 1 680 if n, err = recvmsg(fd, &msg, flags); err != nil { 681 return 682 } 683 oobn = int(msg.Controllen) 684 recvflags = int(msg.Flags) 685 // source address is only specified if the socket is unconnected 686 if rsa.Addr.Family != AF_UNSPEC { 687 from, err = anyToSockaddr(&rsa) 688 } 689 return 690 } 691 692 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 693 _, err = SendmsgN(fd, p, oob, to, flags) 694 return 695 } 696 697 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 698 var ptr unsafe.Pointer 699 var salen _Socklen 700 if to != nil { 701 var err error 702 ptr, salen, err = to.sockaddr() 703 if err != nil { 704 return 0, err 705 } 706 } 707 var msg Msghdr 708 msg.Name = (*byte)(ptr) 709 msg.Namelen = uint32(salen) 710 var iov Iovec 711 if len(p) > 0 { 712 iov.Base = &p[0] 713 iov.SetLen(len(p)) 714 } 715 var dummy byte 716 if len(oob) > 0 { 717 if len(p) == 0 { 718 var sockType int 719 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 720 if err != nil { 721 return 0, err 722 } 723 // send at least one normal byte 724 if sockType != SOCK_DGRAM { 725 iov.Base = &dummy 726 iov.SetLen(1) 727 } 728 } 729 msg.Control = &oob[0] 730 msg.SetControllen(len(oob)) 731 } 732 msg.Iov = &iov 733 msg.Iovlen = 1 734 if n, err = sendmsg(fd, &msg, flags); err != nil { 735 return 0, err 736 } 737 if len(oob) > 0 && len(p) == 0 { 738 n = 0 739 } 740 return n, nil 741 } 742 743 // BindToDevice binds the socket associated with fd to device. 744 func BindToDevice(fd int, device string) (err error) { 745 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 746 } 747 748 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 749 750 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 751 // The peek requests are machine-size oriented, so we wrap it 752 // to retrieve arbitrary-length data. 753 754 // The ptrace syscall differs from glibc's ptrace. 755 // Peeks returns the word in *data, not as the return value. 756 757 var buf [sizeofPtr]byte 758 759 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 760 // access (PEEKUSER warns that it might), but if we don't 761 // align our reads, we might straddle an unmapped page 762 // boundary and not get the bytes leading up to the page 763 // boundary. 764 n := 0 765 if addr%sizeofPtr != 0 { 766 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 767 if err != nil { 768 return 0, err 769 } 770 n += copy(out, buf[addr%sizeofPtr:]) 771 out = out[n:] 772 } 773 774 // Remainder. 775 for len(out) > 0 { 776 // We use an internal buffer to guarantee alignment. 777 // It's not documented if this is necessary, but we're paranoid. 778 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 779 if err != nil { 780 return n, err 781 } 782 copied := copy(out, buf[0:]) 783 n += copied 784 out = out[copied:] 785 } 786 787 return n, nil 788 } 789 790 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 791 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 792 } 793 794 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 795 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 796 } 797 798 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 799 // As for ptracePeek, we need to align our accesses to deal 800 // with the possibility of straddling an invalid page. 801 802 // Leading edge. 803 n := 0 804 if addr%sizeofPtr != 0 { 805 var buf [sizeofPtr]byte 806 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 807 if err != nil { 808 return 0, err 809 } 810 n += copy(buf[addr%sizeofPtr:], data) 811 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 812 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word) 813 if err != nil { 814 return 0, err 815 } 816 data = data[n:] 817 } 818 819 // Interior. 820 for len(data) > sizeofPtr { 821 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 822 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 823 if err != nil { 824 return n, err 825 } 826 n += sizeofPtr 827 data = data[sizeofPtr:] 828 } 829 830 // Trailing edge. 831 if len(data) > 0 { 832 var buf [sizeofPtr]byte 833 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 834 if err != nil { 835 return n, err 836 } 837 copy(buf[0:], data) 838 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 839 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 840 if err != nil { 841 return n, err 842 } 843 n += len(data) 844 } 845 846 return n, nil 847 } 848 849 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 850 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 851 } 852 853 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 854 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 855 } 856 857 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 858 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) 859 } 860 861 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 862 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) 863 } 864 865 func PtraceSetOptions(pid int, options int) (err error) { 866 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 867 } 868 869 func PtraceGetEventMsg(pid int) (msg uint, err error) { 870 var data _C_long 871 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) 872 msg = uint(data) 873 return 874 } 875 876 func PtraceCont(pid int, signal int) (err error) { 877 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 878 } 879 880 func PtraceSyscall(pid int, signal int) (err error) { 881 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) 882 } 883 884 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 885 886 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 887 888 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 889 890 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 891 892 func Reboot(cmd int) (err error) { 893 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 894 } 895 896 func ReadDirent(fd int, buf []byte) (n int, err error) { 897 return Getdents(fd, buf) 898 } 899 900 func direntIno(buf []byte) (uint64, bool) { 901 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 902 } 903 904 func direntReclen(buf []byte) (uint64, bool) { 905 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 906 } 907 908 func direntNamlen(buf []byte) (uint64, bool) { 909 reclen, ok := direntReclen(buf) 910 if !ok { 911 return 0, false 912 } 913 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 914 } 915 916 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 917 918 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 919 // Certain file systems get rather angry and EINVAL if you give 920 // them an empty string of data, rather than NULL. 921 if data == "" { 922 return mount(source, target, fstype, flags, nil) 923 } 924 datap, err := BytePtrFromString(data) 925 if err != nil { 926 return err 927 } 928 return mount(source, target, fstype, flags, datap) 929 } 930 931 // Sendto 932 // Recvfrom 933 // Socketpair 934 935 /* 936 * Direct access 937 */ 938 //sys Acct(path string) (err error) 939 //sys Adjtimex(buf *Timex) (state int, err error) 940 //sys Chdir(path string) (err error) 941 //sys Chroot(path string) (err error) 942 //sys Close(fd int) (err error) 943 //sys Dup(oldfd int) (fd int, err error) 944 //sys Dup3(oldfd int, newfd int, flags int) (err error) 945 //sysnb EpollCreate1(flag int) (fd int, err error) 946 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 947 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 948 //sys Fchdir(fd int) (err error) 949 //sys Fchmod(fd int, mode uint32) (err error) 950 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 951 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 952 //sys Fdatasync(fd int) (err error) 953 //sys Flock(fd int, how int) (err error) 954 //sys Fsync(fd int) (err error) 955 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 956 //sysnb Getpgid(pid int) (pgid int, err error) 957 958 func Getpgrp() (pid int) { 959 pid, _ = Getpgid(0) 960 return 961 } 962 963 //sysnb Getpid() (pid int) 964 //sysnb Getppid() (ppid int) 965 //sys Getpriority(which int, who int) (prio int, err error) 966 //sysnb Getrusage(who int, rusage *Rusage) (err error) 967 //sysnb Gettid() (tid int) 968 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) 969 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 970 //sysnb InotifyInit1(flags int) (fd int, err error) 971 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 972 //sysnb Kill(pid int, sig Signal) (err error) 973 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 974 //sys Listxattr(path string, dest []byte) (sz int, err error) 975 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 976 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 977 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 978 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 979 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 980 //sys read(fd int, p []byte) (n int, err error) 981 //sys Removexattr(path string, attr string) (err error) 982 //sys Setdomainname(p []byte) (err error) 983 //sys Sethostname(p []byte) (err error) 984 //sysnb Setpgid(pid int, pgid int) (err error) 985 //sysnb Setsid() (pid int, err error) 986 //sysnb Settimeofday(tv *Timeval) (err error) 987 988 // allThreadsCaller holds the input and output state for performing a 989 // allThreadsSyscall that needs to synchronize all OS thread state. Linux 990 // generally does not always support this natively, so we have to 991 // manipulate the runtime to fix things up. 992 type allThreadsCaller struct { 993 // arguments 994 trap, a1, a2, a3, a4, a5, a6 uintptr 995 996 // return values (only set by 0th invocation) 997 r1, r2 uintptr 998 999 // err is the error code 1000 err Errno 1001 } 1002 1003 // doSyscall is a callback for executing a syscall on the current m 1004 // (OS thread). 1005 //go:nosplit 1006 //go:norace 1007 func (pc *allThreadsCaller) doSyscall(initial bool) bool { 1008 r1, r2, err := RawSyscall(pc.trap, pc.a1, pc.a2, pc.a3) 1009 if initial { 1010 pc.r1 = r1 1011 pc.r2 = r2 1012 pc.err = err 1013 } else if pc.r1 != r1 || (archHonorsR2 && pc.r2 != r2) || pc.err != err { 1014 print("trap:", pc.trap, ", a123=[", pc.a1, ",", pc.a2, ",", pc.a3, "]\n") 1015 print("results: got {r1=", r1, ",r2=", r2, ",err=", err, "}, want {r1=", pc.r1, ",r2=", pc.r2, ",r3=", pc.err, "}\n") 1016 panic("AllThreadsSyscall results differ between threads; runtime corrupted") 1017 } 1018 return err == 0 1019 } 1020 1021 // doSyscall6 is a callback for executing a syscall6 on the current m 1022 // (OS thread). 1023 //go:nosplit 1024 //go:norace 1025 func (pc *allThreadsCaller) doSyscall6(initial bool) bool { 1026 r1, r2, err := RawSyscall6(pc.trap, pc.a1, pc.a2, pc.a3, pc.a4, pc.a5, pc.a6) 1027 if initial { 1028 pc.r1 = r1 1029 pc.r2 = r2 1030 pc.err = err 1031 } else if pc.r1 != r1 || (archHonorsR2 && pc.r2 != r2) || pc.err != err { 1032 print("trap:", pc.trap, ", a123456=[", pc.a1, ",", pc.a2, ",", pc.a3, ",", pc.a4, ",", pc.a5, ",", pc.a6, "]\n") 1033 print("results: got {r1=", r1, ",r2=", r2, ",err=", err, "}, want {r1=", pc.r1, ",r2=", pc.r2, ",r3=", pc.err, "}\n") 1034 panic("AllThreadsSyscall6 results differ between threads; runtime corrupted") 1035 } 1036 return err == 0 1037 } 1038 1039 // Provided by runtime.syscall_runtime_doAllThreadsSyscall which 1040 // serializes the world and invokes the fn on each OS thread (what the 1041 // runtime refers to as m's). Once this function returns, all threads 1042 // are in sync. 1043 func runtime_doAllThreadsSyscall(fn func(bool) bool) 1044 1045 // AllThreadsSyscall performs a syscall on each OS thread of the Go 1046 // runtime. It first invokes the syscall on one thread. Should that 1047 // invocation fail, it returns immediately with the error status. 1048 // Otherwise, it invokes the syscall on all of the remaining threads 1049 // in parallel. It will terminate the program if it observes any 1050 // invoked syscall's return value differs from that of the first 1051 // invocation. 1052 // 1053 // AllThreadsSyscall is intended for emulating simultaneous 1054 // process-wide state changes that require consistently modifying 1055 // per-thread state of the Go runtime. 1056 // 1057 // AllThreadsSyscall is unaware of any threads that are launched 1058 // explicitly by cgo linked code, so the function always returns 1059 // ENOTSUP in binaries that use cgo. 1060 //go:uintptrescapes 1061 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { 1062 if cgo_libc_setegid != nil { 1063 return minus1, minus1, ENOTSUP 1064 } 1065 pc := &allThreadsCaller{ 1066 trap: trap, 1067 a1: a1, 1068 a2: a2, 1069 a3: a3, 1070 } 1071 runtime_doAllThreadsSyscall(pc.doSyscall) 1072 r1 = pc.r1 1073 r2 = pc.r2 1074 err = pc.err 1075 return 1076 } 1077 1078 // AllThreadsSyscall6 is like AllThreadsSyscall, but extended to six 1079 // arguments. 1080 //go:uintptrescapes 1081 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { 1082 if cgo_libc_setegid != nil { 1083 return minus1, minus1, ENOTSUP 1084 } 1085 pc := &allThreadsCaller{ 1086 trap: trap, 1087 a1: a1, 1088 a2: a2, 1089 a3: a3, 1090 a4: a4, 1091 a5: a5, 1092 a6: a6, 1093 } 1094 runtime_doAllThreadsSyscall(pc.doSyscall6) 1095 r1 = pc.r1 1096 r2 = pc.r2 1097 err = pc.err 1098 return 1099 } 1100 1101 // linked by runtime.cgocall.go 1102 //go:uintptrescapes 1103 func cgocaller(unsafe.Pointer, ...uintptr) uintptr 1104 1105 var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked. 1106 1107 const minus1 = ^uintptr(0) 1108 1109 func Setegid(egid int) (err error) { 1110 if cgo_libc_setegid == nil { 1111 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 { 1112 err = errnoErr(e1) 1113 } 1114 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 { 1115 err = errnoErr(Errno(ret)) 1116 } 1117 return 1118 } 1119 1120 var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked. 1121 1122 func Seteuid(euid int) (err error) { 1123 if cgo_libc_seteuid == nil { 1124 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 { 1125 err = errnoErr(e1) 1126 } 1127 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 { 1128 err = errnoErr(Errno(ret)) 1129 } 1130 return 1131 } 1132 1133 var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked. 1134 1135 func Setgid(gid int) (err error) { 1136 if cgo_libc_setgid == nil { 1137 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 { 1138 err = errnoErr(e1) 1139 } 1140 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 { 1141 err = errnoErr(Errno(ret)) 1142 } 1143 return 1144 } 1145 1146 var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked. 1147 1148 func Setregid(rgid, egid int) (err error) { 1149 if cgo_libc_setregid == nil { 1150 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 { 1151 err = errnoErr(e1) 1152 } 1153 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 { 1154 err = errnoErr(Errno(ret)) 1155 } 1156 return 1157 } 1158 1159 var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked. 1160 1161 func Setresgid(rgid, egid, sgid int) (err error) { 1162 if cgo_libc_setresgid == nil { 1163 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 { 1164 err = errnoErr(e1) 1165 } 1166 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 { 1167 err = errnoErr(Errno(ret)) 1168 } 1169 return 1170 } 1171 1172 var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked. 1173 1174 func Setresuid(ruid, euid, suid int) (err error) { 1175 if cgo_libc_setresuid == nil { 1176 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 { 1177 err = errnoErr(e1) 1178 } 1179 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 { 1180 err = errnoErr(Errno(ret)) 1181 } 1182 return 1183 } 1184 1185 var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked. 1186 1187 func Setreuid(ruid, euid int) (err error) { 1188 if cgo_libc_setreuid == nil { 1189 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 { 1190 err = errnoErr(e1) 1191 } 1192 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 { 1193 err = errnoErr(Errno(ret)) 1194 } 1195 return 1196 } 1197 1198 var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked. 1199 1200 func Setuid(uid int) (err error) { 1201 if cgo_libc_setuid == nil { 1202 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 { 1203 err = errnoErr(e1) 1204 } 1205 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 { 1206 err = errnoErr(Errno(ret)) 1207 } 1208 return 1209 } 1210 1211 //sys Setpriority(which int, who int, prio int) (err error) 1212 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) 1213 //sys Sync() 1214 //sysnb Sysinfo(info *Sysinfo_t) (err error) 1215 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 1216 //sysnb Tgkill(tgid int, tid int, sig Signal) (err error) 1217 //sysnb Times(tms *Tms) (ticks uintptr, err error) 1218 //sysnb Umask(mask int) (oldmask int) 1219 //sysnb Uname(buf *Utsname) (err error) 1220 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 1221 //sys Unshare(flags int) (err error) 1222 //sys write(fd int, p []byte) (n int, err error) 1223 //sys exitThread(code int) (err error) = SYS_EXIT 1224 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ 1225 //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE 1226 1227 // mmap varies by architecture; see syscall_linux_*.go. 1228 //sys munmap(addr uintptr, length uintptr) (err error) 1229 1230 var mapper = &mmapper{ 1231 active: make(map[*byte][]byte), 1232 mmap: mmap, 1233 munmap: munmap, 1234 } 1235 1236 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 1237 return mapper.Mmap(fd, offset, length, prot, flags) 1238 } 1239 1240 func Munmap(b []byte) (err error) { 1241 return mapper.Munmap(b) 1242 } 1243 1244 //sys Madvise(b []byte, advice int) (err error) 1245 //sys Mprotect(b []byte, prot int) (err error) 1246 //sys Mlock(b []byte) (err error) 1247 //sys Munlock(b []byte) (err error) 1248 //sys Mlockall(flags int) (err error) 1249 //sys Munlockall() (err error)