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