Source file
src/syscall/syscall_linux.go
Documentation: syscall
1
2
3
4
5
6
7
8
9
10
11
12 package syscall
13
14 import (
15 "internal/itoa"
16 "runtime"
17 "unsafe"
18 )
19
20
21
22
23
24
25 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
26
27
28
29
30
31
32
33
34
35 func runtime_entersyscall()
36
37
38 func runtime_exitsyscall()
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
62 return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
63 }
64
65
66
67
68 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
69 runtime_entersyscall()
70
71
72
73
74
75
76
77
78
79
80
81
82 r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
83 runtime_exitsyscall()
84 return
85 }
86
87
88
89
90 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
91 runtime_entersyscall()
92 r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
93 runtime_exitsyscall()
94 return
95 }
96
97 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
98 func rawVforkSyscall(trap, a1, a2, a3 uintptr) (r1 uintptr, err Errno)
99
100
103
104 func Access(path string, mode uint32) (err error) {
105 return Faccessat(_AT_FDCWD, path, mode, 0)
106 }
107
108 func Chmod(path string, mode uint32) (err error) {
109 return Fchmodat(_AT_FDCWD, path, mode, 0)
110 }
111
112 func Chown(path string, uid int, gid int) (err error) {
113 return Fchownat(_AT_FDCWD, path, uid, gid, 0)
114 }
115
116 func Creat(path string, mode uint32) (fd int, err error) {
117 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
118 }
119
120 func EpollCreate(size int) (fd int, err error) {
121 if size <= 0 {
122 return -1, EINVAL
123 }
124 return EpollCreate1(0)
125 }
126
127 func isGroupMember(gid int) bool {
128 groups, err := Getgroups()
129 if err != nil {
130 return false
131 }
132
133 for _, g := range groups {
134 if g == gid {
135 return true
136 }
137 }
138 return false
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
152
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
160
161
162
163
164
165
166 if runtime.GOOS != "android" {
167 if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
168 return err
169 }
170 }
171
172
173
174
175
176
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
193 var uid int
194 if flags&_AT_EACCESS != 0 {
195 uid = Geteuid()
196 if uid != 0 && isCapDacOverrideSet() {
197
198
199
200 uid = 0
201 }
202 } else {
203 uid = Getuid()
204 }
205
206 if uid == 0 {
207 if mode&1 == 0 {
208
209 return nil
210 }
211 if st.Mode&0111 != 0 {
212
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
244
245
246 func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
247
248
249 if flags != 0 {
250 err := fchmodat2(dirfd, path, mode, flags)
251 if err == ENOSYS {
252
253
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
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
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
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
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
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
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
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
363
364 return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
365 }
366
367 const ImplementsGetwd = true
368
369
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
378 if n < 1 || n > len(buf) || buf[n-1] != 0 {
379 return "", EINVAL
380 }
381
382
383
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
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
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
453
454
455
456
457
458
459
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
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 if n == len(sa.raw.Path) && name[0] != '@' {
554 return nil, 0, EINVAL
555 }
556 sa.raw.Family = AF_UNIX
557 for i := 0; i < n; i++ {
558 sa.raw.Path[i] = int8(name[i])
559 }
560
561 sl := _Socklen(2)
562 if n > 0 {
563 sl += _Socklen(n) + 1
564 }
565 if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
566
567 sa.raw.Path[0] = 0
568
569 sl--
570 }
571
572 return unsafe.Pointer(&sa.raw), sl, nil
573 }
574
575 type SockaddrLinklayer struct {
576 Protocol uint16
577 Ifindex int
578 Hatype uint16
579 Pkttype uint8
580 Halen uint8
581 Addr [8]byte
582 raw RawSockaddrLinklayer
583 }
584
585 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
586 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
587 return nil, 0, EINVAL
588 }
589 sa.raw.Family = AF_PACKET
590 sa.raw.Protocol = sa.Protocol
591 sa.raw.Ifindex = int32(sa.Ifindex)
592 sa.raw.Hatype = sa.Hatype
593 sa.raw.Pkttype = sa.Pkttype
594 sa.raw.Halen = sa.Halen
595 sa.raw.Addr = sa.Addr
596 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
597 }
598
599 type SockaddrNetlink struct {
600 Family uint16
601 Pad uint16
602 Pid uint32
603 Groups uint32
604 raw RawSockaddrNetlink
605 }
606
607 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
608 sa.raw.Family = AF_NETLINK
609 sa.raw.Pad = sa.Pad
610 sa.raw.Pid = sa.Pid
611 sa.raw.Groups = sa.Groups
612 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
613 }
614
615 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
616 switch rsa.Addr.Family {
617 case AF_NETLINK:
618 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
619 sa := new(SockaddrNetlink)
620 sa.Family = pp.Family
621 sa.Pad = pp.Pad
622 sa.Pid = pp.Pid
623 sa.Groups = pp.Groups
624 return sa, nil
625
626 case AF_PACKET:
627 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
628 sa := new(SockaddrLinklayer)
629 sa.Protocol = pp.Protocol
630 sa.Ifindex = int(pp.Ifindex)
631 sa.Hatype = pp.Hatype
632 sa.Pkttype = pp.Pkttype
633 sa.Halen = pp.Halen
634 sa.Addr = pp.Addr
635 return sa, nil
636
637 case AF_UNIX:
638 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
639 sa := new(SockaddrUnix)
640 if pp.Path[0] == 0 {
641
642
643
644
645
646 pp.Path[0] = '@'
647 }
648
649
650
651
652
653
654 n := 0
655 for n < len(pp.Path) && pp.Path[n] != 0 {
656 n++
657 }
658 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
659 return sa, nil
660
661 case AF_INET:
662 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
663 sa := new(SockaddrInet4)
664 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
665 sa.Port = int(p[0])<<8 + int(p[1])
666 sa.Addr = pp.Addr
667 return sa, nil
668
669 case AF_INET6:
670 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
671 sa := new(SockaddrInet6)
672 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
673 sa.Port = int(p[0])<<8 + int(p[1])
674 sa.ZoneId = pp.Scope_id
675 sa.Addr = pp.Addr
676 return sa, nil
677 }
678 return nil, EAFNOSUPPORT
679 }
680
681 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
682 var rsa RawSockaddrAny
683 var len _Socklen = SizeofSockaddrAny
684 nfd, err = accept4(fd, &rsa, &len, flags)
685 if err != nil {
686 return
687 }
688 if len > SizeofSockaddrAny {
689 panic("RawSockaddrAny too small")
690 }
691 sa, err = anyToSockaddr(&rsa)
692 if err != nil {
693 Close(nfd)
694 nfd = 0
695 }
696 return
697 }
698
699 func Getsockname(fd int) (sa Sockaddr, err error) {
700 var rsa RawSockaddrAny
701 var len _Socklen = SizeofSockaddrAny
702 if err = getsockname(fd, &rsa, &len); err != nil {
703 return
704 }
705 return anyToSockaddr(&rsa)
706 }
707
708 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
709 vallen := _Socklen(4)
710 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
711 return value, err
712 }
713
714 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
715 var value IPMreq
716 vallen := _Socklen(SizeofIPMreq)
717 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
718 return &value, err
719 }
720
721 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
722 var value IPMreqn
723 vallen := _Socklen(SizeofIPMreqn)
724 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
725 return &value, err
726 }
727
728 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
729 var value IPv6Mreq
730 vallen := _Socklen(SizeofIPv6Mreq)
731 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
732 return &value, err
733 }
734
735 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
736 var value IPv6MTUInfo
737 vallen := _Socklen(SizeofIPv6MTUInfo)
738 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
739 return &value, err
740 }
741
742 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
743 var value ICMPv6Filter
744 vallen := _Socklen(SizeofICMPv6Filter)
745 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
746 return &value, err
747 }
748
749 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
750 var value Ucred
751 vallen := _Socklen(SizeofUcred)
752 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
753 return &value, err
754 }
755
756 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
757 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
758 }
759
760 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
761 var msg Msghdr
762 msg.Name = (*byte)(unsafe.Pointer(rsa))
763 msg.Namelen = uint32(SizeofSockaddrAny)
764 var iov Iovec
765 if len(p) > 0 {
766 iov.Base = &p[0]
767 iov.SetLen(len(p))
768 }
769 var dummy byte
770 if len(oob) > 0 {
771 if len(p) == 0 {
772 var sockType int
773 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
774 if err != nil {
775 return
776 }
777
778 if sockType != SOCK_DGRAM {
779 iov.Base = &dummy
780 iov.SetLen(1)
781 }
782 }
783 msg.Control = &oob[0]
784 msg.SetControllen(len(oob))
785 }
786 msg.Iov = &iov
787 msg.Iovlen = 1
788 if n, err = recvmsg(fd, &msg, flags); err != nil {
789 return
790 }
791 oobn = int(msg.Controllen)
792 recvflags = int(msg.Flags)
793 return
794 }
795
796 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
797 var msg Msghdr
798 msg.Name = (*byte)(ptr)
799 msg.Namelen = uint32(salen)
800 var iov Iovec
801 if len(p) > 0 {
802 iov.Base = &p[0]
803 iov.SetLen(len(p))
804 }
805 var dummy byte
806 if len(oob) > 0 {
807 if len(p) == 0 {
808 var sockType int
809 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
810 if err != nil {
811 return 0, err
812 }
813
814 if sockType != SOCK_DGRAM {
815 iov.Base = &dummy
816 iov.SetLen(1)
817 }
818 }
819 msg.Control = &oob[0]
820 msg.SetControllen(len(oob))
821 }
822 msg.Iov = &iov
823 msg.Iovlen = 1
824 if n, err = sendmsg(fd, &msg, flags); err != nil {
825 return 0, err
826 }
827 if len(oob) > 0 && len(p) == 0 {
828 n = 0
829 }
830 return n, nil
831 }
832
833
834 func BindToDevice(fd int, device string) (err error) {
835 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
836 }
837
838
839
840
841 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
842
843
844
845
846
847
848 var buf [sizeofPtr]byte
849
850
851
852
853
854
855 n := 0
856 if addr%sizeofPtr != 0 {
857 err = ptracePtr(req, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
858 if err != nil {
859 return 0, err
860 }
861 n += copy(out, buf[addr%sizeofPtr:])
862 out = out[n:]
863 }
864
865
866 for len(out) > 0 {
867
868
869 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
870 if err != nil {
871 return n, err
872 }
873 copied := copy(out, buf[0:])
874 n += copied
875 out = out[copied:]
876 }
877
878 return n, nil
879 }
880
881 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
882 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
883 }
884
885 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
886 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
887 }
888
889 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
890
891
892
893
894 n := 0
895 if addr%sizeofPtr != 0 {
896 var buf [sizeofPtr]byte
897 err = ptracePtr(peekReq, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
898 if err != nil {
899 return 0, err
900 }
901 n += copy(buf[addr%sizeofPtr:], data)
902 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
903 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
904 if err != nil {
905 return 0, err
906 }
907 data = data[n:]
908 }
909
910
911 for len(data) > sizeofPtr {
912 word := *((*uintptr)(unsafe.Pointer(&data[0])))
913 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
914 if err != nil {
915 return n, err
916 }
917 n += sizeofPtr
918 data = data[sizeofPtr:]
919 }
920
921
922 if len(data) > 0 {
923 var buf [sizeofPtr]byte
924 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
925 if err != nil {
926 return n, err
927 }
928 copy(buf[0:], data)
929 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
930 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
931 if err != nil {
932 return n, err
933 }
934 n += len(data)
935 }
936
937 return n, nil
938 }
939
940 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
941 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
942 }
943
944 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
945 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
946 }
947
948 const (
949 _NT_PRSTATUS = 1
950 )
951
952 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
953 var iov Iovec
954 iov.Base = (*byte)(unsafe.Pointer(regsout))
955 iov.SetLen(int(unsafe.Sizeof(*regsout)))
956 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
957 }
958
959 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
960 var iov Iovec
961 iov.Base = (*byte)(unsafe.Pointer(regs))
962 iov.SetLen(int(unsafe.Sizeof(*regs)))
963 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
964 }
965
966 func PtraceSetOptions(pid int, options int) (err error) {
967 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
968 }
969
970 func PtraceGetEventMsg(pid int) (msg uint, err error) {
971 var data _C_long
972 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
973 msg = uint(data)
974 return
975 }
976
977 func PtraceCont(pid int, signal int) (err error) {
978 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
979 }
980
981 func PtraceSyscall(pid int, signal int) (err error) {
982 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
983 }
984
985 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
986
987 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
988
989 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
990
991
992
993 func Reboot(cmd int) (err error) {
994 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
995 }
996
997 func ReadDirent(fd int, buf []byte) (n int, err error) {
998 return Getdents(fd, buf)
999 }
1000
1001 func direntIno(buf []byte) (uint64, bool) {
1002 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1003 }
1004
1005 func direntReclen(buf []byte) (uint64, bool) {
1006 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1007 }
1008
1009 func direntNamlen(buf []byte) (uint64, bool) {
1010 reclen, ok := direntReclen(buf)
1011 if !ok {
1012 return 0, false
1013 }
1014 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1015 }
1016
1017
1018
1019 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1020
1021
1022 if data == "" {
1023 return mount(source, target, fstype, flags, nil)
1024 }
1025 datap, err := BytePtrFromString(data)
1026 if err != nil {
1027 return err
1028 }
1029 return mount(source, target, fstype, flags, datap)
1030 }
1031
1032
1033
1034
1035
1036
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059 func Getpgrp() (pid int) {
1060 pid, _ = Getpgid(0)
1061 return
1062 }
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1114 if cgo_libc_setegid != nil {
1115 return minus1, minus1, ENOTSUP
1116 }
1117 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1118 return r1, r2, Errno(errno)
1119 }
1120
1121
1122
1123
1124
1125 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1126 if cgo_libc_setegid != nil {
1127 return minus1, minus1, ENOTSUP
1128 }
1129 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1130 return r1, r2, Errno(errno)
1131 }
1132
1133
1134
1135
1136 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1137
1138 var cgo_libc_setegid unsafe.Pointer
1139
1140 const minus1 = ^uintptr(0)
1141
1142 func Setegid(egid int) (err error) {
1143 if cgo_libc_setegid == nil {
1144 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1145 err = errnoErr(e1)
1146 }
1147 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1148 err = errnoErr(Errno(ret))
1149 }
1150 return
1151 }
1152
1153 var cgo_libc_seteuid unsafe.Pointer
1154
1155 func Seteuid(euid int) (err error) {
1156 if cgo_libc_seteuid == nil {
1157 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1158 err = errnoErr(e1)
1159 }
1160 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1161 err = errnoErr(Errno(ret))
1162 }
1163 return
1164 }
1165
1166 var cgo_libc_setgid unsafe.Pointer
1167
1168 func Setgid(gid int) (err error) {
1169 if cgo_libc_setgid == nil {
1170 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1171 err = errnoErr(e1)
1172 }
1173 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1174 err = errnoErr(Errno(ret))
1175 }
1176 return
1177 }
1178
1179 var cgo_libc_setregid unsafe.Pointer
1180
1181 func Setregid(rgid, egid int) (err error) {
1182 if cgo_libc_setregid == nil {
1183 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1184 err = errnoErr(e1)
1185 }
1186 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1187 err = errnoErr(Errno(ret))
1188 }
1189 return
1190 }
1191
1192 var cgo_libc_setresgid unsafe.Pointer
1193
1194 func Setresgid(rgid, egid, sgid int) (err error) {
1195 if cgo_libc_setresgid == nil {
1196 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1197 err = errnoErr(e1)
1198 }
1199 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1200 err = errnoErr(Errno(ret))
1201 }
1202 return
1203 }
1204
1205 var cgo_libc_setresuid unsafe.Pointer
1206
1207 func Setresuid(ruid, euid, suid int) (err error) {
1208 if cgo_libc_setresuid == nil {
1209 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1210 err = errnoErr(e1)
1211 }
1212 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1213 err = errnoErr(Errno(ret))
1214 }
1215 return
1216 }
1217
1218 var cgo_libc_setreuid unsafe.Pointer
1219
1220 func Setreuid(ruid, euid int) (err error) {
1221 if cgo_libc_setreuid == nil {
1222 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1223 err = errnoErr(e1)
1224 }
1225 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1226 err = errnoErr(Errno(ret))
1227 }
1228 return
1229 }
1230
1231 var cgo_libc_setuid unsafe.Pointer
1232
1233 func Setuid(uid int) (err error) {
1234 if cgo_libc_setuid == nil {
1235 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1236 err = errnoErr(e1)
1237 }
1238 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1239 err = errnoErr(Errno(ret))
1240 }
1241 return
1242 }
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262 var mapper = &mmapper{
1263 active: make(map[*byte][]byte),
1264 mmap: mmap,
1265 munmap: munmap,
1266 }
1267
1268 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1269 return mapper.Mmap(fd, offset, length, prot, flags)
1270 }
1271
1272 func Munmap(b []byte) (err error) {
1273 return mapper.Munmap(b)
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
1287 err = prlimit1(pid, resource, newlimit, old)
1288 if err == nil && newlimit != nil && resource == RLIMIT_NOFILE {
1289 origRlimitNofile.Store(nil)
1290 }
1291 return err
1292 }
1293
View as plain text