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