blob: 1b7d59d8963bf4f634b06968420a632eb5b77e8e [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -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 "syscall"
16 "unsafe"
17)
18
19/*
20 * Wrapped
21 */
22
23func Access(path string, mode uint32) (err error) {
24 return Faccessat(AT_FDCWD, path, mode, 0)
25}
26
27func Chmod(path string, mode uint32) (err error) {
28 return Fchmodat(AT_FDCWD, path, mode, 0)
29}
30
31func Chown(path string, uid int, gid int) (err error) {
32 return Fchownat(AT_FDCWD, path, uid, gid, 0)
33}
34
35func Creat(path string, mode uint32) (fd int, err error) {
36 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
37}
38
39//sys fchmodat(dirfd int, path string, mode uint32) (err error)
40
41func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
42 // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
43 // and check the flags. Otherwise the mode would be applied to the symlink
44 // destination which is not what the user expects.
45 if flags&^AT_SYMLINK_NOFOLLOW != 0 {
46 return EINVAL
47 } else if flags&AT_SYMLINK_NOFOLLOW != 0 {
48 return EOPNOTSUPP
49 }
50 return fchmodat(dirfd, path, mode)
51}
52
53//sys ioctl(fd int, req uint, arg uintptr) (err error)
54
55// ioctl itself should not be exposed directly, but additional get/set
56// functions for specific types are permissible.
57
58// IoctlSetInt performs an ioctl operation which sets an integer value
59// on fd, using the specified request number.
60func IoctlSetInt(fd int, req uint, value int) error {
61 return ioctl(fd, req, uintptr(value))
62}
63
64func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
65 return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
66}
67
68func IoctlSetTermios(fd int, req uint, value *Termios) error {
69 return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
70}
71
72// IoctlGetInt performs an ioctl operation which gets an integer value
73// from fd, using the specified request number.
74func IoctlGetInt(fd int, req uint) (int, error) {
75 var value int
76 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
77 return value, err
78}
79
80func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
81 var value Winsize
82 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
83 return &value, err
84}
85
86func IoctlGetTermios(fd int, req uint) (*Termios, error) {
87 var value Termios
88 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
89 return &value, err
90}
91
92//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
93
94func Link(oldpath string, newpath string) (err error) {
95 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)
96}
97
98func Mkdir(path string, mode uint32) (err error) {
99 return Mkdirat(AT_FDCWD, path, mode)
100}
101
102func Mknod(path string, mode uint32, dev int) (err error) {
103 return Mknodat(AT_FDCWD, path, mode, dev)
104}
105
106func Open(path string, mode int, perm uint32) (fd int, err error) {
107 return openat(AT_FDCWD, path, mode|O_LARGEFILE, perm)
108}
109
110//sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
111
112func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
113 return openat(dirfd, path, flags|O_LARGEFILE, mode)
114}
115
116//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
117
118func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
119 if len(fds) == 0 {
120 return ppoll(nil, 0, timeout, sigmask)
121 }
122 return ppoll(&fds[0], len(fds), timeout, sigmask)
123}
124
125//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
126
127func Readlink(path string, buf []byte) (n int, err error) {
128 return Readlinkat(AT_FDCWD, path, buf)
129}
130
131func Rename(oldpath string, newpath string) (err error) {
132 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath)
133}
134
135func Rmdir(path string) error {
136 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
137}
138
139//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
140
141func Symlink(oldpath string, newpath string) (err error) {
142 return Symlinkat(oldpath, AT_FDCWD, newpath)
143}
144
145func Unlink(path string) error {
146 return Unlinkat(AT_FDCWD, path, 0)
147}
148
149//sys Unlinkat(dirfd int, path string, flags int) (err error)
150
151//sys utimes(path string, times *[2]Timeval) (err error)
152
153func Utimes(path string, tv []Timeval) error {
154 if tv == nil {
155 err := utimensat(AT_FDCWD, path, nil, 0)
156 if err != ENOSYS {
157 return err
158 }
159 return utimes(path, nil)
160 }
161 if len(tv) != 2 {
162 return EINVAL
163 }
164 var ts [2]Timespec
165 ts[0] = NsecToTimespec(TimevalToNsec(tv[0]))
166 ts[1] = NsecToTimespec(TimevalToNsec(tv[1]))
167 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
168 if err != ENOSYS {
169 return err
170 }
171 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
172}
173
174//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
175
176func UtimesNano(path string, ts []Timespec) error {
177 if ts == nil {
178 err := utimensat(AT_FDCWD, path, nil, 0)
179 if err != ENOSYS {
180 return err
181 }
182 return utimes(path, nil)
183 }
184 if len(ts) != 2 {
185 return EINVAL
186 }
187 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
188 if err != ENOSYS {
189 return err
190 }
191 // If the utimensat syscall isn't available (utimensat was added to Linux
192 // in 2.6.22, Released, 8 July 2007) then fall back to utimes
193 var tv [2]Timeval
194 for i := 0; i < 2; i++ {
195 tv[i] = NsecToTimeval(TimespecToNsec(ts[i]))
196 }
197 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
198}
199
200func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
201 if ts == nil {
202 return utimensat(dirfd, path, nil, flags)
203 }
204 if len(ts) != 2 {
205 return EINVAL
206 }
207 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
208}
209
210//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
211
212func Futimesat(dirfd int, path string, tv []Timeval) error {
213 pathp, err := BytePtrFromString(path)
214 if err != nil {
215 return err
216 }
217 if tv == nil {
218 return futimesat(dirfd, pathp, nil)
219 }
220 if len(tv) != 2 {
221 return EINVAL
222 }
223 return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
224}
225
226func Futimes(fd int, tv []Timeval) (err error) {
227 // Believe it or not, this is the best we can do on Linux
228 // (and is what glibc does).
229 return Utimes("/proc/self/fd/"+itoa(fd), tv)
230}
231
232const ImplementsGetwd = true
233
234//sys Getcwd(buf []byte) (n int, err error)
235
236func Getwd() (wd string, err error) {
237 var buf [PathMax]byte
238 n, err := Getcwd(buf[0:])
239 if err != nil {
240 return "", err
241 }
242 // Getcwd returns the number of bytes written to buf, including the NUL.
243 if n < 1 || n > len(buf) || buf[n-1] != 0 {
244 return "", EINVAL
245 }
246 return string(buf[0 : n-1]), nil
247}
248
249func Getgroups() (gids []int, err error) {
250 n, err := getgroups(0, nil)
251 if err != nil {
252 return nil, err
253 }
254 if n == 0 {
255 return nil, nil
256 }
257
258 // Sanity check group count. Max is 1<<16 on Linux.
259 if n < 0 || n > 1<<20 {
260 return nil, EINVAL
261 }
262
263 a := make([]_Gid_t, n)
264 n, err = getgroups(n, &a[0])
265 if err != nil {
266 return nil, err
267 }
268 gids = make([]int, n)
269 for i, v := range a[0:n] {
270 gids[i] = int(v)
271 }
272 return
273}
274
275func Setgroups(gids []int) (err error) {
276 if len(gids) == 0 {
277 return setgroups(0, nil)
278 }
279
280 a := make([]_Gid_t, len(gids))
281 for i, v := range gids {
282 a[i] = _Gid_t(v)
283 }
284 return setgroups(len(a), &a[0])
285}
286
287type WaitStatus uint32
288
289// Wait status is 7 bits at bottom, either 0 (exited),
290// 0x7F (stopped), or a signal number that caused an exit.
291// The 0x80 bit is whether there was a core dump.
292// An extra number (exit code, signal causing a stop)
293// is in the high bits. At least that's the idea.
294// There are various irregularities. For example, the
295// "continued" status is 0xFFFF, distinguishing itself
296// from stopped via the core dump bit.
297
298const (
299 mask = 0x7F
300 core = 0x80
301 exited = 0x00
302 stopped = 0x7F
303 shift = 8
304)
305
306func (w WaitStatus) Exited() bool { return w&mask == exited }
307
308func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
309
310func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
311
312func (w WaitStatus) Continued() bool { return w == 0xFFFF }
313
314func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
315
316func (w WaitStatus) ExitStatus() int {
317 if !w.Exited() {
318 return -1
319 }
320 return int(w>>shift) & 0xFF
321}
322
323func (w WaitStatus) Signal() syscall.Signal {
324 if !w.Signaled() {
325 return -1
326 }
327 return syscall.Signal(w & mask)
328}
329
330func (w WaitStatus) StopSignal() syscall.Signal {
331 if !w.Stopped() {
332 return -1
333 }
334 return syscall.Signal(w>>shift) & 0xFF
335}
336
337func (w WaitStatus) TrapCause() int {
338 if w.StopSignal() != SIGTRAP {
339 return -1
340 }
341 return int(w>>shift) >> 8
342}
343
344//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
345
346func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
347 var status _C_int
348 wpid, err = wait4(pid, &status, options, rusage)
349 if wstatus != nil {
350 *wstatus = WaitStatus(status)
351 }
352 return
353}
354
355func Mkfifo(path string, mode uint32) error {
356 return Mknod(path, mode|S_IFIFO, 0)
357}
358
359func Mkfifoat(dirfd int, path string, mode uint32) error {
360 return Mknodat(dirfd, path, mode|S_IFIFO, 0)
361}
362
363func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
364 if sa.Port < 0 || sa.Port > 0xFFFF {
365 return nil, 0, EINVAL
366 }
367 sa.raw.Family = AF_INET
368 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
369 p[0] = byte(sa.Port >> 8)
370 p[1] = byte(sa.Port)
371 for i := 0; i < len(sa.Addr); i++ {
372 sa.raw.Addr[i] = sa.Addr[i]
373 }
374 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
375}
376
377func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
378 if sa.Port < 0 || sa.Port > 0xFFFF {
379 return nil, 0, EINVAL
380 }
381 sa.raw.Family = AF_INET6
382 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
383 p[0] = byte(sa.Port >> 8)
384 p[1] = byte(sa.Port)
385 sa.raw.Scope_id = sa.ZoneId
386 for i := 0; i < len(sa.Addr); i++ {
387 sa.raw.Addr[i] = sa.Addr[i]
388 }
389 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
390}
391
392func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
393 name := sa.Name
394 n := len(name)
395 if n >= len(sa.raw.Path) {
396 return nil, 0, EINVAL
397 }
398 sa.raw.Family = AF_UNIX
399 for i := 0; i < n; i++ {
400 sa.raw.Path[i] = int8(name[i])
401 }
402 // length is family (uint16), name, NUL.
403 sl := _Socklen(2)
404 if n > 0 {
405 sl += _Socklen(n) + 1
406 }
407 if sa.raw.Path[0] == '@' {
408 sa.raw.Path[0] = 0
409 // Don't count trailing NUL for abstract address.
410 sl--
411 }
412
413 return unsafe.Pointer(&sa.raw), sl, nil
414}
415
416type SockaddrLinklayer struct {
417 Protocol uint16
418 Ifindex int
419 Hatype uint16
420 Pkttype uint8
421 Halen uint8
422 Addr [8]byte
423 raw RawSockaddrLinklayer
424}
425
426func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
427 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
428 return nil, 0, EINVAL
429 }
430 sa.raw.Family = AF_PACKET
431 sa.raw.Protocol = sa.Protocol
432 sa.raw.Ifindex = int32(sa.Ifindex)
433 sa.raw.Hatype = sa.Hatype
434 sa.raw.Pkttype = sa.Pkttype
435 sa.raw.Halen = sa.Halen
436 for i := 0; i < len(sa.Addr); i++ {
437 sa.raw.Addr[i] = sa.Addr[i]
438 }
439 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
440}
441
442type SockaddrNetlink struct {
443 Family uint16
444 Pad uint16
445 Pid uint32
446 Groups uint32
447 raw RawSockaddrNetlink
448}
449
450func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
451 sa.raw.Family = AF_NETLINK
452 sa.raw.Pad = sa.Pad
453 sa.raw.Pid = sa.Pid
454 sa.raw.Groups = sa.Groups
455 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
456}
457
458type SockaddrHCI struct {
459 Dev uint16
460 Channel uint16
461 raw RawSockaddrHCI
462}
463
464func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
465 sa.raw.Family = AF_BLUETOOTH
466 sa.raw.Dev = sa.Dev
467 sa.raw.Channel = sa.Channel
468 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
469}
470
471// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
472// The RxID and TxID fields are used for transport protocol addressing in
473// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
474// zero values for CAN_RAW and CAN_BCM sockets as they have no meaning.
475//
476// The SockaddrCAN struct must be bound to the socket file descriptor
477// using Bind before the CAN socket can be used.
478//
479// // Read one raw CAN frame
480// fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW)
481// addr := &SockaddrCAN{Ifindex: index}
482// Bind(fd, addr)
483// frame := make([]byte, 16)
484// Read(fd, frame)
485//
486// The full SocketCAN documentation can be found in the linux kernel
487// archives at: https://www.kernel.org/doc/Documentation/networking/can.txt
488type SockaddrCAN struct {
489 Ifindex int
490 RxID uint32
491 TxID uint32
492 raw RawSockaddrCAN
493}
494
495func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
496 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
497 return nil, 0, EINVAL
498 }
499 sa.raw.Family = AF_CAN
500 sa.raw.Ifindex = int32(sa.Ifindex)
501 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
502 for i := 0; i < 4; i++ {
503 sa.raw.Addr[i] = rx[i]
504 }
505 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
506 for i := 0; i < 4; i++ {
507 sa.raw.Addr[i+4] = tx[i]
508 }
509 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
510}
511
512// SockaddrALG implements the Sockaddr interface for AF_ALG type sockets.
513// SockaddrALG enables userspace access to the Linux kernel's cryptography
514// subsystem. The Type and Name fields specify which type of hash or cipher
515// should be used with a given socket.
516//
517// To create a file descriptor that provides access to a hash or cipher, both
518// Bind and Accept must be used. Once the setup process is complete, input
519// data can be written to the socket, processed by the kernel, and then read
520// back as hash output or ciphertext.
521//
522// Here is an example of using an AF_ALG socket with SHA1 hashing.
523// The initial socket setup process is as follows:
524//
525// // Open a socket to perform SHA1 hashing.
526// fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0)
527// addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"}
528// unix.Bind(fd, addr)
529// // Note: unix.Accept does not work at this time; must invoke accept()
530// // manually using unix.Syscall.
531// hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0)
532//
533// Once a file descriptor has been returned from Accept, it may be used to
534// perform SHA1 hashing. The descriptor is not safe for concurrent use, but
535// may be re-used repeatedly with subsequent Write and Read operations.
536//
537// When hashing a small byte slice or string, a single Write and Read may
538// be used:
539//
540// // Assume hashfd is already configured using the setup process.
541// hash := os.NewFile(hashfd, "sha1")
542// // Hash an input string and read the results. Each Write discards
543// // previous hash state. Read always reads the current state.
544// b := make([]byte, 20)
545// for i := 0; i < 2; i++ {
546// io.WriteString(hash, "Hello, world.")
547// hash.Read(b)
548// fmt.Println(hex.EncodeToString(b))
549// }
550// // Output:
551// // 2ae01472317d1935a84797ec1983ae243fc6aa28
552// // 2ae01472317d1935a84797ec1983ae243fc6aa28
553//
554// For hashing larger byte slices, or byte streams such as those read from
555// a file or socket, use Sendto with MSG_MORE to instruct the kernel to update
556// the hash digest instead of creating a new one for a given chunk and finalizing it.
557//
558// // Assume hashfd and addr are already configured using the setup process.
559// hash := os.NewFile(hashfd, "sha1")
560// // Hash the contents of a file.
561// f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz")
562// b := make([]byte, 4096)
563// for {
564// n, err := f.Read(b)
565// if err == io.EOF {
566// break
567// }
568// unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr)
569// }
570// hash.Read(b)
571// fmt.Println(hex.EncodeToString(b))
572// // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5
573//
574// For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html.
575type SockaddrALG struct {
576 Type string
577 Name string
578 Feature uint32
579 Mask uint32
580 raw RawSockaddrALG
581}
582
583func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) {
584 // Leave room for NUL byte terminator.
585 if len(sa.Type) > 13 {
586 return nil, 0, EINVAL
587 }
588 if len(sa.Name) > 63 {
589 return nil, 0, EINVAL
590 }
591
592 sa.raw.Family = AF_ALG
593 sa.raw.Feat = sa.Feature
594 sa.raw.Mask = sa.Mask
595
596 typ, err := ByteSliceFromString(sa.Type)
597 if err != nil {
598 return nil, 0, err
599 }
600 name, err := ByteSliceFromString(sa.Name)
601 if err != nil {
602 return nil, 0, err
603 }
604
605 copy(sa.raw.Type[:], typ)
606 copy(sa.raw.Name[:], name)
607
608 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil
609}
610
611// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
612// SockaddrVM provides access to Linux VM sockets: a mechanism that enables
613// bidirectional communication between a hypervisor and its guest virtual
614// machines.
615type SockaddrVM struct {
616 // CID and Port specify a context ID and port address for a VM socket.
617 // Guests have a unique CID, and hosts may have a well-known CID of:
618 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
619 // - VMADDR_CID_HOST: refers to other processes on the host.
620 CID uint32
621 Port uint32
622 raw RawSockaddrVM
623}
624
625func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
626 sa.raw.Family = AF_VSOCK
627 sa.raw.Port = sa.Port
628 sa.raw.Cid = sa.CID
629
630 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
631}
632
633func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
634 switch rsa.Addr.Family {
635 case AF_NETLINK:
636 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
637 sa := new(SockaddrNetlink)
638 sa.Family = pp.Family
639 sa.Pad = pp.Pad
640 sa.Pid = pp.Pid
641 sa.Groups = pp.Groups
642 return sa, nil
643
644 case AF_PACKET:
645 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
646 sa := new(SockaddrLinklayer)
647 sa.Protocol = pp.Protocol
648 sa.Ifindex = int(pp.Ifindex)
649 sa.Hatype = pp.Hatype
650 sa.Pkttype = pp.Pkttype
651 sa.Halen = pp.Halen
652 for i := 0; i < len(sa.Addr); i++ {
653 sa.Addr[i] = pp.Addr[i]
654 }
655 return sa, nil
656
657 case AF_UNIX:
658 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
659 sa := new(SockaddrUnix)
660 if pp.Path[0] == 0 {
661 // "Abstract" Unix domain socket.
662 // Rewrite leading NUL as @ for textual display.
663 // (This is the standard convention.)
664 // Not friendly to overwrite in place,
665 // but the callers below don't care.
666 pp.Path[0] = '@'
667 }
668
669 // Assume path ends at NUL.
670 // This is not technically the Linux semantics for
671 // abstract Unix domain sockets--they are supposed
672 // to be uninterpreted fixed-size binary blobs--but
673 // everyone uses this convention.
674 n := 0
675 for n < len(pp.Path) && pp.Path[n] != 0 {
676 n++
677 }
678 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
679 sa.Name = string(bytes)
680 return sa, nil
681
682 case AF_INET:
683 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
684 sa := new(SockaddrInet4)
685 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
686 sa.Port = int(p[0])<<8 + int(p[1])
687 for i := 0; i < len(sa.Addr); i++ {
688 sa.Addr[i] = pp.Addr[i]
689 }
690 return sa, nil
691
692 case AF_INET6:
693 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
694 sa := new(SockaddrInet6)
695 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
696 sa.Port = int(p[0])<<8 + int(p[1])
697 sa.ZoneId = pp.Scope_id
698 for i := 0; i < len(sa.Addr); i++ {
699 sa.Addr[i] = pp.Addr[i]
700 }
701 return sa, nil
702
703 case AF_VSOCK:
704 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
705 sa := &SockaddrVM{
706 CID: pp.Cid,
707 Port: pp.Port,
708 }
709 return sa, nil
710 }
711 return nil, EAFNOSUPPORT
712}
713
714func Accept(fd int) (nfd int, sa Sockaddr, err error) {
715 var rsa RawSockaddrAny
716 var len _Socklen = SizeofSockaddrAny
717 nfd, err = accept(fd, &rsa, &len)
718 if err != nil {
719 return
720 }
721 sa, err = anyToSockaddr(&rsa)
722 if err != nil {
723 Close(nfd)
724 nfd = 0
725 }
726 return
727}
728
729func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
730 var rsa RawSockaddrAny
731 var len _Socklen = SizeofSockaddrAny
732 nfd, err = accept4(fd, &rsa, &len, flags)
733 if err != nil {
734 return
735 }
736 if len > SizeofSockaddrAny {
737 panic("RawSockaddrAny too small")
738 }
739 sa, err = anyToSockaddr(&rsa)
740 if err != nil {
741 Close(nfd)
742 nfd = 0
743 }
744 return
745}
746
747func Getsockname(fd int) (sa Sockaddr, err error) {
748 var rsa RawSockaddrAny
749 var len _Socklen = SizeofSockaddrAny
750 if err = getsockname(fd, &rsa, &len); err != nil {
751 return
752 }
753 return anyToSockaddr(&rsa)
754}
755
756func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
757 vallen := _Socklen(4)
758 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
759 return value, err
760}
761
762func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
763 var value IPMreq
764 vallen := _Socklen(SizeofIPMreq)
765 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
766 return &value, err
767}
768
769func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
770 var value IPMreqn
771 vallen := _Socklen(SizeofIPMreqn)
772 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
773 return &value, err
774}
775
776func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
777 var value IPv6Mreq
778 vallen := _Socklen(SizeofIPv6Mreq)
779 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
780 return &value, err
781}
782
783func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
784 var value IPv6MTUInfo
785 vallen := _Socklen(SizeofIPv6MTUInfo)
786 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
787 return &value, err
788}
789
790func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
791 var value ICMPv6Filter
792 vallen := _Socklen(SizeofICMPv6Filter)
793 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
794 return &value, err
795}
796
797func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
798 var value Ucred
799 vallen := _Socklen(SizeofUcred)
800 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
801 return &value, err
802}
803
804func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
805 var value TCPInfo
806 vallen := _Socklen(SizeofTCPInfo)
807 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
808 return &value, err
809}
810
811func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
812 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
813}
814
815// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
816
817// KeyctlInt calls keyctl commands in which each argument is an int.
818// These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK,
819// KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT,
820// KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT,
821// KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT.
822//sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL
823
824// KeyctlBuffer calls keyctl commands in which the third and fourth
825// arguments are a buffer and its length, respectively.
826// These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE.
827//sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL
828
829// KeyctlString calls keyctl commands which return a string.
830// These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY.
831func KeyctlString(cmd int, id int) (string, error) {
832 // We must loop as the string data may change in between the syscalls.
833 // We could allocate a large buffer here to reduce the chance that the
834 // syscall needs to be called twice; however, this is unnecessary as
835 // the performance loss is negligible.
836 var buffer []byte
837 for {
838 // Try to fill the buffer with data
839 length, err := KeyctlBuffer(cmd, id, buffer, 0)
840 if err != nil {
841 return "", err
842 }
843
844 // Check if the data was written
845 if length <= len(buffer) {
846 // Exclude the null terminator
847 return string(buffer[:length-1]), nil
848 }
849
850 // Make a bigger buffer if needed
851 buffer = make([]byte, length)
852 }
853}
854
855// Keyctl commands with special signatures.
856
857// KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command.
858// See the full documentation at:
859// http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html
860func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {
861 createInt := 0
862 if create {
863 createInt = 1
864 }
865 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)
866}
867
868// KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the
869// key handle permission mask as described in the "keyctl setperm" section of
870// http://man7.org/linux/man-pages/man1/keyctl.1.html.
871// See the full documentation at:
872// http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html
873func KeyctlSetperm(id int, perm uint32) error {
874 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)
875 return err
876}
877
878//sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL
879
880// KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command.
881// See the full documentation at:
882// http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html
883func KeyctlJoinSessionKeyring(name string) (ringid int, err error) {
884 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)
885}
886
887//sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL
888
889// KeyctlSearch implements the KEYCTL_SEARCH command.
890// See the full documentation at:
891// http://man7.org/linux/man-pages/man3/keyctl_search.3.html
892func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {
893 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)
894}
895
896//sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL
897
898// KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This
899// command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice
900// of Iovec (each of which represents a buffer) instead of a single buffer.
901// See the full documentation at:
902// http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html
903func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {
904 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)
905}
906
907//sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL
908
909// KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command
910// computes a Diffie-Hellman shared secret based on the provide params. The
911// secret is written to the provided buffer and the returned size is the number
912// of bytes written (returning an error if there is insufficient space in the
913// buffer). If a nil buffer is passed in, this function returns the minimum
914// buffer length needed to store the appropriate data. Note that this differs
915// from KEYCTL_READ's behavior which always returns the requested payload size.
916// See the full documentation at:
917// http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html
918func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
919 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
920}
921
922func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
923 var msg Msghdr
924 var rsa RawSockaddrAny
925 msg.Name = (*byte)(unsafe.Pointer(&rsa))
926 msg.Namelen = uint32(SizeofSockaddrAny)
927 var iov Iovec
928 if len(p) > 0 {
929 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
930 iov.SetLen(len(p))
931 }
932 var dummy byte
933 if len(oob) > 0 {
934 var sockType int
935 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
936 if err != nil {
937 return
938 }
939 // receive at least one normal byte
940 if sockType != SOCK_DGRAM && len(p) == 0 {
941 iov.Base = &dummy
942 iov.SetLen(1)
943 }
944 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
945 msg.SetControllen(len(oob))
946 }
947 msg.Iov = &iov
948 msg.Iovlen = 1
949 if n, err = recvmsg(fd, &msg, flags); err != nil {
950 return
951 }
952 oobn = int(msg.Controllen)
953 recvflags = int(msg.Flags)
954 // source address is only specified if the socket is unconnected
955 if rsa.Addr.Family != AF_UNSPEC {
956 from, err = anyToSockaddr(&rsa)
957 }
958 return
959}
960
961func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
962 _, err = SendmsgN(fd, p, oob, to, flags)
963 return
964}
965
966func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
967 var ptr unsafe.Pointer
968 var salen _Socklen
969 if to != nil {
970 var err error
971 ptr, salen, err = to.sockaddr()
972 if err != nil {
973 return 0, err
974 }
975 }
976 var msg Msghdr
977 msg.Name = (*byte)(unsafe.Pointer(ptr))
978 msg.Namelen = uint32(salen)
979 var iov Iovec
980 if len(p) > 0 {
981 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
982 iov.SetLen(len(p))
983 }
984 var dummy byte
985 if len(oob) > 0 {
986 var sockType int
987 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
988 if err != nil {
989 return 0, err
990 }
991 // send at least one normal byte
992 if sockType != SOCK_DGRAM && len(p) == 0 {
993 iov.Base = &dummy
994 iov.SetLen(1)
995 }
996 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
997 msg.SetControllen(len(oob))
998 }
999 msg.Iov = &iov
1000 msg.Iovlen = 1
1001 if n, err = sendmsg(fd, &msg, flags); err != nil {
1002 return 0, err
1003 }
1004 if len(oob) > 0 && len(p) == 0 {
1005 n = 0
1006 }
1007 return n, nil
1008}
1009
1010// BindToDevice binds the socket associated with fd to device.
1011func BindToDevice(fd int, device string) (err error) {
1012 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
1013}
1014
1015//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
1016
1017func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
1018 // The peek requests are machine-size oriented, so we wrap it
1019 // to retrieve arbitrary-length data.
1020
1021 // The ptrace syscall differs from glibc's ptrace.
1022 // Peeks returns the word in *data, not as the return value.
1023
1024 var buf [sizeofPtr]byte
1025
1026 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
1027 // access (PEEKUSER warns that it might), but if we don't
1028 // align our reads, we might straddle an unmapped page
1029 // boundary and not get the bytes leading up to the page
1030 // boundary.
1031 n := 0
1032 if addr%sizeofPtr != 0 {
1033 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
1034 if err != nil {
1035 return 0, err
1036 }
1037 n += copy(out, buf[addr%sizeofPtr:])
1038 out = out[n:]
1039 }
1040
1041 // Remainder.
1042 for len(out) > 0 {
1043 // We use an internal buffer to guarantee alignment.
1044 // It's not documented if this is necessary, but we're paranoid.
1045 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
1046 if err != nil {
1047 return n, err
1048 }
1049 copied := copy(out, buf[0:])
1050 n += copied
1051 out = out[copied:]
1052 }
1053
1054 return n, nil
1055}
1056
1057func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
1058 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
1059}
1060
1061func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
1062 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
1063}
1064
1065func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {
1066 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out)
1067}
1068
1069func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
1070 // As for ptracePeek, we need to align our accesses to deal
1071 // with the possibility of straddling an invalid page.
1072
1073 // Leading edge.
1074 n := 0
1075 if addr%sizeofPtr != 0 {
1076 var buf [sizeofPtr]byte
1077 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
1078 if err != nil {
1079 return 0, err
1080 }
1081 n += copy(buf[addr%sizeofPtr:], data)
1082 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1083 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
1084 if err != nil {
1085 return 0, err
1086 }
1087 data = data[n:]
1088 }
1089
1090 // Interior.
1091 for len(data) > sizeofPtr {
1092 word := *((*uintptr)(unsafe.Pointer(&data[0])))
1093 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1094 if err != nil {
1095 return n, err
1096 }
1097 n += sizeofPtr
1098 data = data[sizeofPtr:]
1099 }
1100
1101 // Trailing edge.
1102 if len(data) > 0 {
1103 var buf [sizeofPtr]byte
1104 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
1105 if err != nil {
1106 return n, err
1107 }
1108 copy(buf[0:], data)
1109 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1110 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1111 if err != nil {
1112 return n, err
1113 }
1114 n += len(data)
1115 }
1116
1117 return n, nil
1118}
1119
1120func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
1121 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
1122}
1123
1124func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
1125 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
1126}
1127
1128func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
1129 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
1130}
1131
1132func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
1133 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
1134}
1135
1136func PtraceSetOptions(pid int, options int) (err error) {
1137 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
1138}
1139
1140func PtraceGetEventMsg(pid int) (msg uint, err error) {
1141 var data _C_long
1142 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
1143 msg = uint(data)
1144 return
1145}
1146
1147func PtraceCont(pid int, signal int) (err error) {
1148 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
1149}
1150
1151func PtraceSyscall(pid int, signal int) (err error) {
1152 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
1153}
1154
1155func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
1156
1157func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
1158
1159func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1160
1161//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
1162
1163func Reboot(cmd int) (err error) {
1164 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1165}
1166
1167func ReadDirent(fd int, buf []byte) (n int, err error) {
1168 return Getdents(fd, buf)
1169}
1170
1171func direntIno(buf []byte) (uint64, bool) {
1172 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1173}
1174
1175func direntReclen(buf []byte) (uint64, bool) {
1176 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1177}
1178
1179func direntNamlen(buf []byte) (uint64, bool) {
1180 reclen, ok := direntReclen(buf)
1181 if !ok {
1182 return 0, false
1183 }
1184 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1185}
1186
1187//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
1188
1189func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1190 // Certain file systems get rather angry and EINVAL if you give
1191 // them an empty string of data, rather than NULL.
1192 if data == "" {
1193 return mount(source, target, fstype, flags, nil)
1194 }
1195 datap, err := BytePtrFromString(data)
1196 if err != nil {
1197 return err
1198 }
1199 return mount(source, target, fstype, flags, datap)
1200}
1201
1202// Sendto
1203// Recvfrom
1204// Socketpair
1205
1206/*
1207 * Direct access
1208 */
1209//sys Acct(path string) (err error)
1210//sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
1211//sys Adjtimex(buf *Timex) (state int, err error)
1212//sys Chdir(path string) (err error)
1213//sys Chroot(path string) (err error)
1214//sys ClockGettime(clockid int32, time *Timespec) (err error)
1215//sys Close(fd int) (err error)
1216//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
1217//sys Dup(oldfd int) (fd int, err error)
1218//sys Dup3(oldfd int, newfd int, flags int) (err error)
1219//sysnb EpollCreate(size int) (fd int, err error)
1220//sysnb EpollCreate1(flag int) (fd int, err error)
1221//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
1222//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
1223//sys Exit(code int) = SYS_EXIT_GROUP
1224//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
1225//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
1226//sys Fchdir(fd int) (err error)
1227//sys Fchmod(fd int, mode uint32) (err error)
1228//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
1229//sys fcntl(fd int, cmd int, arg int) (val int, err error)
1230//sys Fdatasync(fd int) (err error)
1231//sys Flock(fd int, how int) (err error)
1232//sys Fsync(fd int) (err error)
1233//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
1234//sysnb Getpgid(pid int) (pgid int, err error)
1235
1236func Getpgrp() (pid int) {
1237 pid, _ = Getpgid(0)
1238 return
1239}
1240
1241//sysnb Getpid() (pid int)
1242//sysnb Getppid() (ppid int)
1243//sys Getpriority(which int, who int) (prio int, err error)
1244//sys Getrandom(buf []byte, flags int) (n int, err error)
1245//sysnb Getrusage(who int, rusage *Rusage) (err error)
1246//sysnb Getsid(pid int) (sid int, err error)
1247//sysnb Gettid() (tid int)
1248//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
1249//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
1250//sysnb InotifyInit1(flags int) (fd int, err error)
1251//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
1252//sysnb Kill(pid int, sig syscall.Signal) (err error)
1253//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
1254//sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error)
1255//sys Listxattr(path string, dest []byte) (sz int, err error)
1256//sys Llistxattr(path string, dest []byte) (sz int, err error)
1257//sys Lremovexattr(path string, attr string) (err error)
1258//sys Lsetxattr(path string, attr string, data []byte, flags int) (err error)
1259//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
1260//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
1261//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
1262//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
1263//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
1264//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
1265//sys read(fd int, p []byte) (n int, err error)
1266//sys Removexattr(path string, attr string) (err error)
1267//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
1268//sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
1269//sys Setdomainname(p []byte) (err error)
1270//sys Sethostname(p []byte) (err error)
1271//sysnb Setpgid(pid int, pgid int) (err error)
1272//sysnb Setsid() (pid int, err error)
1273//sysnb Settimeofday(tv *Timeval) (err error)
1274//sys Setns(fd int, nstype int) (err error)
1275
1276// issue 1435.
1277// On linux Setuid and Setgid only affects the current thread, not the process.
1278// This does not match what most callers expect so we must return an error
1279// here rather than letting the caller think that the call succeeded.
1280
1281func Setuid(uid int) (err error) {
1282 return EOPNOTSUPP
1283}
1284
1285func Setgid(uid int) (err error) {
1286 return EOPNOTSUPP
1287}
1288
1289//sys Setpriority(which int, who int, prio int) (err error)
1290//sys Setxattr(path string, attr string, data []byte, flags int) (err error)
1291//sys Sync()
1292//sys Syncfs(fd int) (err error)
1293//sysnb Sysinfo(info *Sysinfo_t) (err error)
1294//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
1295//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
1296//sysnb Times(tms *Tms) (ticks uintptr, err error)
1297//sysnb Umask(mask int) (oldmask int)
1298//sysnb Uname(buf *Utsname) (err error)
1299//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
1300//sys Unshare(flags int) (err error)
1301//sys Ustat(dev int, ubuf *Ustat_t) (err error)
1302//sys write(fd int, p []byte) (n int, err error)
1303//sys exitThread(code int) (err error) = SYS_EXIT
1304//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
1305//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
1306
1307// mmap varies by architecture; see syscall_linux_*.go.
1308//sys munmap(addr uintptr, length uintptr) (err error)
1309
1310var mapper = &mmapper{
1311 active: make(map[*byte][]byte),
1312 mmap: mmap,
1313 munmap: munmap,
1314}
1315
1316func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1317 return mapper.Mmap(fd, offset, length, prot, flags)
1318}
1319
1320func Munmap(b []byte) (err error) {
1321 return mapper.Munmap(b)
1322}
1323
1324//sys Madvise(b []byte, advice int) (err error)
1325//sys Mprotect(b []byte, prot int) (err error)
1326//sys Mlock(b []byte) (err error)
1327//sys Mlockall(flags int) (err error)
1328//sys Msync(b []byte, flags int) (err error)
1329//sys Munlock(b []byte) (err error)
1330//sys Munlockall() (err error)
1331
1332// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
1333// using the specified flags.
1334func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
1335 n, _, errno := Syscall6(
1336 SYS_VMSPLICE,
1337 uintptr(fd),
1338 uintptr(unsafe.Pointer(&iovs[0])),
1339 uintptr(len(iovs)),
1340 uintptr(flags),
1341 0,
1342 0,
1343 )
1344 if errno != 0 {
1345 return 0, syscall.Errno(errno)
1346 }
1347
1348 return int(n), nil
1349}
1350
1351/*
1352 * Unimplemented
1353 */
1354// AfsSyscall
1355// Alarm
1356// ArchPrctl
1357// Brk
1358// Capget
1359// Capset
1360// ClockGetres
1361// ClockNanosleep
1362// ClockSettime
1363// Clone
1364// CreateModule
1365// DeleteModule
1366// EpollCtlOld
1367// EpollPwait
1368// EpollWaitOld
1369// Execve
1370// Fgetxattr
1371// Flistxattr
1372// Fork
1373// Fremovexattr
1374// Fsetxattr
1375// Futex
1376// GetKernelSyms
1377// GetMempolicy
1378// GetRobustList
1379// GetThreadArea
1380// Getitimer
1381// Getpmsg
1382// IoCancel
1383// IoDestroy
1384// IoGetevents
1385// IoSetup
1386// IoSubmit
1387// IoprioGet
1388// IoprioSet
1389// KexecLoad
1390// LookupDcookie
1391// Mbind
1392// MigratePages
1393// Mincore
1394// ModifyLdt
1395// Mount
1396// MovePages
1397// MqGetsetattr
1398// MqNotify
1399// MqOpen
1400// MqTimedreceive
1401// MqTimedsend
1402// MqUnlink
1403// Mremap
1404// Msgctl
1405// Msgget
1406// Msgrcv
1407// Msgsnd
1408// Newfstatat
1409// Nfsservctl
1410// Personality
1411// Pselect6
1412// Ptrace
1413// Putpmsg
1414// QueryModule
1415// Quotactl
1416// Readahead
1417// Readv
1418// RemapFilePages
1419// RestartSyscall
1420// RtSigaction
1421// RtSigpending
1422// RtSigprocmask
1423// RtSigqueueinfo
1424// RtSigreturn
1425// RtSigsuspend
1426// RtSigtimedwait
1427// SchedGetPriorityMax
1428// SchedGetPriorityMin
1429// SchedGetaffinity
1430// SchedGetparam
1431// SchedGetscheduler
1432// SchedRrGetInterval
1433// SchedSetaffinity
1434// SchedSetparam
1435// SchedYield
1436// Security
1437// Semctl
1438// Semget
1439// Semop
1440// Semtimedop
1441// SetMempolicy
1442// SetRobustList
1443// SetThreadArea
1444// SetTidAddress
1445// Shmat
1446// Shmctl
1447// Shmdt
1448// Shmget
1449// Sigaltstack
1450// Signalfd
1451// Swapoff
1452// Swapon
1453// Sysfs
1454// TimerCreate
1455// TimerDelete
1456// TimerGetoverrun
1457// TimerGettime
1458// TimerSettime
1459// Timerfd
1460// Tkill (obsolete)
1461// Tuxcall
1462// Umount2
1463// Uselib
1464// Utimensat
1465// Vfork
1466// Vhangup
1467// Vserver
1468// Waitid
1469// _Sysctl