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