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