github.com/etecs-ru/go-sys-wineventlog@v0.0.0-20210227233244-4c3abb794018/unix/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 unix 13 14 import ( 15 "encoding/binary" 16 "runtime" 17 "syscall" 18 "unsafe" 19 ) 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 //sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) 42 //sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) 43 44 func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) { 45 if pathname == "" { 46 return fanotifyMark(fd, flags, mask, dirFd, nil) 47 } 48 p, err := BytePtrFromString(pathname) 49 if err != nil { 50 return err 51 } 52 return fanotifyMark(fd, flags, mask, dirFd, p) 53 } 54 55 //sys fchmodat(dirfd int, path string, mode uint32) (err error) 56 57 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { 58 // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior 59 // and check the flags. Otherwise the mode would be applied to the symlink 60 // destination which is not what the user expects. 61 if flags&^AT_SYMLINK_NOFOLLOW != 0 { 62 return EINVAL 63 } else if flags&AT_SYMLINK_NOFOLLOW != 0 { 64 return EOPNOTSUPP 65 } 66 return fchmodat(dirfd, path, mode) 67 } 68 69 //sys ioctl(fd int, req uint, arg uintptr) (err error) 70 71 // ioctl itself should not be exposed directly, but additional get/set 72 // functions for specific types are permissible. 73 74 // IoctlRetInt performs an ioctl operation specified by req on a device 75 // associated with opened file descriptor fd, and returns a non-negative 76 // integer that is returned by the ioctl syscall. 77 func IoctlRetInt(fd int, req uint) (int, error) { 78 ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0) 79 if err != 0 { 80 return 0, err 81 } 82 return int(ret), nil 83 } 84 85 func IoctlSetRTCTime(fd int, value *RTCTime) error { 86 err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) 87 runtime.KeepAlive(value) 88 return err 89 } 90 91 func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { 92 err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value))) 93 runtime.KeepAlive(value) 94 return err 95 } 96 97 func IoctlGetUint32(fd int, req uint) (uint32, error) { 98 var value uint32 99 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) 100 return value, err 101 } 102 103 func IoctlGetRTCTime(fd int) (*RTCTime, error) { 104 var value RTCTime 105 err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) 106 return &value, err 107 } 108 109 // IoctlGetWatchdogInfo fetches information about a watchdog device from the 110 // Linux watchdog API. For more information, see: 111 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. 112 func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { 113 var value WatchdogInfo 114 err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value))) 115 return &value, err 116 } 117 118 func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { 119 var value RTCWkAlrm 120 err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value))) 121 return &value, err 122 } 123 124 // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the 125 // range of data conveyed in value to the file associated with the file 126 // descriptor destFd. See the ioctl_ficlonerange(2) man page for details. 127 func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { 128 err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value))) 129 runtime.KeepAlive(value) 130 return err 131 } 132 133 // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file 134 // associated with the file description srcFd to the file associated with the 135 // file descriptor destFd. See the ioctl_ficlone(2) man page for details. 136 func IoctlFileClone(destFd, srcFd int) error { 137 return ioctl(destFd, FICLONE, uintptr(srcFd)) 138 } 139 140 type FileDedupeRange struct { 141 Src_offset uint64 142 Src_length uint64 143 Reserved1 uint16 144 Reserved2 uint32 145 Info []FileDedupeRangeInfo 146 } 147 148 type FileDedupeRangeInfo struct { 149 Dest_fd int64 150 Dest_offset uint64 151 Bytes_deduped uint64 152 Status int32 153 Reserved uint32 154 } 155 156 // IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the 157 // range of data conveyed in value from the file associated with the file 158 // descriptor srcFd to the value.Info destinations. See the 159 // ioctl_fideduperange(2) man page for details. 160 func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error { 161 buf := make([]byte, SizeofRawFileDedupeRange+ 162 len(value.Info)*SizeofRawFileDedupeRangeInfo) 163 rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0])) 164 rawrange.Src_offset = value.Src_offset 165 rawrange.Src_length = value.Src_length 166 rawrange.Dest_count = uint16(len(value.Info)) 167 rawrange.Reserved1 = value.Reserved1 168 rawrange.Reserved2 = value.Reserved2 169 170 for i := range value.Info { 171 rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer( 172 uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) + 173 uintptr(i*SizeofRawFileDedupeRangeInfo))) 174 rawinfo.Dest_fd = value.Info[i].Dest_fd 175 rawinfo.Dest_offset = value.Info[i].Dest_offset 176 rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped 177 rawinfo.Status = value.Info[i].Status 178 rawinfo.Reserved = value.Info[i].Reserved 179 } 180 181 err := ioctl(srcFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(&buf[0]))) 182 183 // Output 184 for i := range value.Info { 185 rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer( 186 uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) + 187 uintptr(i*SizeofRawFileDedupeRangeInfo))) 188 value.Info[i].Dest_fd = rawinfo.Dest_fd 189 value.Info[i].Dest_offset = rawinfo.Dest_offset 190 value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped 191 value.Info[i].Status = rawinfo.Status 192 value.Info[i].Reserved = rawinfo.Reserved 193 } 194 195 return err 196 } 197 198 // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For 199 // more information, see: 200 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. 201 func IoctlWatchdogKeepalive(fd int) error { 202 return ioctl(fd, WDIOC_KEEPALIVE, 0) 203 } 204 205 func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { 206 err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value))) 207 runtime.KeepAlive(value) 208 return err 209 } 210 211 func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { 212 var value HIDRawDevInfo 213 err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value))) 214 return &value, err 215 } 216 217 func IoctlHIDGetRawName(fd int) (string, error) { 218 var value [_HIDIOCGRAWNAME_LEN]byte 219 err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0]))) 220 return ByteSliceToString(value[:]), err 221 } 222 223 func IoctlHIDGetRawPhys(fd int) (string, error) { 224 var value [_HIDIOCGRAWPHYS_LEN]byte 225 err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0]))) 226 return ByteSliceToString(value[:]), err 227 } 228 229 func IoctlHIDGetRawUniq(fd int) (string, error) { 230 var value [_HIDIOCGRAWUNIQ_LEN]byte 231 err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0]))) 232 return ByteSliceToString(value[:]), err 233 } 234 235 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) 236 237 func Link(oldpath string, newpath string) (err error) { 238 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) 239 } 240 241 func Mkdir(path string, mode uint32) (err error) { 242 return Mkdirat(AT_FDCWD, path, mode) 243 } 244 245 func Mknod(path string, mode uint32, dev int) (err error) { 246 return Mknodat(AT_FDCWD, path, mode, dev) 247 } 248 249 func Open(path string, mode int, perm uint32) (fd int, err error) { 250 return openat(AT_FDCWD, path, mode|O_LARGEFILE, perm) 251 } 252 253 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) 254 255 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { 256 return openat(dirfd, path, flags|O_LARGEFILE, mode) 257 } 258 259 //sys openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) 260 261 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { 262 return openat2(dirfd, path, how, SizeofOpenHow) 263 } 264 265 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) 266 267 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { 268 if len(fds) == 0 { 269 return ppoll(nil, 0, timeout, sigmask) 270 } 271 return ppoll(&fds[0], len(fds), timeout, sigmask) 272 } 273 274 //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) 275 276 func Readlink(path string, buf []byte) (n int, err error) { 277 return Readlinkat(AT_FDCWD, path, buf) 278 } 279 280 func Rename(oldpath string, newpath string) (err error) { 281 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath) 282 } 283 284 func Rmdir(path string) error { 285 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR) 286 } 287 288 //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) 289 290 func Symlink(oldpath string, newpath string) (err error) { 291 return Symlinkat(oldpath, AT_FDCWD, newpath) 292 } 293 294 func Unlink(path string) error { 295 return Unlinkat(AT_FDCWD, path, 0) 296 } 297 298 //sys Unlinkat(dirfd int, path string, flags int) (err error) 299 300 func Utimes(path string, tv []Timeval) error { 301 if tv == nil { 302 err := utimensat(AT_FDCWD, path, nil, 0) 303 if err != ENOSYS { 304 return err 305 } 306 return utimes(path, nil) 307 } 308 if len(tv) != 2 { 309 return EINVAL 310 } 311 var ts [2]Timespec 312 ts[0] = NsecToTimespec(TimevalToNsec(tv[0])) 313 ts[1] = NsecToTimespec(TimevalToNsec(tv[1])) 314 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 315 if err != ENOSYS { 316 return err 317 } 318 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 319 } 320 321 //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) 322 323 func UtimesNano(path string, ts []Timespec) error { 324 if ts == nil { 325 err := utimensat(AT_FDCWD, path, nil, 0) 326 if err != ENOSYS { 327 return err 328 } 329 return utimes(path, nil) 330 } 331 if len(ts) != 2 { 332 return EINVAL 333 } 334 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 335 if err != ENOSYS { 336 return err 337 } 338 // If the utimensat syscall isn't available (utimensat was added to Linux 339 // in 2.6.22, Released, 8 July 2007) then fall back to utimes 340 var tv [2]Timeval 341 for i := 0; i < 2; i++ { 342 tv[i] = NsecToTimeval(TimespecToNsec(ts[i])) 343 } 344 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 345 } 346 347 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { 348 if ts == nil { 349 return utimensat(dirfd, path, nil, flags) 350 } 351 if len(ts) != 2 { 352 return EINVAL 353 } 354 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) 355 } 356 357 func Futimesat(dirfd int, path string, tv []Timeval) error { 358 if tv == nil { 359 return futimesat(dirfd, path, nil) 360 } 361 if len(tv) != 2 { 362 return EINVAL 363 } 364 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 365 } 366 367 func Futimes(fd int, tv []Timeval) (err error) { 368 // Believe it or not, this is the best we can do on Linux 369 // (and is what glibc does). 370 return Utimes("/proc/self/fd/"+itoa(fd), tv) 371 } 372 373 const ImplementsGetwd = true 374 375 //sys Getcwd(buf []byte) (n int, err error) 376 377 func Getwd() (wd string, err error) { 378 var buf [PathMax]byte 379 n, err := Getcwd(buf[0:]) 380 if err != nil { 381 return "", err 382 } 383 // Getcwd returns the number of bytes written to buf, including the NUL. 384 if n < 1 || n > len(buf) || buf[n-1] != 0 { 385 return "", EINVAL 386 } 387 return string(buf[0 : n-1]), nil 388 } 389 390 func Getgroups() (gids []int, err error) { 391 n, err := getgroups(0, nil) 392 if err != nil { 393 return nil, err 394 } 395 if n == 0 { 396 return nil, nil 397 } 398 399 // Sanity check group count. Max is 1<<16 on Linux. 400 if n < 0 || n > 1<<20 { 401 return nil, EINVAL 402 } 403 404 a := make([]_Gid_t, n) 405 n, err = getgroups(n, &a[0]) 406 if err != nil { 407 return nil, err 408 } 409 gids = make([]int, n) 410 for i, v := range a[0:n] { 411 gids[i] = int(v) 412 } 413 return 414 } 415 416 func Setgroups(gids []int) (err error) { 417 if len(gids) == 0 { 418 return setgroups(0, nil) 419 } 420 421 a := make([]_Gid_t, len(gids)) 422 for i, v := range gids { 423 a[i] = _Gid_t(v) 424 } 425 return setgroups(len(a), &a[0]) 426 } 427 428 type WaitStatus uint32 429 430 // Wait status is 7 bits at bottom, either 0 (exited), 431 // 0x7F (stopped), or a signal number that caused an exit. 432 // The 0x80 bit is whether there was a core dump. 433 // An extra number (exit code, signal causing a stop) 434 // is in the high bits. At least that's the idea. 435 // There are various irregularities. For example, the 436 // "continued" status is 0xFFFF, distinguishing itself 437 // from stopped via the core dump bit. 438 439 const ( 440 mask = 0x7F 441 core = 0x80 442 exited = 0x00 443 stopped = 0x7F 444 shift = 8 445 ) 446 447 func (w WaitStatus) Exited() bool { return w&mask == exited } 448 449 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 450 451 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 452 453 func (w WaitStatus) Continued() bool { return w == 0xFFFF } 454 455 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 456 457 func (w WaitStatus) ExitStatus() int { 458 if !w.Exited() { 459 return -1 460 } 461 return int(w>>shift) & 0xFF 462 } 463 464 func (w WaitStatus) Signal() syscall.Signal { 465 if !w.Signaled() { 466 return -1 467 } 468 return syscall.Signal(w & mask) 469 } 470 471 func (w WaitStatus) StopSignal() syscall.Signal { 472 if !w.Stopped() { 473 return -1 474 } 475 return syscall.Signal(w>>shift) & 0xFF 476 } 477 478 func (w WaitStatus) TrapCause() int { 479 if w.StopSignal() != SIGTRAP { 480 return -1 481 } 482 return int(w>>shift) >> 8 483 } 484 485 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 486 487 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 488 var status _C_int 489 wpid, err = wait4(pid, &status, options, rusage) 490 if wstatus != nil { 491 *wstatus = WaitStatus(status) 492 } 493 return 494 } 495 496 func Mkfifo(path string, mode uint32) error { 497 return Mknod(path, mode|S_IFIFO, 0) 498 } 499 500 func Mkfifoat(dirfd int, path string, mode uint32) error { 501 return Mknodat(dirfd, path, mode|S_IFIFO, 0) 502 } 503 504 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 505 if sa.Port < 0 || sa.Port > 0xFFFF { 506 return nil, 0, EINVAL 507 } 508 sa.raw.Family = AF_INET 509 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 510 p[0] = byte(sa.Port >> 8) 511 p[1] = byte(sa.Port) 512 for i := 0; i < len(sa.Addr); i++ { 513 sa.raw.Addr[i] = sa.Addr[i] 514 } 515 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 516 } 517 518 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 519 if sa.Port < 0 || sa.Port > 0xFFFF { 520 return nil, 0, EINVAL 521 } 522 sa.raw.Family = AF_INET6 523 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 524 p[0] = byte(sa.Port >> 8) 525 p[1] = byte(sa.Port) 526 sa.raw.Scope_id = sa.ZoneId 527 for i := 0; i < len(sa.Addr); i++ { 528 sa.raw.Addr[i] = sa.Addr[i] 529 } 530 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 531 } 532 533 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 534 name := sa.Name 535 n := len(name) 536 if n >= len(sa.raw.Path) { 537 return nil, 0, EINVAL 538 } 539 sa.raw.Family = AF_UNIX 540 for i := 0; i < n; i++ { 541 sa.raw.Path[i] = int8(name[i]) 542 } 543 // length is family (uint16), name, NUL. 544 sl := _Socklen(2) 545 if n > 0 { 546 sl += _Socklen(n) + 1 547 } 548 if sa.raw.Path[0] == '@' { 549 sa.raw.Path[0] = 0 550 // Don't count trailing NUL for abstract address. 551 sl-- 552 } 553 554 return unsafe.Pointer(&sa.raw), sl, nil 555 } 556 557 // SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets. 558 type SockaddrLinklayer struct { 559 Protocol uint16 560 Ifindex int 561 Hatype uint16 562 Pkttype uint8 563 Halen uint8 564 Addr [8]byte 565 raw RawSockaddrLinklayer 566 } 567 568 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { 569 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 570 return nil, 0, EINVAL 571 } 572 sa.raw.Family = AF_PACKET 573 sa.raw.Protocol = sa.Protocol 574 sa.raw.Ifindex = int32(sa.Ifindex) 575 sa.raw.Hatype = sa.Hatype 576 sa.raw.Pkttype = sa.Pkttype 577 sa.raw.Halen = sa.Halen 578 for i := 0; i < len(sa.Addr); i++ { 579 sa.raw.Addr[i] = sa.Addr[i] 580 } 581 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil 582 } 583 584 // SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets. 585 type SockaddrNetlink struct { 586 Family uint16 587 Pad uint16 588 Pid uint32 589 Groups uint32 590 raw RawSockaddrNetlink 591 } 592 593 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { 594 sa.raw.Family = AF_NETLINK 595 sa.raw.Pad = sa.Pad 596 sa.raw.Pid = sa.Pid 597 sa.raw.Groups = sa.Groups 598 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil 599 } 600 601 // SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets 602 // using the HCI protocol. 603 type SockaddrHCI struct { 604 Dev uint16 605 Channel uint16 606 raw RawSockaddrHCI 607 } 608 609 func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) { 610 sa.raw.Family = AF_BLUETOOTH 611 sa.raw.Dev = sa.Dev 612 sa.raw.Channel = sa.Channel 613 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil 614 } 615 616 // SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets 617 // using the L2CAP protocol. 618 type SockaddrL2 struct { 619 PSM uint16 620 CID uint16 621 Addr [6]uint8 622 AddrType uint8 623 raw RawSockaddrL2 624 } 625 626 func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { 627 sa.raw.Family = AF_BLUETOOTH 628 psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) 629 psm[0] = byte(sa.PSM) 630 psm[1] = byte(sa.PSM >> 8) 631 for i := 0; i < len(sa.Addr); i++ { 632 sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] 633 } 634 cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) 635 cid[0] = byte(sa.CID) 636 cid[1] = byte(sa.CID >> 8) 637 sa.raw.Bdaddr_type = sa.AddrType 638 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil 639 } 640 641 // SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets 642 // using the RFCOMM protocol. 643 // 644 // Server example: 645 // 646 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) 647 // _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ 648 // Channel: 1, 649 // Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 650 // }) 651 // _ = Listen(fd, 1) 652 // nfd, sa, _ := Accept(fd) 653 // fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) 654 // Read(nfd, buf) 655 // 656 // Client example: 657 // 658 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) 659 // _ = Connect(fd, &SockaddrRFCOMM{ 660 // Channel: 1, 661 // Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 662 // }) 663 // Write(fd, []byte(`hello`)) 664 type SockaddrRFCOMM struct { 665 // Addr represents a bluetooth address, byte ordering is little-endian. 666 Addr [6]uint8 667 668 // Channel is a designated bluetooth channel, only 1-30 are available for use. 669 // Since Linux 2.6.7 and further zero value is the first available channel. 670 Channel uint8 671 672 raw RawSockaddrRFCOMM 673 } 674 675 func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) { 676 sa.raw.Family = AF_BLUETOOTH 677 sa.raw.Channel = sa.Channel 678 sa.raw.Bdaddr = sa.Addr 679 return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil 680 } 681 682 // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets. 683 // The RxID and TxID fields are used for transport protocol addressing in 684 // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with 685 // zero values for CAN_RAW and CAN_BCM sockets as they have no meaning. 686 // 687 // The SockaddrCAN struct must be bound to the socket file descriptor 688 // using Bind before the CAN socket can be used. 689 // 690 // // Read one raw CAN frame 691 // fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW) 692 // addr := &SockaddrCAN{Ifindex: index} 693 // Bind(fd, addr) 694 // frame := make([]byte, 16) 695 // Read(fd, frame) 696 // 697 // The full SocketCAN documentation can be found in the linux kernel 698 // archives at: https://www.kernel.org/doc/Documentation/networking/can.txt 699 type SockaddrCAN struct { 700 Ifindex int 701 RxID uint32 702 TxID uint32 703 raw RawSockaddrCAN 704 } 705 706 func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) { 707 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 708 return nil, 0, EINVAL 709 } 710 sa.raw.Family = AF_CAN 711 sa.raw.Ifindex = int32(sa.Ifindex) 712 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) 713 for i := 0; i < 4; i++ { 714 sa.raw.Addr[i] = rx[i] 715 } 716 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) 717 for i := 0; i < 4; i++ { 718 sa.raw.Addr[i+4] = tx[i] 719 } 720 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil 721 } 722 723 // SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939 724 // protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information 725 // on the purposes of the fields, check the official linux kernel documentation 726 // available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst 727 type SockaddrCANJ1939 struct { 728 Ifindex int 729 Name uint64 730 PGN uint32 731 Addr uint8 732 raw RawSockaddrCAN 733 } 734 735 func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) { 736 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 737 return nil, 0, EINVAL 738 } 739 sa.raw.Family = AF_CAN 740 sa.raw.Ifindex = int32(sa.Ifindex) 741 n := (*[8]byte)(unsafe.Pointer(&sa.Name)) 742 for i := 0; i < 8; i++ { 743 sa.raw.Addr[i] = n[i] 744 } 745 p := (*[4]byte)(unsafe.Pointer(&sa.PGN)) 746 for i := 0; i < 4; i++ { 747 sa.raw.Addr[i+8] = p[i] 748 } 749 sa.raw.Addr[12] = sa.Addr 750 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil 751 } 752 753 // SockaddrALG implements the Sockaddr interface for AF_ALG type sockets. 754 // SockaddrALG enables userspace access to the Linux kernel's cryptography 755 // subsystem. The Type and Name fields specify which type of hash or cipher 756 // should be used with a given socket. 757 // 758 // To create a file descriptor that provides access to a hash or cipher, both 759 // Bind and Accept must be used. Once the setup process is complete, input 760 // data can be written to the socket, processed by the kernel, and then read 761 // back as hash output or ciphertext. 762 // 763 // Here is an example of using an AF_ALG socket with SHA1 hashing. 764 // The initial socket setup process is as follows: 765 // 766 // // Open a socket to perform SHA1 hashing. 767 // fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0) 768 // addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"} 769 // unix.Bind(fd, addr) 770 // // Note: unix.Accept does not work at this time; must invoke accept() 771 // // manually using unix.Syscall. 772 // hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0) 773 // 774 // Once a file descriptor has been returned from Accept, it may be used to 775 // perform SHA1 hashing. The descriptor is not safe for concurrent use, but 776 // may be re-used repeatedly with subsequent Write and Read operations. 777 // 778 // When hashing a small byte slice or string, a single Write and Read may 779 // be used: 780 // 781 // // Assume hashfd is already configured using the setup process. 782 // hash := os.NewFile(hashfd, "sha1") 783 // // Hash an input string and read the results. Each Write discards 784 // // previous hash state. Read always reads the current state. 785 // b := make([]byte, 20) 786 // for i := 0; i < 2; i++ { 787 // io.WriteString(hash, "Hello, world.") 788 // hash.Read(b) 789 // fmt.Println(hex.EncodeToString(b)) 790 // } 791 // // Output: 792 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 793 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 794 // 795 // For hashing larger byte slices, or byte streams such as those read from 796 // a file or socket, use Sendto with MSG_MORE to instruct the kernel to update 797 // the hash digest instead of creating a new one for a given chunk and finalizing it. 798 // 799 // // Assume hashfd and addr are already configured using the setup process. 800 // hash := os.NewFile(hashfd, "sha1") 801 // // Hash the contents of a file. 802 // f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz") 803 // b := make([]byte, 4096) 804 // for { 805 // n, err := f.Read(b) 806 // if err == io.EOF { 807 // break 808 // } 809 // unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr) 810 // } 811 // hash.Read(b) 812 // fmt.Println(hex.EncodeToString(b)) 813 // // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5 814 // 815 // For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html. 816 type SockaddrALG struct { 817 Type string 818 Name string 819 Feature uint32 820 Mask uint32 821 raw RawSockaddrALG 822 } 823 824 func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) { 825 // Leave room for NUL byte terminator. 826 if len(sa.Type) > 13 { 827 return nil, 0, EINVAL 828 } 829 if len(sa.Name) > 63 { 830 return nil, 0, EINVAL 831 } 832 833 sa.raw.Family = AF_ALG 834 sa.raw.Feat = sa.Feature 835 sa.raw.Mask = sa.Mask 836 837 typ, err := ByteSliceFromString(sa.Type) 838 if err != nil { 839 return nil, 0, err 840 } 841 name, err := ByteSliceFromString(sa.Name) 842 if err != nil { 843 return nil, 0, err 844 } 845 846 copy(sa.raw.Type[:], typ) 847 copy(sa.raw.Name[:], name) 848 849 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil 850 } 851 852 // SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets. 853 // SockaddrVM provides access to Linux VM sockets: a mechanism that enables 854 // bidirectional communication between a hypervisor and its guest virtual 855 // machines. 856 type SockaddrVM struct { 857 // CID and Port specify a context ID and port address for a VM socket. 858 // Guests have a unique CID, and hosts may have a well-known CID of: 859 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. 860 // - VMADDR_CID_HOST: refers to other processes on the host. 861 CID uint32 862 Port uint32 863 raw RawSockaddrVM 864 } 865 866 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { 867 sa.raw.Family = AF_VSOCK 868 sa.raw.Port = sa.Port 869 sa.raw.Cid = sa.CID 870 871 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil 872 } 873 874 type SockaddrXDP struct { 875 Flags uint16 876 Ifindex uint32 877 QueueID uint32 878 SharedUmemFD uint32 879 raw RawSockaddrXDP 880 } 881 882 func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) { 883 sa.raw.Family = AF_XDP 884 sa.raw.Flags = sa.Flags 885 sa.raw.Ifindex = sa.Ifindex 886 sa.raw.Queue_id = sa.QueueID 887 sa.raw.Shared_umem_fd = sa.SharedUmemFD 888 889 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil 890 } 891 892 // This constant mirrors the #define of PX_PROTO_OE in 893 // linux/if_pppox.h. We're defining this by hand here instead of 894 // autogenerating through mkerrors.sh because including 895 // linux/if_pppox.h causes some declaration conflicts with other 896 // includes (linux/if_pppox.h includes linux/in.h, which conflicts 897 // with netinet/in.h). Given that we only need a single zero constant 898 // out of that file, it's cleaner to just define it by hand here. 899 const px_proto_oe = 0 900 901 type SockaddrPPPoE struct { 902 SID uint16 903 Remote []byte 904 Dev string 905 raw RawSockaddrPPPoX 906 } 907 908 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { 909 if len(sa.Remote) != 6 { 910 return nil, 0, EINVAL 911 } 912 if len(sa.Dev) > IFNAMSIZ-1 { 913 return nil, 0, EINVAL 914 } 915 916 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX 917 // This next field is in host-endian byte order. We can't use the 918 // same unsafe pointer cast as above, because this value is not 919 // 32-bit aligned and some architectures don't allow unaligned 920 // access. 921 // 922 // However, the value of px_proto_oe is 0, so we can use 923 // encoding/binary helpers to write the bytes without worrying 924 // about the ordering. 925 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe) 926 // This field is deliberately big-endian, unlike the previous 927 // one. The kernel expects SID to be in network byte order. 928 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) 929 copy(sa.raw[8:14], sa.Remote) 930 for i := 14; i < 14+IFNAMSIZ; i++ { 931 sa.raw[i] = 0 932 } 933 copy(sa.raw[14:], sa.Dev) 934 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil 935 } 936 937 // SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets. 938 // For more information on TIPC, see: http://tipc.sourceforge.net/. 939 type SockaddrTIPC struct { 940 // Scope is the publication scopes when binding service/service range. 941 // Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE. 942 Scope int 943 944 // Addr is the type of address used to manipulate a socket. Addr must be 945 // one of: 946 // - *TIPCSocketAddr: "id" variant in the C addr union 947 // - *TIPCServiceRange: "nameseq" variant in the C addr union 948 // - *TIPCServiceName: "name" variant in the C addr union 949 // 950 // If nil, EINVAL will be returned when the structure is used. 951 Addr TIPCAddr 952 953 raw RawSockaddrTIPC 954 } 955 956 // TIPCAddr is implemented by types that can be used as an address for 957 // SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange, 958 // and *TIPCServiceName. 959 type TIPCAddr interface { 960 tipcAddrtype() uint8 961 tipcAddr() [12]byte 962 } 963 964 func (sa *TIPCSocketAddr) tipcAddr() [12]byte { 965 var out [12]byte 966 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:]) 967 return out 968 } 969 970 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR } 971 972 func (sa *TIPCServiceRange) tipcAddr() [12]byte { 973 var out [12]byte 974 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:]) 975 return out 976 } 977 978 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE } 979 980 func (sa *TIPCServiceName) tipcAddr() [12]byte { 981 var out [12]byte 982 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:]) 983 return out 984 } 985 986 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR } 987 988 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) { 989 if sa.Addr == nil { 990 return nil, 0, EINVAL 991 } 992 993 sa.raw.Family = AF_TIPC 994 sa.raw.Scope = int8(sa.Scope) 995 sa.raw.Addrtype = sa.Addr.tipcAddrtype() 996 sa.raw.Addr = sa.Addr.tipcAddr() 997 998 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil 999 } 1000 1001 // SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets. 1002 type SockaddrL2TPIP struct { 1003 Addr [4]byte 1004 ConnId uint32 1005 raw RawSockaddrL2TPIP 1006 } 1007 1008 func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) { 1009 sa.raw.Family = AF_INET 1010 sa.raw.Conn_id = sa.ConnId 1011 for i := 0; i < len(sa.Addr); i++ { 1012 sa.raw.Addr[i] = sa.Addr[i] 1013 } 1014 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil 1015 } 1016 1017 // SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets. 1018 type SockaddrL2TPIP6 struct { 1019 Addr [16]byte 1020 ZoneId uint32 1021 ConnId uint32 1022 raw RawSockaddrL2TPIP6 1023 } 1024 1025 func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) { 1026 sa.raw.Family = AF_INET6 1027 sa.raw.Conn_id = sa.ConnId 1028 sa.raw.Scope_id = sa.ZoneId 1029 for i := 0; i < len(sa.Addr); i++ { 1030 sa.raw.Addr[i] = sa.Addr[i] 1031 } 1032 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil 1033 } 1034 1035 // SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets. 1036 type SockaddrIUCV struct { 1037 UserID string 1038 Name string 1039 raw RawSockaddrIUCV 1040 } 1041 1042 func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { 1043 sa.raw.Family = AF_IUCV 1044 // These are EBCDIC encoded by the kernel, but we still need to pad them 1045 // with blanks. Initializing with blanks allows the caller to feed in either 1046 // a padded or an unpadded string. 1047 for i := 0; i < 8; i++ { 1048 sa.raw.Nodeid[i] = ' ' 1049 sa.raw.User_id[i] = ' ' 1050 sa.raw.Name[i] = ' ' 1051 } 1052 if len(sa.UserID) > 8 || len(sa.Name) > 8 { 1053 return nil, 0, EINVAL 1054 } 1055 for i, b := range []byte(sa.UserID[:]) { 1056 sa.raw.User_id[i] = int8(b) 1057 } 1058 for i, b := range []byte(sa.Name[:]) { 1059 sa.raw.Name[i] = int8(b) 1060 } 1061 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil 1062 } 1063 1064 var socketProtocol = func(fd int) (int, error) { 1065 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) 1066 } 1067 1068 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { 1069 switch rsa.Addr.Family { 1070 case AF_NETLINK: 1071 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 1072 sa := new(SockaddrNetlink) 1073 sa.Family = pp.Family 1074 sa.Pad = pp.Pad 1075 sa.Pid = pp.Pid 1076 sa.Groups = pp.Groups 1077 return sa, nil 1078 1079 case AF_PACKET: 1080 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 1081 sa := new(SockaddrLinklayer) 1082 sa.Protocol = pp.Protocol 1083 sa.Ifindex = int(pp.Ifindex) 1084 sa.Hatype = pp.Hatype 1085 sa.Pkttype = pp.Pkttype 1086 sa.Halen = pp.Halen 1087 for i := 0; i < len(sa.Addr); i++ { 1088 sa.Addr[i] = pp.Addr[i] 1089 } 1090 return sa, nil 1091 1092 case AF_UNIX: 1093 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 1094 sa := new(SockaddrUnix) 1095 if pp.Path[0] == 0 { 1096 // "Abstract" Unix domain socket. 1097 // Rewrite leading NUL as @ for textual display. 1098 // (This is the standard convention.) 1099 // Not friendly to overwrite in place, 1100 // but the callers below don't care. 1101 pp.Path[0] = '@' 1102 } 1103 1104 // Assume path ends at NUL. 1105 // This is not technically the Linux semantics for 1106 // abstract Unix domain sockets--they are supposed 1107 // to be uninterpreted fixed-size binary blobs--but 1108 // everyone uses this convention. 1109 n := 0 1110 for n < len(pp.Path) && pp.Path[n] != 0 { 1111 n++ 1112 } 1113 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 1114 sa.Name = string(bytes) 1115 return sa, nil 1116 1117 case AF_INET: 1118 proto, err := socketProtocol(fd) 1119 if err != nil { 1120 return nil, err 1121 } 1122 1123 switch proto { 1124 case IPPROTO_L2TP: 1125 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa)) 1126 sa := new(SockaddrL2TPIP) 1127 sa.ConnId = pp.Conn_id 1128 for i := 0; i < len(sa.Addr); i++ { 1129 sa.Addr[i] = pp.Addr[i] 1130 } 1131 return sa, nil 1132 default: 1133 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 1134 sa := new(SockaddrInet4) 1135 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 1136 sa.Port = int(p[0])<<8 + int(p[1]) 1137 for i := 0; i < len(sa.Addr); i++ { 1138 sa.Addr[i] = pp.Addr[i] 1139 } 1140 return sa, nil 1141 } 1142 1143 case AF_INET6: 1144 proto, err := socketProtocol(fd) 1145 if err != nil { 1146 return nil, err 1147 } 1148 1149 switch proto { 1150 case IPPROTO_L2TP: 1151 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa)) 1152 sa := new(SockaddrL2TPIP6) 1153 sa.ConnId = pp.Conn_id 1154 sa.ZoneId = pp.Scope_id 1155 for i := 0; i < len(sa.Addr); i++ { 1156 sa.Addr[i] = pp.Addr[i] 1157 } 1158 return sa, nil 1159 default: 1160 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 1161 sa := new(SockaddrInet6) 1162 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 1163 sa.Port = int(p[0])<<8 + int(p[1]) 1164 sa.ZoneId = pp.Scope_id 1165 for i := 0; i < len(sa.Addr); i++ { 1166 sa.Addr[i] = pp.Addr[i] 1167 } 1168 return sa, nil 1169 } 1170 1171 case AF_VSOCK: 1172 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) 1173 sa := &SockaddrVM{ 1174 CID: pp.Cid, 1175 Port: pp.Port, 1176 } 1177 return sa, nil 1178 case AF_BLUETOOTH: 1179 proto, err := socketProtocol(fd) 1180 if err != nil { 1181 return nil, err 1182 } 1183 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections 1184 switch proto { 1185 case BTPROTO_L2CAP: 1186 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa)) 1187 sa := &SockaddrL2{ 1188 PSM: pp.Psm, 1189 CID: pp.Cid, 1190 Addr: pp.Bdaddr, 1191 AddrType: pp.Bdaddr_type, 1192 } 1193 return sa, nil 1194 case BTPROTO_RFCOMM: 1195 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa)) 1196 sa := &SockaddrRFCOMM{ 1197 Channel: pp.Channel, 1198 Addr: pp.Bdaddr, 1199 } 1200 return sa, nil 1201 } 1202 case AF_XDP: 1203 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa)) 1204 sa := &SockaddrXDP{ 1205 Flags: pp.Flags, 1206 Ifindex: pp.Ifindex, 1207 QueueID: pp.Queue_id, 1208 SharedUmemFD: pp.Shared_umem_fd, 1209 } 1210 return sa, nil 1211 case AF_PPPOX: 1212 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa)) 1213 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe { 1214 return nil, EINVAL 1215 } 1216 sa := &SockaddrPPPoE{ 1217 SID: binary.BigEndian.Uint16(pp[6:8]), 1218 Remote: pp[8:14], 1219 } 1220 for i := 14; i < 14+IFNAMSIZ; i++ { 1221 if pp[i] == 0 { 1222 sa.Dev = string(pp[14:i]) 1223 break 1224 } 1225 } 1226 return sa, nil 1227 case AF_TIPC: 1228 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa)) 1229 1230 sa := &SockaddrTIPC{ 1231 Scope: int(pp.Scope), 1232 } 1233 1234 // Determine which union variant is present in pp.Addr by checking 1235 // pp.Addrtype. 1236 switch pp.Addrtype { 1237 case TIPC_SERVICE_RANGE: 1238 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr)) 1239 case TIPC_SERVICE_ADDR: 1240 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr)) 1241 case TIPC_SOCKET_ADDR: 1242 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr)) 1243 default: 1244 return nil, EINVAL 1245 } 1246 1247 return sa, nil 1248 case AF_IUCV: 1249 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa)) 1250 1251 var user [8]byte 1252 var name [8]byte 1253 1254 for i := 0; i < 8; i++ { 1255 user[i] = byte(pp.User_id[i]) 1256 name[i] = byte(pp.Name[i]) 1257 } 1258 1259 sa := &SockaddrIUCV{ 1260 UserID: string(user[:]), 1261 Name: string(name[:]), 1262 } 1263 return sa, nil 1264 1265 case AF_CAN: 1266 proto, err := socketProtocol(fd) 1267 if err != nil { 1268 return nil, err 1269 } 1270 1271 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa)) 1272 1273 switch proto { 1274 case CAN_J1939: 1275 sa := &SockaddrCANJ1939{ 1276 Ifindex: int(pp.Ifindex), 1277 } 1278 name := (*[8]byte)(unsafe.Pointer(&sa.Name)) 1279 for i := 0; i < 8; i++ { 1280 name[i] = pp.Addr[i] 1281 } 1282 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) 1283 for i := 0; i < 4; i++ { 1284 pgn[i] = pp.Addr[i+8] 1285 } 1286 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) 1287 addr[0] = pp.Addr[12] 1288 return sa, nil 1289 default: 1290 sa := &SockaddrCAN{ 1291 Ifindex: int(pp.Ifindex), 1292 } 1293 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) 1294 for i := 0; i < 4; i++ { 1295 rx[i] = pp.Addr[i] 1296 } 1297 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) 1298 for i := 0; i < 4; i++ { 1299 tx[i] = pp.Addr[i+4] 1300 } 1301 return sa, nil 1302 } 1303 } 1304 return nil, EAFNOSUPPORT 1305 } 1306 1307 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 1308 var rsa RawSockaddrAny 1309 var len _Socklen = SizeofSockaddrAny 1310 nfd, err = accept(fd, &rsa, &len) 1311 if err != nil { 1312 return 1313 } 1314 sa, err = anyToSockaddr(fd, &rsa) 1315 if err != nil { 1316 Close(nfd) 1317 nfd = 0 1318 } 1319 return 1320 } 1321 1322 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { 1323 var rsa RawSockaddrAny 1324 var len _Socklen = SizeofSockaddrAny 1325 nfd, err = accept4(fd, &rsa, &len, flags) 1326 if err != nil { 1327 return 1328 } 1329 if len > SizeofSockaddrAny { 1330 panic("RawSockaddrAny too small") 1331 } 1332 sa, err = anyToSockaddr(fd, &rsa) 1333 if err != nil { 1334 Close(nfd) 1335 nfd = 0 1336 } 1337 return 1338 } 1339 1340 func Getsockname(fd int) (sa Sockaddr, err error) { 1341 var rsa RawSockaddrAny 1342 var len _Socklen = SizeofSockaddrAny 1343 if err = getsockname(fd, &rsa, &len); err != nil { 1344 return 1345 } 1346 return anyToSockaddr(fd, &rsa) 1347 } 1348 1349 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 1350 var value IPMreqn 1351 vallen := _Socklen(SizeofIPMreqn) 1352 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1353 return &value, err 1354 } 1355 1356 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { 1357 var value Ucred 1358 vallen := _Socklen(SizeofUcred) 1359 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1360 return &value, err 1361 } 1362 1363 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { 1364 var value TCPInfo 1365 vallen := _Socklen(SizeofTCPInfo) 1366 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1367 return &value, err 1368 } 1369 1370 // GetsockoptString returns the string value of the socket option opt for the 1371 // socket associated with fd at the given socket level. 1372 func GetsockoptString(fd, level, opt int) (string, error) { 1373 buf := make([]byte, 256) 1374 vallen := _Socklen(len(buf)) 1375 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 1376 if err != nil { 1377 if err == ERANGE { 1378 buf = make([]byte, vallen) 1379 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 1380 } 1381 if err != nil { 1382 return "", err 1383 } 1384 } 1385 return string(buf[:vallen-1]), nil 1386 } 1387 1388 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) { 1389 var value TpacketStats 1390 vallen := _Socklen(SizeofTpacketStats) 1391 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1392 return &value, err 1393 } 1394 1395 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) { 1396 var value TpacketStatsV3 1397 vallen := _Socklen(SizeofTpacketStatsV3) 1398 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1399 return &value, err 1400 } 1401 1402 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 1403 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 1404 } 1405 1406 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error { 1407 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 1408 } 1409 1410 // SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a 1411 // socket to filter incoming packets. See 'man 7 socket' for usage information. 1412 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error { 1413 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog)) 1414 } 1415 1416 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error { 1417 var p unsafe.Pointer 1418 if len(filter) > 0 { 1419 p = unsafe.Pointer(&filter[0]) 1420 } 1421 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter)) 1422 } 1423 1424 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error { 1425 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) 1426 } 1427 1428 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { 1429 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) 1430 } 1431 1432 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) 1433 1434 // KeyctlInt calls keyctl commands in which each argument is an int. 1435 // These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK, 1436 // KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT, 1437 // KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT, 1438 // KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT. 1439 //sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL 1440 1441 // KeyctlBuffer calls keyctl commands in which the third and fourth 1442 // arguments are a buffer and its length, respectively. 1443 // These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE. 1444 //sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL 1445 1446 // KeyctlString calls keyctl commands which return a string. 1447 // These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY. 1448 func KeyctlString(cmd int, id int) (string, error) { 1449 // We must loop as the string data may change in between the syscalls. 1450 // We could allocate a large buffer here to reduce the chance that the 1451 // syscall needs to be called twice; however, this is unnecessary as 1452 // the performance loss is negligible. 1453 var buffer []byte 1454 for { 1455 // Try to fill the buffer with data 1456 length, err := KeyctlBuffer(cmd, id, buffer, 0) 1457 if err != nil { 1458 return "", err 1459 } 1460 1461 // Check if the data was written 1462 if length <= len(buffer) { 1463 // Exclude the null terminator 1464 return string(buffer[:length-1]), nil 1465 } 1466 1467 // Make a bigger buffer if needed 1468 buffer = make([]byte, length) 1469 } 1470 } 1471 1472 // Keyctl commands with special signatures. 1473 1474 // KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command. 1475 // See the full documentation at: 1476 // http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html 1477 func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) { 1478 createInt := 0 1479 if create { 1480 createInt = 1 1481 } 1482 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0) 1483 } 1484 1485 // KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the 1486 // key handle permission mask as described in the "keyctl setperm" section of 1487 // http://man7.org/linux/man-pages/man1/keyctl.1.html. 1488 // See the full documentation at: 1489 // http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html 1490 func KeyctlSetperm(id int, perm uint32) error { 1491 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0) 1492 return err 1493 } 1494 1495 //sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL 1496 1497 // KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command. 1498 // See the full documentation at: 1499 // http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html 1500 func KeyctlJoinSessionKeyring(name string) (ringid int, err error) { 1501 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name) 1502 } 1503 1504 //sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL 1505 1506 // KeyctlSearch implements the KEYCTL_SEARCH command. 1507 // See the full documentation at: 1508 // http://man7.org/linux/man-pages/man3/keyctl_search.3.html 1509 func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) { 1510 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid) 1511 } 1512 1513 //sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL 1514 1515 // KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This 1516 // command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice 1517 // of Iovec (each of which represents a buffer) instead of a single buffer. 1518 // See the full documentation at: 1519 // http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html 1520 func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error { 1521 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid) 1522 } 1523 1524 //sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL 1525 1526 // KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command 1527 // computes a Diffie-Hellman shared secret based on the provide params. The 1528 // secret is written to the provided buffer and the returned size is the number 1529 // of bytes written (returning an error if there is insufficient space in the 1530 // buffer). If a nil buffer is passed in, this function returns the minimum 1531 // buffer length needed to store the appropriate data. Note that this differs 1532 // from KEYCTL_READ's behavior which always returns the requested payload size. 1533 // See the full documentation at: 1534 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html 1535 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) { 1536 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) 1537 } 1538 1539 // KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This 1540 // command limits the set of keys that can be linked to the keyring, regardless 1541 // of keyring permissions. The command requires the "setattr" permission. 1542 // 1543 // When called with an empty keyType the command locks the keyring, preventing 1544 // any further keys from being linked to the keyring. 1545 // 1546 // The "asymmetric" keyType defines restrictions requiring key payloads to be 1547 // DER encoded X.509 certificates signed by keys in another keyring. Restrictions 1548 // for "asymmetric" include "builtin_trusted", "builtin_and_secondary_trusted", 1549 // "key_or_keyring:<key>", and "key_or_keyring:<key>:chain". 1550 // 1551 // As of Linux 4.12, only the "asymmetric" keyType defines type-specific 1552 // restrictions. 1553 // 1554 // See the full documentation at: 1555 // http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html 1556 // http://man7.org/linux/man-pages/man2/keyctl.2.html 1557 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error { 1558 if keyType == "" { 1559 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid) 1560 } 1561 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction) 1562 } 1563 1564 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL 1565 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL 1566 1567 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 1568 var msg Msghdr 1569 var rsa RawSockaddrAny 1570 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 1571 msg.Namelen = uint32(SizeofSockaddrAny) 1572 var iov Iovec 1573 if len(p) > 0 { 1574 iov.Base = &p[0] 1575 iov.SetLen(len(p)) 1576 } 1577 var dummy byte 1578 if len(oob) > 0 { 1579 if len(p) == 0 { 1580 var sockType int 1581 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1582 if err != nil { 1583 return 1584 } 1585 // receive at least one normal byte 1586 if sockType != SOCK_DGRAM { 1587 iov.Base = &dummy 1588 iov.SetLen(1) 1589 } 1590 } 1591 msg.Control = &oob[0] 1592 msg.SetControllen(len(oob)) 1593 } 1594 msg.Iov = &iov 1595 msg.Iovlen = 1 1596 if n, err = recvmsg(fd, &msg, flags); err != nil { 1597 return 1598 } 1599 oobn = int(msg.Controllen) 1600 recvflags = int(msg.Flags) 1601 // source address is only specified if the socket is unconnected 1602 if rsa.Addr.Family != AF_UNSPEC { 1603 from, err = anyToSockaddr(fd, &rsa) 1604 } 1605 return 1606 } 1607 1608 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 1609 _, err = SendmsgN(fd, p, oob, to, flags) 1610 return 1611 } 1612 1613 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 1614 var ptr unsafe.Pointer 1615 var salen _Socklen 1616 if to != nil { 1617 var err error 1618 ptr, salen, err = to.sockaddr() 1619 if err != nil { 1620 return 0, err 1621 } 1622 } 1623 var msg Msghdr 1624 msg.Name = (*byte)(ptr) 1625 msg.Namelen = uint32(salen) 1626 var iov Iovec 1627 if len(p) > 0 { 1628 iov.Base = &p[0] 1629 iov.SetLen(len(p)) 1630 } 1631 var dummy byte 1632 if len(oob) > 0 { 1633 if len(p) == 0 { 1634 var sockType int 1635 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1636 if err != nil { 1637 return 0, err 1638 } 1639 // send at least one normal byte 1640 if sockType != SOCK_DGRAM { 1641 iov.Base = &dummy 1642 iov.SetLen(1) 1643 } 1644 } 1645 msg.Control = &oob[0] 1646 msg.SetControllen(len(oob)) 1647 } 1648 msg.Iov = &iov 1649 msg.Iovlen = 1 1650 if n, err = sendmsg(fd, &msg, flags); err != nil { 1651 return 0, err 1652 } 1653 if len(oob) > 0 && len(p) == 0 { 1654 n = 0 1655 } 1656 return n, nil 1657 } 1658 1659 // BindToDevice binds the socket associated with fd to device. 1660 func BindToDevice(fd int, device string) (err error) { 1661 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 1662 } 1663 1664 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 1665 1666 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 1667 // The peek requests are machine-size oriented, so we wrap it 1668 // to retrieve arbitrary-length data. 1669 1670 // The ptrace syscall differs from glibc's ptrace. 1671 // Peeks returns the word in *data, not as the return value. 1672 1673 var buf [SizeofPtr]byte 1674 1675 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 1676 // access (PEEKUSER warns that it might), but if we don't 1677 // align our reads, we might straddle an unmapped page 1678 // boundary and not get the bytes leading up to the page 1679 // boundary. 1680 n := 0 1681 if addr%SizeofPtr != 0 { 1682 err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 1683 if err != nil { 1684 return 0, err 1685 } 1686 n += copy(out, buf[addr%SizeofPtr:]) 1687 out = out[n:] 1688 } 1689 1690 // Remainder. 1691 for len(out) > 0 { 1692 // We use an internal buffer to guarantee alignment. 1693 // It's not documented if this is necessary, but we're paranoid. 1694 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 1695 if err != nil { 1696 return n, err 1697 } 1698 copied := copy(out, buf[0:]) 1699 n += copied 1700 out = out[copied:] 1701 } 1702 1703 return n, nil 1704 } 1705 1706 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 1707 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 1708 } 1709 1710 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 1711 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 1712 } 1713 1714 func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) { 1715 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out) 1716 } 1717 1718 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 1719 // As for ptracePeek, we need to align our accesses to deal 1720 // with the possibility of straddling an invalid page. 1721 1722 // Leading edge. 1723 n := 0 1724 if addr%SizeofPtr != 0 { 1725 var buf [SizeofPtr]byte 1726 err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 1727 if err != nil { 1728 return 0, err 1729 } 1730 n += copy(buf[addr%SizeofPtr:], data) 1731 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1732 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word) 1733 if err != nil { 1734 return 0, err 1735 } 1736 data = data[n:] 1737 } 1738 1739 // Interior. 1740 for len(data) > SizeofPtr { 1741 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 1742 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1743 if err != nil { 1744 return n, err 1745 } 1746 n += SizeofPtr 1747 data = data[SizeofPtr:] 1748 } 1749 1750 // Trailing edge. 1751 if len(data) > 0 { 1752 var buf [SizeofPtr]byte 1753 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 1754 if err != nil { 1755 return n, err 1756 } 1757 copy(buf[0:], data) 1758 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1759 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1760 if err != nil { 1761 return n, err 1762 } 1763 n += len(data) 1764 } 1765 1766 return n, nil 1767 } 1768 1769 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 1770 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 1771 } 1772 1773 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 1774 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 1775 } 1776 1777 func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { 1778 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) 1779 } 1780 1781 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 1782 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) 1783 } 1784 1785 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 1786 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) 1787 } 1788 1789 func PtraceSetOptions(pid int, options int) (err error) { 1790 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 1791 } 1792 1793 func PtraceGetEventMsg(pid int) (msg uint, err error) { 1794 var data _C_long 1795 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) 1796 msg = uint(data) 1797 return 1798 } 1799 1800 func PtraceCont(pid int, signal int) (err error) { 1801 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 1802 } 1803 1804 func PtraceSyscall(pid int, signal int) (err error) { 1805 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) 1806 } 1807 1808 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 1809 1810 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) } 1811 1812 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 1813 1814 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) } 1815 1816 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 1817 1818 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 1819 1820 func Reboot(cmd int) (err error) { 1821 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 1822 } 1823 1824 func direntIno(buf []byte) (uint64, bool) { 1825 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 1826 } 1827 1828 func direntReclen(buf []byte) (uint64, bool) { 1829 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 1830 } 1831 1832 func direntNamlen(buf []byte) (uint64, bool) { 1833 reclen, ok := direntReclen(buf) 1834 if !ok { 1835 return 0, false 1836 } 1837 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 1838 } 1839 1840 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 1841 1842 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 1843 // Certain file systems get rather angry and EINVAL if you give 1844 // them an empty string of data, rather than NULL. 1845 if data == "" { 1846 return mount(source, target, fstype, flags, nil) 1847 } 1848 datap, err := BytePtrFromString(data) 1849 if err != nil { 1850 return err 1851 } 1852 return mount(source, target, fstype, flags, datap) 1853 } 1854 1855 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 1856 if raceenabled { 1857 raceReleaseMerge(unsafe.Pointer(&ioSync)) 1858 } 1859 return sendfile(outfd, infd, offset, count) 1860 } 1861 1862 // Sendto 1863 // Recvfrom 1864 // Socketpair 1865 1866 /* 1867 * Direct access 1868 */ 1869 //sys Acct(path string) (err error) 1870 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) 1871 //sys Adjtimex(buf *Timex) (state int, err error) 1872 //sysnb Capget(hdr *CapUserHeader, data *CapUserData) (err error) 1873 //sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error) 1874 //sys Chdir(path string) (err error) 1875 //sys Chroot(path string) (err error) 1876 //sys ClockGetres(clockid int32, res *Timespec) (err error) 1877 //sys ClockGettime(clockid int32, time *Timespec) (err error) 1878 //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) 1879 //sys Close(fd int) (err error) 1880 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) 1881 //sys DeleteModule(name string, flags int) (err error) 1882 //sys Dup(oldfd int) (fd int, err error) 1883 1884 func Dup2(oldfd, newfd int) error { 1885 // Android O and newer blocks dup2; riscv and arm64 don't implement dup2. 1886 if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" { 1887 return Dup3(oldfd, newfd, 0) 1888 } 1889 return dup2(oldfd, newfd) 1890 } 1891 1892 //sys Dup3(oldfd int, newfd int, flags int) (err error) 1893 //sysnb EpollCreate1(flag int) (fd int, err error) 1894 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 1895 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 1896 //sys Exit(code int) = SYS_EXIT_GROUP 1897 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 1898 //sys Fchdir(fd int) (err error) 1899 //sys Fchmod(fd int, mode uint32) (err error) 1900 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 1901 //sys Fdatasync(fd int) (err error) 1902 //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) 1903 //sys FinitModule(fd int, params string, flags int) (err error) 1904 //sys Flistxattr(fd int, dest []byte) (sz int, err error) 1905 //sys Flock(fd int, how int) (err error) 1906 //sys Fremovexattr(fd int, attr string) (err error) 1907 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) 1908 //sys Fsync(fd int) (err error) 1909 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 1910 //sysnb Getpgid(pid int) (pgid int, err error) 1911 1912 func Getpgrp() (pid int) { 1913 pid, _ = Getpgid(0) 1914 return 1915 } 1916 1917 //sysnb Getpid() (pid int) 1918 //sysnb Getppid() (ppid int) 1919 //sys Getpriority(which int, who int) (prio int, err error) 1920 //sys Getrandom(buf []byte, flags int) (n int, err error) 1921 //sysnb Getrusage(who int, rusage *Rusage) (err error) 1922 //sysnb Getsid(pid int) (sid int, err error) 1923 //sysnb Gettid() (tid int) 1924 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) 1925 //sys InitModule(moduleImage []byte, params string) (err error) 1926 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 1927 //sysnb InotifyInit1(flags int) (fd int, err error) 1928 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 1929 //sysnb Kill(pid int, sig syscall.Signal) (err error) 1930 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 1931 //sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error) 1932 //sys Listxattr(path string, dest []byte) (sz int, err error) 1933 //sys Llistxattr(path string, dest []byte) (sz int, err error) 1934 //sys Lremovexattr(path string, attr string) (err error) 1935 //sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) 1936 //sys MemfdCreate(name string, flags int) (fd int, err error) 1937 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 1938 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 1939 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 1940 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) 1941 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 1942 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 1943 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) 1944 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 1945 //sys read(fd int, p []byte) (n int, err error) 1946 //sys Removexattr(path string, attr string) (err error) 1947 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) 1948 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) 1949 //sys Setdomainname(p []byte) (err error) 1950 //sys Sethostname(p []byte) (err error) 1951 //sysnb Setpgid(pid int, pgid int) (err error) 1952 //sysnb Setsid() (pid int, err error) 1953 //sysnb Settimeofday(tv *Timeval) (err error) 1954 //sys Setns(fd int, nstype int) (err error) 1955 1956 // PrctlRetInt performs a prctl operation specified by option and further 1957 // optional arguments arg2 through arg5 depending on option. It returns a 1958 // non-negative integer that is returned by the prctl syscall. 1959 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) { 1960 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) 1961 if err != 0 { 1962 return 0, err 1963 } 1964 return int(ret), nil 1965 } 1966 1967 // issue 1435. 1968 // On linux Setuid and Setgid only affects the current thread, not the process. 1969 // This does not match what most callers expect so we must return an error 1970 // here rather than letting the caller think that the call succeeded. 1971 1972 func Setuid(uid int) (err error) { 1973 return EOPNOTSUPP 1974 } 1975 1976 func Setgid(uid int) (err error) { 1977 return EOPNOTSUPP 1978 } 1979 1980 // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set. 1981 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability. 1982 // If the call fails due to other reasons, current fsgid will be returned. 1983 func SetfsgidRetGid(gid int) (int, error) { 1984 return setfsgid(gid) 1985 } 1986 1987 // SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set. 1988 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability 1989 // If the call fails due to other reasons, current fsuid will be returned. 1990 func SetfsuidRetUid(uid int) (int, error) { 1991 return setfsuid(uid) 1992 } 1993 1994 func Setfsgid(gid int) error { 1995 _, err := setfsgid(gid) 1996 return err 1997 } 1998 1999 func Setfsuid(uid int) error { 2000 _, err := setfsuid(uid) 2001 return err 2002 } 2003 2004 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { 2005 return signalfd(fd, sigmask, _C__NSIG/8, flags) 2006 } 2007 2008 //sys Setpriority(which int, who int, prio int) (err error) 2009 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) 2010 //sys signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4 2011 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) 2012 //sys Sync() 2013 //sys Syncfs(fd int) (err error) 2014 //sysnb Sysinfo(info *Sysinfo_t) (err error) 2015 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 2016 //sysnb TimerfdCreate(clockid int, flags int) (fd int, err error) 2017 //sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error) 2018 //sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) 2019 //sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) 2020 //sysnb Times(tms *Tms) (ticks uintptr, err error) 2021 //sysnb Umask(mask int) (oldmask int) 2022 //sysnb Uname(buf *Utsname) (err error) 2023 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 2024 //sys Unshare(flags int) (err error) 2025 //sys write(fd int, p []byte) (n int, err error) 2026 //sys exitThread(code int) (err error) = SYS_EXIT 2027 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ 2028 //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE 2029 //sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV 2030 //sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV 2031 //sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV 2032 //sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV 2033 //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 2034 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 2035 2036 func bytes2iovec(bs [][]byte) []Iovec { 2037 iovecs := make([]Iovec, len(bs)) 2038 for i, b := range bs { 2039 iovecs[i].SetLen(len(b)) 2040 if len(b) > 0 { 2041 iovecs[i].Base = &b[0] 2042 } else { 2043 iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero)) 2044 } 2045 } 2046 return iovecs 2047 } 2048 2049 // offs2lohi splits offs into its lower and upper unsigned long. On 64-bit 2050 // systems, hi will always be 0. On 32-bit systems, offs will be split in half. 2051 // preadv/pwritev chose this calling convention so they don't need to add a 2052 // padding-register for alignment on ARM. 2053 func offs2lohi(offs int64) (lo, hi uintptr) { 2054 return uintptr(offs), uintptr(uint64(offs) >> SizeofLong) 2055 } 2056 2057 func Readv(fd int, iovs [][]byte) (n int, err error) { 2058 iovecs := bytes2iovec(iovs) 2059 n, err = readv(fd, iovecs) 2060 readvRacedetect(iovecs, n, err) 2061 return n, err 2062 } 2063 2064 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { 2065 iovecs := bytes2iovec(iovs) 2066 lo, hi := offs2lohi(offset) 2067 n, err = preadv(fd, iovecs, lo, hi) 2068 readvRacedetect(iovecs, n, err) 2069 return n, err 2070 } 2071 2072 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { 2073 iovecs := bytes2iovec(iovs) 2074 lo, hi := offs2lohi(offset) 2075 n, err = preadv2(fd, iovecs, lo, hi, flags) 2076 readvRacedetect(iovecs, n, err) 2077 return n, err 2078 } 2079 2080 func readvRacedetect(iovecs []Iovec, n int, err error) { 2081 if !raceenabled { 2082 return 2083 } 2084 for i := 0; n > 0 && i < len(iovecs); i++ { 2085 m := int(iovecs[i].Len) 2086 if m > n { 2087 m = n 2088 } 2089 n -= m 2090 if m > 0 { 2091 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) 2092 } 2093 } 2094 if err == nil { 2095 raceAcquire(unsafe.Pointer(&ioSync)) 2096 } 2097 } 2098 2099 func Writev(fd int, iovs [][]byte) (n int, err error) { 2100 iovecs := bytes2iovec(iovs) 2101 if raceenabled { 2102 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2103 } 2104 n, err = writev(fd, iovecs) 2105 writevRacedetect(iovecs, n) 2106 return n, err 2107 } 2108 2109 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { 2110 iovecs := bytes2iovec(iovs) 2111 if raceenabled { 2112 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2113 } 2114 lo, hi := offs2lohi(offset) 2115 n, err = pwritev(fd, iovecs, lo, hi) 2116 writevRacedetect(iovecs, n) 2117 return n, err 2118 } 2119 2120 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { 2121 iovecs := bytes2iovec(iovs) 2122 if raceenabled { 2123 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2124 } 2125 lo, hi := offs2lohi(offset) 2126 n, err = pwritev2(fd, iovecs, lo, hi, flags) 2127 writevRacedetect(iovecs, n) 2128 return n, err 2129 } 2130 2131 func writevRacedetect(iovecs []Iovec, n int) { 2132 if !raceenabled { 2133 return 2134 } 2135 for i := 0; n > 0 && i < len(iovecs); i++ { 2136 m := int(iovecs[i].Len) 2137 if m > n { 2138 m = n 2139 } 2140 n -= m 2141 if m > 0 { 2142 raceReadRange(unsafe.Pointer(iovecs[i].Base), m) 2143 } 2144 } 2145 } 2146 2147 // mmap varies by architecture; see syscall_linux_*.go. 2148 //sys munmap(addr uintptr, length uintptr) (err error) 2149 2150 var mapper = &mmapper{ 2151 active: make(map[*byte][]byte), 2152 mmap: mmap, 2153 munmap: munmap, 2154 } 2155 2156 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 2157 return mapper.Mmap(fd, offset, length, prot, flags) 2158 } 2159 2160 func Munmap(b []byte) (err error) { 2161 return mapper.Munmap(b) 2162 } 2163 2164 //sys Madvise(b []byte, advice int) (err error) 2165 //sys Mprotect(b []byte, prot int) (err error) 2166 //sys Mlock(b []byte) (err error) 2167 //sys Mlockall(flags int) (err error) 2168 //sys Msync(b []byte, flags int) (err error) 2169 //sys Munlock(b []byte) (err error) 2170 //sys Munlockall() (err error) 2171 2172 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, 2173 // using the specified flags. 2174 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { 2175 var p unsafe.Pointer 2176 if len(iovs) > 0 { 2177 p = unsafe.Pointer(&iovs[0]) 2178 } 2179 2180 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0) 2181 if errno != 0 { 2182 return 0, syscall.Errno(errno) 2183 } 2184 2185 return int(n), nil 2186 } 2187 2188 func isGroupMember(gid int) bool { 2189 groups, err := Getgroups() 2190 if err != nil { 2191 return false 2192 } 2193 2194 for _, g := range groups { 2195 if g == gid { 2196 return true 2197 } 2198 } 2199 return false 2200 } 2201 2202 //sys faccessat(dirfd int, path string, mode uint32) (err error) 2203 //sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) 2204 2205 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { 2206 if flags == 0 { 2207 return faccessat(dirfd, path, mode) 2208 } 2209 2210 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM { 2211 return err 2212 } 2213 2214 // The Linux kernel faccessat system call does not take any flags. 2215 // The glibc faccessat implements the flags itself; see 2216 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD 2217 // Because people naturally expect syscall.Faccessat to act 2218 // like C faccessat, we do the same. 2219 2220 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { 2221 return EINVAL 2222 } 2223 2224 var st Stat_t 2225 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { 2226 return err 2227 } 2228 2229 mode &= 7 2230 if mode == 0 { 2231 return nil 2232 } 2233 2234 var uid int 2235 if flags&AT_EACCESS != 0 { 2236 uid = Geteuid() 2237 } else { 2238 uid = Getuid() 2239 } 2240 2241 if uid == 0 { 2242 if mode&1 == 0 { 2243 // Root can read and write any file. 2244 return nil 2245 } 2246 if st.Mode&0111 != 0 { 2247 // Root can execute any file that anybody can execute. 2248 return nil 2249 } 2250 return EACCES 2251 } 2252 2253 var fmode uint32 2254 if uint32(uid) == st.Uid { 2255 fmode = (st.Mode >> 6) & 7 2256 } else { 2257 var gid int 2258 if flags&AT_EACCESS != 0 { 2259 gid = Getegid() 2260 } else { 2261 gid = Getgid() 2262 } 2263 2264 if uint32(gid) == st.Gid || isGroupMember(gid) { 2265 fmode = (st.Mode >> 3) & 7 2266 } else { 2267 fmode = st.Mode & 7 2268 } 2269 } 2270 2271 if fmode&mode == mode { 2272 return nil 2273 } 2274 2275 return EACCES 2276 } 2277 2278 //sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT 2279 //sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT 2280 2281 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We 2282 // originally tried to generate it via unix/linux/types.go with "type 2283 // fileHandle C.struct_file_handle" but that generated empty structs 2284 // for mips64 and mips64le. Instead, hard code it for now (it's the 2285 // same everywhere else) until the mips64 generator issue is fixed. 2286 type fileHandle struct { 2287 Bytes uint32 2288 Type int32 2289 } 2290 2291 // FileHandle represents the C struct file_handle used by 2292 // name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see 2293 // OpenByHandleAt). 2294 type FileHandle struct { 2295 *fileHandle 2296 } 2297 2298 // NewFileHandle constructs a FileHandle. 2299 func NewFileHandle(handleType int32, handle []byte) FileHandle { 2300 const hdrSize = unsafe.Sizeof(fileHandle{}) 2301 buf := make([]byte, hdrSize+uintptr(len(handle))) 2302 copy(buf[hdrSize:], handle) 2303 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) 2304 fh.Type = handleType 2305 fh.Bytes = uint32(len(handle)) 2306 return FileHandle{fh} 2307 } 2308 2309 func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) } 2310 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type } 2311 func (fh *FileHandle) Bytes() []byte { 2312 n := fh.Size() 2313 if n == 0 { 2314 return nil 2315 } 2316 return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n] 2317 } 2318 2319 // NameToHandleAt wraps the name_to_handle_at system call; it obtains 2320 // a handle for a path name. 2321 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) { 2322 var mid _C_int 2323 // Try first with a small buffer, assuming the handle will 2324 // only be 32 bytes. 2325 size := uint32(32 + unsafe.Sizeof(fileHandle{})) 2326 didResize := false 2327 for { 2328 buf := make([]byte, size) 2329 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) 2330 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{})) 2331 err = nameToHandleAt(dirfd, path, fh, &mid, flags) 2332 if err == EOVERFLOW { 2333 if didResize { 2334 // We shouldn't need to resize more than once 2335 return 2336 } 2337 didResize = true 2338 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{})) 2339 continue 2340 } 2341 if err != nil { 2342 return 2343 } 2344 return FileHandle{fh}, int(mid), nil 2345 } 2346 } 2347 2348 // OpenByHandleAt wraps the open_by_handle_at system call; it opens a 2349 // file via a handle as previously returned by NameToHandleAt. 2350 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) { 2351 return openByHandleAt(mountFD, handle.fileHandle, flags) 2352 } 2353 2354 // Klogset wraps the sys_syslog system call; it sets console_loglevel to 2355 // the value specified by arg and passes a dummy pointer to bufp. 2356 func Klogset(typ int, arg int) (err error) { 2357 var p unsafe.Pointer 2358 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg)) 2359 if errno != 0 { 2360 return errnoErr(errno) 2361 } 2362 return nil 2363 } 2364 2365 // RemoteIovec is Iovec with the pointer replaced with an integer. 2366 // It is used for ProcessVMReadv and ProcessVMWritev, where the pointer 2367 // refers to a location in a different process' address space, which 2368 // would confuse the Go garbage collector. 2369 type RemoteIovec struct { 2370 Base uintptr 2371 Len int 2372 } 2373 2374 //sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV 2375 //sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV 2376 2377 /* 2378 * Unimplemented 2379 */ 2380 // AfsSyscall 2381 // Alarm 2382 // ArchPrctl 2383 // Brk 2384 // ClockNanosleep 2385 // ClockSettime 2386 // Clone 2387 // EpollCtlOld 2388 // EpollPwait 2389 // EpollWaitOld 2390 // Execve 2391 // Fork 2392 // Futex 2393 // GetKernelSyms 2394 // GetMempolicy 2395 // GetRobustList 2396 // GetThreadArea 2397 // Getitimer 2398 // Getpmsg 2399 // IoCancel 2400 // IoDestroy 2401 // IoGetevents 2402 // IoSetup 2403 // IoSubmit 2404 // IoprioGet 2405 // IoprioSet 2406 // KexecLoad 2407 // LookupDcookie 2408 // Mbind 2409 // MigratePages 2410 // Mincore 2411 // ModifyLdt 2412 // Mount 2413 // MovePages 2414 // MqGetsetattr 2415 // MqNotify 2416 // MqOpen 2417 // MqTimedreceive 2418 // MqTimedsend 2419 // MqUnlink 2420 // Mremap 2421 // Msgctl 2422 // Msgget 2423 // Msgrcv 2424 // Msgsnd 2425 // Nfsservctl 2426 // Personality 2427 // Pselect6 2428 // Ptrace 2429 // Putpmsg 2430 // Quotactl 2431 // Readahead 2432 // Readv 2433 // RemapFilePages 2434 // RestartSyscall 2435 // RtSigaction 2436 // RtSigpending 2437 // RtSigprocmask 2438 // RtSigqueueinfo 2439 // RtSigreturn 2440 // RtSigsuspend 2441 // RtSigtimedwait 2442 // SchedGetPriorityMax 2443 // SchedGetPriorityMin 2444 // SchedGetparam 2445 // SchedGetscheduler 2446 // SchedRrGetInterval 2447 // SchedSetparam 2448 // SchedYield 2449 // Security 2450 // Semctl 2451 // Semget 2452 // Semop 2453 // Semtimedop 2454 // SetMempolicy 2455 // SetRobustList 2456 // SetThreadArea 2457 // SetTidAddress 2458 // Shmat 2459 // Shmctl 2460 // Shmdt 2461 // Shmget 2462 // Sigaltstack 2463 // Swapoff 2464 // Swapon 2465 // Sysfs 2466 // TimerCreate 2467 // TimerDelete 2468 // TimerGetoverrun 2469 // TimerGettime 2470 // TimerSettime 2471 // Tkill (obsolete) 2472 // Tuxcall 2473 // Umount2 2474 // Uselib 2475 // Utimensat 2476 // Vfork 2477 // Vhangup 2478 // Vserver 2479 // Waitid 2480 // _Sysctl