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