syscall_linux.mx raw
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 syscall
13
14 import (
15 "internal/itoa"
16 runtimesyscall "internal/runtime/syscall"
17 "runtime"
18 "slices"
19 "unsafe"
20 )
21
22 // Pull in entersyscall/exitsyscall for Syscall/Syscall6.
23 //
24 // Note that this can't be a push linkname because the runtime already has a
25 // nameless linkname to export to assembly here and in x/sys. Additionally,
26 // entersyscall fetches the caller PC and SP and thus can't have a wrapper
27 // inbetween.
28
29 //go:linkname runtime_entersyscall runtime.entersyscall
30 func runtime_entersyscall()
31
32 //go:linkname runtime_exitsyscall runtime.exitsyscall
33 func runtime_exitsyscall()
34
35 // N.B. For the Syscall functions below:
36 //
37 // //go:uintptrkeepalive because the uintptr argument may be converted pointers
38 // that need to be kept alive in the caller.
39 //
40 // //go:nosplit because stack copying does not account for uintptrkeepalive, so
41 // the stack must not grow. Stack copying cannot blindly assume that all
42 // uintptr arguments are pointers, because some values may look like pointers,
43 // but not really be pointers, and adjusting their value would break the call.
44 //
45 // //go:norace, on RawSyscall, to avoid race instrumentation if RawSyscall is
46 // called after fork, or from a signal handler.
47 //
48 // //go:linkname to ensure ABI wrappers are generated for external callers
49 // (notably x/sys/unix assembly).
50
51 //go:uintptrkeepalive
52 //go:nosplit
53 //go:norace
54 //go:linkname RawSyscall
55 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
56 return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
57 }
58
59 //go:uintptrkeepalive
60 //go:nosplit
61 //go:norace
62 //go:linkname RawSyscall6
63 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
64 var errno uintptr
65 r1, r2, errno = runtimesyscall.Syscall6(trap, a1, a2, a3, a4, a5, a6)
66 err = Errno(errno)
67 return
68 }
69
70 //go:uintptrkeepalive
71 //go:nosplit
72 //go:linkname Syscall
73 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
74 runtime_entersyscall()
75 // N.B. Calling RawSyscall here is unsafe with atomic coverage
76 // instrumentation and race mode.
77 //
78 // Coverage instrumentation will add a sync/atomic call to RawSyscall.
79 // Race mode will add race instrumentation to sync/atomic. Race
80 // instrumentation requires a P, which we no longer have.
81 //
82 // RawSyscall6 is fine because it is implemented in assembly and thus
83 // has no coverage instrumentation.
84 //
85 // This is typically not a problem in the runtime because cmd/go avoids
86 // adding coverage instrumentation to the runtime in race mode.
87 r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
88 runtime_exitsyscall()
89 return
90 }
91
92 //go:uintptrkeepalive
93 //go:nosplit
94 //go:linkname Syscall6
95 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
96 runtime_entersyscall()
97 r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
98 runtime_exitsyscall()
99 return
100 }
101
102 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
103 func rawVforkSyscall(trap, a1, a2, a3 uintptr) (r1 uintptr, err Errno)
104
105 /*
106 * Wrapped
107 */
108
109 func Access(path string, mode uint32) (err error) {
110 return Faccessat(_AT_FDCWD, path, mode, 0)
111 }
112
113 func Chmod(path string, mode uint32) (err error) {
114 return Fchmodat(_AT_FDCWD, path, mode, 0)
115 }
116
117 func Chown(path string, uid int, gid int) (err error) {
118 return Fchownat(_AT_FDCWD, path, uid, gid, 0)
119 }
120
121 func Creat(path string, mode uint32) (fd int, err error) {
122 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
123 }
124
125 func EpollCreate(size int) (fd int, err error) {
126 if size <= 0 {
127 return -1, EINVAL
128 }
129 return EpollCreate1(0)
130 }
131
132 func isGroupMember(gid int) bool {
133 groups, err := Getgroups()
134 if err != nil {
135 return false
136 }
137
138 return slices.Contains(groups, gid)
139 }
140
141 func isCapDacOverrideSet() bool {
142 const _CAP_DAC_OVERRIDE = 1
143 var c caps
144 c.hdr.version = _LINUX_CAPABILITY_VERSION_3
145
146 _, _, err := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&c.hdr)), uintptr(unsafe.Pointer(&c.data[0])), 0)
147
148 return err == 0 && c.data[0].effective&capToMask(_CAP_DAC_OVERRIDE) != 0
149 }
150
151 //sys faccessat(dirfd int, path string, mode uint32) (err error)
152 //sys faccessat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_faccessat2
153
154 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
155 if flags == 0 {
156 return faccessat(dirfd, path, mode)
157 }
158
159 // Attempt to use the newer faccessat2, which supports flags directly,
160 // falling back if it doesn't exist.
161 //
162 // Don't attempt on Android, which does not allow faccessat2 through
163 // its seccomp policy [1] on any version of Android as of 2022-12-20.
164 //
165 // [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
166 if runtime.GOOS != "android" {
167 if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
168 return err
169 }
170 }
171
172 // The Linux kernel faccessat system call does not take any flags.
173 // The glibc faccessat implements the flags itself; see
174 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
175 // Because people naturally expect syscall.Faccessat to act
176 // like C faccessat, we do the same.
177
178 if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
179 return EINVAL
180 }
181
182 var st Stat_t
183 if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
184 return err
185 }
186
187 mode &= 7
188 if mode == 0 {
189 return nil
190 }
191
192 // Fallback to checking permission bits.
193 var uid int
194 if flags&_AT_EACCESS != 0 {
195 uid = Geteuid()
196 if uid != 0 && isCapDacOverrideSet() {
197 // If CAP_DAC_OVERRIDE is set, file access check is
198 // done by the kernel in the same way as for root
199 // (see generic_permission() in the Linux sources).
200 uid = 0
201 }
202 } else {
203 uid = Getuid()
204 }
205
206 if uid == 0 {
207 if mode&1 == 0 {
208 // Root can read and write any file.
209 return nil
210 }
211 if st.Mode&0111 != 0 {
212 // Root can execute any file that anybody can execute.
213 return nil
214 }
215 return EACCES
216 }
217
218 var fmode uint32
219 if uint32(uid) == st.Uid {
220 fmode = (st.Mode >> 6) & 7
221 } else {
222 var gid int
223 if flags&_AT_EACCESS != 0 {
224 gid = Getegid()
225 } else {
226 gid = Getgid()
227 }
228
229 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
230 fmode = (st.Mode >> 3) & 7
231 } else {
232 fmode = st.Mode & 7
233 }
234 }
235
236 if fmode&mode == mode {
237 return nil
238 }
239
240 return EACCES
241 }
242
243 //sys fchmodat(dirfd int, path string, mode uint32) (err error)
244 //sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_fchmodat2
245
246 func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
247 // Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
248 // Try fchmodat2 if flags are specified.
249 if flags != 0 {
250 err := fchmodat2(dirfd, path, mode, flags)
251 if err == ENOSYS {
252 // fchmodat2 isn't available. If the flags are known to be valid,
253 // return EOPNOTSUPP to indicate that fchmodat doesn't support them.
254 if flags&^(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
255 return EINVAL
256 } else if flags&(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
257 return EOPNOTSUPP
258 }
259 }
260 return err
261 }
262 return fchmodat(dirfd, path, mode)
263 }
264
265 //sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
266
267 func Link(oldpath string, newpath string) (err error) {
268 return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0)
269 }
270
271 func Mkdir(path string, mode uint32) (err error) {
272 return Mkdirat(_AT_FDCWD, path, mode)
273 }
274
275 func Mknod(path string, mode uint32, dev int) (err error) {
276 return Mknodat(_AT_FDCWD, path, mode, dev)
277 }
278
279 func Open(path string, mode int, perm uint32) (fd int, err error) {
280 return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm)
281 }
282
283 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
284
285 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
286 return openat(dirfd, path, flags|O_LARGEFILE, mode)
287 }
288
289 func Pipe(p []int) error {
290 return Pipe2(p, 0)
291 }
292
293 //sysnb pipe2(p *[2]_C_int, flags int) (err error)
294
295 func Pipe2(p []int, flags int) error {
296 if len(p) != 2 {
297 return EINVAL
298 }
299 var pp [2]_C_int
300 err := pipe2(&pp, flags)
301 if err == nil {
302 p[0] = int(pp[0])
303 p[1] = int(pp[1])
304 }
305 return err
306 }
307
308 //sys readlinkat(dirfd int, path string, buf []byte) (n int, err error)
309
310 func Readlink(path string, buf []byte) (n int, err error) {
311 return readlinkat(_AT_FDCWD, path, buf)
312 }
313
314 func Rename(oldpath string, newpath string) (err error) {
315 return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath)
316 }
317
318 func Rmdir(path string) error {
319 return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR)
320 }
321
322 //sys symlinkat(oldpath string, newdirfd int, newpath string) (err error)
323
324 func Symlink(oldpath string, newpath string) (err error) {
325 return symlinkat(oldpath, _AT_FDCWD, newpath)
326 }
327
328 func Unlink(path string) error {
329 return unlinkat(_AT_FDCWD, path, 0)
330 }
331
332 //sys unlinkat(dirfd int, path string, flags int) (err error)
333
334 func Unlinkat(dirfd int, path string) error {
335 return unlinkat(dirfd, path, 0)
336 }
337
338 func Utimes(path string, tv []Timeval) (err error) {
339 if len(tv) != 2 {
340 return EINVAL
341 }
342 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
343 }
344
345 //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
346
347 func UtimesNano(path string, ts []Timespec) (err error) {
348 if len(ts) != 2 {
349 return EINVAL
350 }
351 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
352 }
353
354 func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
355 if len(tv) != 2 {
356 return EINVAL
357 }
358 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
359 }
360
361 func Futimes(fd int, tv []Timeval) (err error) {
362 // Believe it or not, this is the best we can do on Linux
363 // (and is what glibc does).
364 return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
365 }
366
367 const ImplementsGetwd = true
368
369 //sys Getcwd(buf []byte) (n int, err error)
370
371 func Getwd() (wd string, err error) {
372 var buf [PathMax]byte
373 n, err := Getcwd(buf[0:])
374 if err != nil {
375 return "", err
376 }
377 // Getcwd returns the number of bytes written to buf, including the NUL.
378 if n < 1 || n > len(buf) || buf[n-1] != 0 {
379 return "", EINVAL
380 }
381 // In some cases, Linux can return a path that starts with the
382 // "(unreachable)" prefix, which can potentially be a valid relative
383 // path. To work around that, return ENOENT if path is not absolute.
384 if buf[0] != '/' {
385 return "", ENOENT
386 }
387
388 return string(buf[0 : n-1]), nil
389 }
390
391 func Getgroups() (gids []int, err error) {
392 n, err := getgroups(0, nil)
393 if err != nil {
394 return nil, err
395 }
396 if n == 0 {
397 return nil, nil
398 }
399
400 // Sanity check group count. Max is 1<<16 on Linux.
401 if n < 0 || n > 1<<20 {
402 return nil, EINVAL
403 }
404
405 a := make([]_Gid_t, n)
406 n, err = getgroups(n, &a[0])
407 if err != nil {
408 return nil, err
409 }
410 gids = make([]int, n)
411 for i, v := range a[0:n] {
412 gids[i] = int(v)
413 }
414 return
415 }
416
417 var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked.
418
419 func Setgroups(gids []int) (err error) {
420 n := uintptr(len(gids))
421 if n == 0 {
422 if cgo_libc_setgroups == nil {
423 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 {
424 err = errnoErr(e1)
425 }
426 return
427 }
428 if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 {
429 err = errnoErr(Errno(ret))
430 }
431 return
432 }
433
434 a := make([]_Gid_t, len(gids))
435 for i, v := range gids {
436 a[i] = _Gid_t(v)
437 }
438 if cgo_libc_setgroups == nil {
439 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 {
440 err = errnoErr(e1)
441 }
442 return
443 }
444 if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 {
445 err = errnoErr(Errno(ret))
446 }
447 return
448 }
449
450 type WaitStatus uint32
451
452 // Wait status is 7 bits at bottom, either 0 (exited),
453 // 0x7F (stopped), or a signal number that caused an exit.
454 // The 0x80 bit is whether there was a core dump.
455 // An extra number (exit code, signal causing a stop)
456 // is in the high bits. At least that's the idea.
457 // There are various irregularities. For example, the
458 // "continued" status is 0xFFFF, distinguishing itself
459 // from stopped via the core dump bit.
460
461 const (
462 mask = 0x7F
463 core = 0x80
464 exited = 0x00
465 stopped = 0x7F
466 shift = 8
467 )
468
469 func (w WaitStatus) Exited() bool { return w&mask == exited }
470
471 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
472
473 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
474
475 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
476
477 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
478
479 func (w WaitStatus) ExitStatus() int {
480 if !w.Exited() {
481 return -1
482 }
483 return int(w>>shift) & 0xFF
484 }
485
486 func (w WaitStatus) Signal() Signal {
487 if !w.Signaled() {
488 return -1
489 }
490 return Signal(w & mask)
491 }
492
493 func (w WaitStatus) StopSignal() Signal {
494 if !w.Stopped() {
495 return -1
496 }
497 return Signal(w>>shift) & 0xFF
498 }
499
500 func (w WaitStatus) TrapCause() int {
501 if w.StopSignal() != SIGTRAP {
502 return -1
503 }
504 return int(w>>shift) >> 8
505 }
506
507 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
508
509 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
510 var status _C_int
511 wpid, err = wait4(pid, &status, options, rusage)
512 if wstatus != nil {
513 *wstatus = WaitStatus(status)
514 }
515 return
516 }
517
518 func Mkfifo(path string, mode uint32) (err error) {
519 return Mknod(path, mode|S_IFIFO, 0)
520 }
521
522 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
523 if sa.Port < 0 || sa.Port > 0xFFFF {
524 return nil, 0, EINVAL
525 }
526 sa.raw.Family = AF_INET
527 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
528 p[0] = byte(sa.Port >> 8)
529 p[1] = byte(sa.Port)
530 sa.raw.Addr = sa.Addr
531 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
532 }
533
534 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
535 if sa.Port < 0 || sa.Port > 0xFFFF {
536 return nil, 0, EINVAL
537 }
538 sa.raw.Family = AF_INET6
539 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
540 p[0] = byte(sa.Port >> 8)
541 p[1] = byte(sa.Port)
542 sa.raw.Scope_id = sa.ZoneId
543 sa.raw.Addr = sa.Addr
544 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
545 }
546
547 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
548 name := sa.Name
549 n := len(name)
550 if n > len(sa.raw.Path) {
551 return nil, 0, EINVAL
552 }
553 // Abstract addresses start with NUL.
554 // '@' is also a valid way to specify abstract addresses.
555 isAbstract := n > 0 && (name[0] == '@' || name[0] == '\x00')
556
557 // Non-abstract named addresses are NUL terminated.
558 // The length can't use the full capacity as we need to add NUL.
559 if n == len(sa.raw.Path) && !isAbstract {
560 return nil, 0, EINVAL
561 }
562 sa.raw.Family = AF_UNIX
563 for i := 0; i < n; i++ {
564 sa.raw.Path[i] = int8(name[i])
565 }
566 // Length is family + name (+ NUL if non-abstract).
567 // Family is of type uint16 (2 bytes).
568 sl := _Socklen(2 + n)
569 if isAbstract {
570 // Abstract addresses are not NUL terminated.
571 // We rewrite '@' prefix to NUL here.
572 sa.raw.Path[0] = 0
573 } else if n > 0 {
574 // Add NUL for non-abstract named addresses.
575 sl++
576 }
577
578 return unsafe.Pointer(&sa.raw), sl, nil
579 }
580
581 type SockaddrLinklayer struct {
582 Protocol uint16
583 Ifindex int
584 Hatype uint16
585 Pkttype uint8
586 Halen uint8
587 Addr [8]byte
588 raw RawSockaddrLinklayer
589 }
590
591 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
592 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
593 return nil, 0, EINVAL
594 }
595 sa.raw.Family = AF_PACKET
596 sa.raw.Protocol = sa.Protocol
597 sa.raw.Ifindex = int32(sa.Ifindex)
598 sa.raw.Hatype = sa.Hatype
599 sa.raw.Pkttype = sa.Pkttype
600 sa.raw.Halen = sa.Halen
601 sa.raw.Addr = sa.Addr
602 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
603 }
604
605 type SockaddrNetlink struct {
606 Family uint16
607 Pad uint16
608 Pid uint32
609 Groups uint32
610 raw RawSockaddrNetlink
611 }
612
613 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
614 sa.raw.Family = AF_NETLINK
615 sa.raw.Pad = sa.Pad
616 sa.raw.Pid = sa.Pid
617 sa.raw.Groups = sa.Groups
618 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
619 }
620
621 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
622 switch rsa.Addr.Family {
623 case AF_NETLINK:
624 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
625 sa := new(SockaddrNetlink)
626 sa.Family = pp.Family
627 sa.Pad = pp.Pad
628 sa.Pid = pp.Pid
629 sa.Groups = pp.Groups
630 return sa, nil
631
632 case AF_PACKET:
633 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
634 sa := new(SockaddrLinklayer)
635 sa.Protocol = pp.Protocol
636 sa.Ifindex = int(pp.Ifindex)
637 sa.Hatype = pp.Hatype
638 sa.Pkttype = pp.Pkttype
639 sa.Halen = pp.Halen
640 sa.Addr = pp.Addr
641 return sa, nil
642
643 case AF_UNIX:
644 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
645 sa := new(SockaddrUnix)
646 if pp.Path[0] == 0 {
647 // "Abstract" Unix domain socket.
648 // Rewrite leading NUL as @ for textual display.
649 // (This is the standard convention.)
650 // Not friendly to overwrite in place,
651 // but the callers below don't care.
652 pp.Path[0] = '@'
653 }
654
655 // Assume path ends at NUL.
656 // This is not technically the Linux semantics for
657 // abstract Unix domain sockets--they are supposed
658 // to be uninterpreted fixed-size binary blobs--but
659 // everyone uses this convention.
660 n := 0
661 for n < len(pp.Path) && pp.Path[n] != 0 {
662 n++
663 }
664 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
665 return sa, nil
666
667 case AF_INET:
668 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
669 sa := new(SockaddrInet4)
670 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
671 sa.Port = int(p[0])<<8 + int(p[1])
672 sa.Addr = pp.Addr
673 return sa, nil
674
675 case AF_INET6:
676 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
677 sa := new(SockaddrInet6)
678 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
679 sa.Port = int(p[0])<<8 + int(p[1])
680 sa.ZoneId = pp.Scope_id
681 sa.Addr = pp.Addr
682 return sa, nil
683 }
684 return nil, EAFNOSUPPORT
685 }
686
687 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
688 return Accept4(fd, 0)
689 }
690
691 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
692 var rsa RawSockaddrAny
693 var len _Socklen = SizeofSockaddrAny
694 nfd, err = accept4(fd, &rsa, &len, flags)
695 if err != nil {
696 return
697 }
698 if len > SizeofSockaddrAny {
699 panic("RawSockaddrAny too small")
700 }
701 sa, err = anyToSockaddr(&rsa)
702 if err != nil {
703 Close(nfd)
704 nfd = 0
705 }
706 return
707 }
708
709 func Getsockname(fd int) (sa Sockaddr, err error) {
710 var rsa RawSockaddrAny
711 var len _Socklen = SizeofSockaddrAny
712 if err = getsockname(fd, &rsa, &len); err != nil {
713 return
714 }
715 return anyToSockaddr(&rsa)
716 }
717
718 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
719 vallen := _Socklen(4)
720 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
721 return value, err
722 }
723
724 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
725 var value IPMreq
726 vallen := _Socklen(SizeofIPMreq)
727 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
728 return &value, err
729 }
730
731 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
732 var value IPMreqn
733 vallen := _Socklen(SizeofIPMreqn)
734 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
735 return &value, err
736 }
737
738 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
739 var value IPv6Mreq
740 vallen := _Socklen(SizeofIPv6Mreq)
741 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
742 return &value, err
743 }
744
745 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
746 var value IPv6MTUInfo
747 vallen := _Socklen(SizeofIPv6MTUInfo)
748 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
749 return &value, err
750 }
751
752 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
753 var value ICMPv6Filter
754 vallen := _Socklen(SizeofICMPv6Filter)
755 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
756 return &value, err
757 }
758
759 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
760 var value Ucred
761 vallen := _Socklen(SizeofUcred)
762 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
763 return &value, err
764 }
765
766 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
767 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
768 }
769
770 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
771 var msg Msghdr
772 msg.Name = (*byte)(unsafe.Pointer(rsa))
773 msg.Namelen = uint32(SizeofSockaddrAny)
774 var iov Iovec
775 if len(p) > 0 {
776 iov.Base = &p[0]
777 iov.SetLen(len(p))
778 }
779 var dummy byte
780 if len(oob) > 0 {
781 if len(p) == 0 {
782 var sockType int
783 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
784 if err != nil {
785 return
786 }
787 // receive at least one normal byte
788 if sockType != SOCK_DGRAM {
789 iov.Base = &dummy
790 iov.SetLen(1)
791 }
792 }
793 msg.Control = &oob[0]
794 msg.SetControllen(len(oob))
795 }
796 msg.Iov = &iov
797 msg.Iovlen = 1
798 if n, err = recvmsg(fd, &msg, flags); err != nil {
799 return
800 }
801 oobn = int(msg.Controllen)
802 recvflags = int(msg.Flags)
803 return
804 }
805
806 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
807 var msg Msghdr
808 msg.Name = (*byte)(ptr)
809 msg.Namelen = uint32(salen)
810 var iov Iovec
811 if len(p) > 0 {
812 iov.Base = &p[0]
813 iov.SetLen(len(p))
814 }
815 var dummy byte
816 if len(oob) > 0 {
817 if len(p) == 0 {
818 var sockType int
819 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
820 if err != nil {
821 return 0, err
822 }
823 // send at least one normal byte
824 if sockType != SOCK_DGRAM {
825 iov.Base = &dummy
826 iov.SetLen(1)
827 }
828 }
829 msg.Control = &oob[0]
830 msg.SetControllen(len(oob))
831 }
832 msg.Iov = &iov
833 msg.Iovlen = 1
834 if n, err = sendmsg(fd, &msg, flags); err != nil {
835 return 0, err
836 }
837 if len(oob) > 0 && len(p) == 0 {
838 n = 0
839 }
840 return n, nil
841 }
842
843 // BindToDevice binds the socket associated with fd to device.
844 func BindToDevice(fd int, device string) (err error) {
845 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
846 }
847
848 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
849 //sys ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE
850
851 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
852 // The peek requests are machine-size oriented, so we wrap it
853 // to retrieve arbitrary-length data.
854
855 // The ptrace syscall differs from glibc's ptrace.
856 // Peeks returns the word in *data, not as the return value.
857
858 var buf [sizeofPtr]byte
859
860 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
861 // access (PEEKUSER warns that it might), but if we don't
862 // align our reads, we might straddle an unmapped page
863 // boundary and not get the bytes leading up to the page
864 // boundary.
865 n := 0
866 if addr%sizeofPtr != 0 {
867 err = ptracePtr(req, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
868 if err != nil {
869 return 0, err
870 }
871 n += copy(out, buf[addr%sizeofPtr:])
872 out = out[n:]
873 }
874
875 // Remainder.
876 for len(out) > 0 {
877 // We use an internal buffer to guarantee alignment.
878 // It's not documented if this is necessary, but we're paranoid.
879 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
880 if err != nil {
881 return n, err
882 }
883 copied := copy(out, buf[0:])
884 n += copied
885 out = out[copied:]
886 }
887
888 return n, nil
889 }
890
891 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
892 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
893 }
894
895 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
896 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
897 }
898
899 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
900 // As for ptracePeek, we need to align our accesses to deal
901 // with the possibility of straddling an invalid page.
902
903 // Leading edge.
904 n := 0
905 if addr%sizeofPtr != 0 {
906 var buf [sizeofPtr]byte
907 err = ptracePtr(peekReq, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
908 if err != nil {
909 return 0, err
910 }
911 n += copy(buf[addr%sizeofPtr:], data)
912 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
913 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
914 if err != nil {
915 return 0, err
916 }
917 data = data[n:]
918 }
919
920 // Interior.
921 for len(data) > sizeofPtr {
922 word := *((*uintptr)(unsafe.Pointer(&data[0])))
923 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
924 if err != nil {
925 return n, err
926 }
927 n += sizeofPtr
928 data = data[sizeofPtr:]
929 }
930
931 // Trailing edge.
932 if len(data) > 0 {
933 var buf [sizeofPtr]byte
934 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
935 if err != nil {
936 return n, err
937 }
938 copy(buf[0:], data)
939 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
940 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
941 if err != nil {
942 return n, err
943 }
944 n += len(data)
945 }
946
947 return n, nil
948 }
949
950 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
951 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
952 }
953
954 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
955 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
956 }
957
958 const (
959 _NT_PRSTATUS = 1
960 )
961
962 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
963 var iov Iovec
964 iov.Base = (*byte)(unsafe.Pointer(regsout))
965 iov.SetLen(int(unsafe.Sizeof(*regsout)))
966 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
967 }
968
969 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
970 var iov Iovec
971 iov.Base = (*byte)(unsafe.Pointer(regs))
972 iov.SetLen(int(unsafe.Sizeof(*regs)))
973 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
974 }
975
976 func PtraceSetOptions(pid int, options int) (err error) {
977 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
978 }
979
980 func PtraceGetEventMsg(pid int) (msg uint, err error) {
981 var data _C_long
982 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
983 msg = uint(data)
984 return
985 }
986
987 func PtraceCont(pid int, signal int) (err error) {
988 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
989 }
990
991 func PtraceSyscall(pid int, signal int) (err error) {
992 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
993 }
994
995 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
996
997 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
998
999 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1000
1001 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
1002
1003 func Reboot(cmd int) (err error) {
1004 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1005 }
1006
1007 func ReadDirent(fd int, buf []byte) (n int, err error) {
1008 return Getdents(fd, buf)
1009 }
1010
1011 func direntIno(buf []byte) (uint64, bool) {
1012 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1013 }
1014
1015 func direntReclen(buf []byte) (uint64, bool) {
1016 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1017 }
1018
1019 func direntNamlen(buf []byte) (uint64, bool) {
1020 reclen, ok := direntReclen(buf)
1021 if !ok {
1022 return 0, false
1023 }
1024 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1025 }
1026
1027 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
1028
1029 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1030 // Certain file systems get rather angry and EINVAL if you give
1031 // them an empty string of data, rather than NULL.
1032 if data == "" {
1033 return mount(source, target, fstype, flags, nil)
1034 }
1035 datap, err := BytePtrFromString(data)
1036 if err != nil {
1037 return err
1038 }
1039 return mount(source, target, fstype, flags, datap)
1040 }
1041
1042 // Sendto
1043 // Recvfrom
1044 // Socketpair
1045
1046 /*
1047 * Direct access
1048 */
1049 //sys Acct(path string) (err error)
1050 //sys Adjtimex(buf *Timex) (state int, err error)
1051 //sys Chdir(path string) (err error)
1052 //sys Chroot(path string) (err error)
1053 //sys Close(fd int) (err error)
1054 //sys Dup(oldfd int) (fd int, err error)
1055 //sys Dup3(oldfd int, newfd int, flags int) (err error)
1056 //sysnb EpollCreate1(flag int) (fd int, err error)
1057 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
1058 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
1059 //sys Fchdir(fd int) (err error)
1060 //sys Fchmod(fd int, mode uint32) (err error)
1061 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
1062 //sys fcntl(fd int, cmd int, arg int) (val int, err error)
1063 //sys Fdatasync(fd int) (err error)
1064 //sys Flock(fd int, how int) (err error)
1065 //sys Fsync(fd int) (err error)
1066 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
1067 //sysnb Getpgid(pid int) (pgid int, err error)
1068
1069 func Getpgrp() (pid int) {
1070 pid, _ = Getpgid(0)
1071 return
1072 }
1073
1074 //sysnb Getpid() (pid int)
1075 //sysnb Getppid() (ppid int)
1076 //sys Getpriority(which int, who int) (prio int, err error)
1077 //sysnb Getrusage(who int, rusage *Rusage) (err error)
1078 //sysnb Gettid() (tid int)
1079 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
1080 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
1081 //sysnb InotifyInit1(flags int) (fd int, err error)
1082 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
1083 //sysnb Kill(pid int, sig Signal) (err error)
1084 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
1085 //sys Listxattr(path string, dest []byte) (sz int, err error)
1086 //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
1087 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
1088 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
1089 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
1090 //sysnb prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
1091 //sys read(fd int, p []byte) (n int, err error)
1092 //sys Removexattr(path string, attr string) (err error)
1093 //sys Setdomainname(p []byte) (err error)
1094 //sys Sethostname(p []byte) (err error)
1095 //sysnb Setpgid(pid int, pgid int) (err error)
1096 //sysnb Setsid() (pid int, err error)
1097 //sysnb Settimeofday(tv *Timeval) (err error)
1098
1099 // Provided by runtime.syscall_runtime_doAllThreadsSyscall which stops the
1100 // world and invokes the syscall on each OS thread. Once this function returns,
1101 // all threads are in sync.
1102 //
1103 //go:uintptrescapes
1104 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1105
1106 // AllThreadsSyscall performs a syscall on each OS thread of the Go
1107 // runtime. It first invokes the syscall on one thread. Should that
1108 // invocation fail, it returns immediately with the error status.
1109 // Otherwise, it invokes the syscall on all of the remaining threads
1110 // in parallel. It will terminate the program if it observes any
1111 // invoked syscall's return value differs from that of the first
1112 // invocation.
1113 //
1114 // AllThreadsSyscall is intended for emulating simultaneous
1115 // process-wide state changes that require consistently modifying
1116 // per-thread state of the Go runtime.
1117 //
1118 // AllThreadsSyscall is unaware of any threads that are launched
1119 // explicitly by cgo linked code, so the function always returns
1120 // [ENOTSUP] in binaries that use cgo.
1121 //
1122 //go:uintptrescapes
1123 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1124 if cgo_libc_setegid != nil {
1125 return minus1, minus1, ENOTSUP
1126 }
1127 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1128 return r1, r2, Errno(errno)
1129 }
1130
1131 // AllThreadsSyscall6 is like [AllThreadsSyscall], but extended to six
1132 // arguments.
1133 //
1134 //go:uintptrescapes
1135 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1136 if cgo_libc_setegid != nil {
1137 return minus1, minus1, ENOTSUP
1138 }
1139 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1140 return r1, r2, Errno(errno)
1141 }
1142
1143 // linked by runtime.cgocall.go
1144 //
1145 //go:uintptrescapes
1146 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1147
1148 var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked.
1149
1150 const minus1 = ^uintptr(0)
1151
1152 func Setegid(egid int) (err error) {
1153 if cgo_libc_setegid == nil {
1154 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1155 err = errnoErr(e1)
1156 }
1157 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1158 err = errnoErr(Errno(ret))
1159 }
1160 return
1161 }
1162
1163 var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked.
1164
1165 func Seteuid(euid int) (err error) {
1166 if cgo_libc_seteuid == nil {
1167 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1168 err = errnoErr(e1)
1169 }
1170 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1171 err = errnoErr(Errno(ret))
1172 }
1173 return
1174 }
1175
1176 var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked.
1177
1178 func Setgid(gid int) (err error) {
1179 if cgo_libc_setgid == nil {
1180 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1181 err = errnoErr(e1)
1182 }
1183 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1184 err = errnoErr(Errno(ret))
1185 }
1186 return
1187 }
1188
1189 var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked.
1190
1191 func Setregid(rgid, egid int) (err error) {
1192 if cgo_libc_setregid == nil {
1193 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1194 err = errnoErr(e1)
1195 }
1196 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1197 err = errnoErr(Errno(ret))
1198 }
1199 return
1200 }
1201
1202 var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked.
1203
1204 func Setresgid(rgid, egid, sgid int) (err error) {
1205 if cgo_libc_setresgid == nil {
1206 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1207 err = errnoErr(e1)
1208 }
1209 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1210 err = errnoErr(Errno(ret))
1211 }
1212 return
1213 }
1214
1215 var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked.
1216
1217 func Setresuid(ruid, euid, suid int) (err error) {
1218 if cgo_libc_setresuid == nil {
1219 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1220 err = errnoErr(e1)
1221 }
1222 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1223 err = errnoErr(Errno(ret))
1224 }
1225 return
1226 }
1227
1228 var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked.
1229
1230 func Setreuid(ruid, euid int) (err error) {
1231 if cgo_libc_setreuid == nil {
1232 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1233 err = errnoErr(e1)
1234 }
1235 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1236 err = errnoErr(Errno(ret))
1237 }
1238 return
1239 }
1240
1241 var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked.
1242
1243 func Setuid(uid int) (err error) {
1244 if cgo_libc_setuid == nil {
1245 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1246 err = errnoErr(e1)
1247 }
1248 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1249 err = errnoErr(Errno(ret))
1250 }
1251 return
1252 }
1253
1254 //sys Setpriority(which int, who int, prio int) (err error)
1255 //sys Setxattr(path string, attr string, data []byte, flags int) (err error)
1256 //sys Sync()
1257 //sysnb Sysinfo(info *Sysinfo_t) (err error)
1258 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
1259 //sysnb Tgkill(tgid int, tid int, sig Signal) (err error)
1260 //sysnb Times(tms *Tms) (ticks uintptr, err error)
1261 //sysnb Umask(mask int) (oldmask int)
1262 //sysnb Uname(buf *Utsname) (err error)
1263 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
1264 //sys Unshare(flags int) (err error)
1265 //sys write(fd int, p []byte) (n int, err error)
1266 //sys exitThread(code int) (err error) = SYS_EXIT
1267 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
1268
1269 // mmap varies by architecture; see syscall_linux_*.go.
1270 //sys munmap(addr uintptr, length uintptr) (err error)
1271
1272 var mapper = &mmapper{
1273 active: make(map[*byte][]byte),
1274 mmap: mmap,
1275 munmap: munmap,
1276 }
1277
1278 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1279 return mapper.Mmap(fd, offset, length, prot, flags)
1280 }
1281
1282 func Munmap(b []byte) (err error) {
1283 return mapper.Munmap(b)
1284 }
1285
1286 //sys Madvise(b []byte, advice int) (err error)
1287 //sys Mprotect(b []byte, prot int) (err error)
1288 //sys Mlock(b []byte) (err error)
1289 //sys Munlock(b []byte) (err error)
1290 //sys Mlockall(flags int) (err error)
1291 //sys Munlockall() (err error)
1292
1293 func Getrlimit(resource int, rlim *Rlimit) (err error) {
1294 // prlimit1 is the same as prlimit when newlimit == nil
1295 return prlimit1(0, resource, nil, rlim)
1296 }
1297
1298 // setrlimit sets a resource limit.
1299 // The Setrlimit function is in rlimit.go, and calls this one.
1300 func setrlimit(resource int, rlim *Rlimit) (err error) {
1301 return prlimit1(0, resource, rlim, nil)
1302 }
1303
1304 // prlimit changes a resource limit. We use a single definition so that
1305 // we can tell StartProcess to not restore the original NOFILE limit.
1306 //
1307 // golang.org/x/sys linknames prlimit.
1308 // Do not remove or change the type signature.
1309 //
1310 //go:linkname prlimit
1311 func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
1312 err = prlimit1(pid, resource, newlimit, old)
1313 if err == nil && newlimit != nil && resource == RLIMIT_NOFILE && (pid == 0 || pid == Getpid()) {
1314 origRlimitNofile.Store(nil)
1315 }
1316 return err
1317 }
1318