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