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