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