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