all repos

rss-tools @ master

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/sys/unix/syscall_linux.go (view raw)

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