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