Source file
src/syscall/syscall_linux.go
1
2
3
4
5
6
7
8
9
10
11
12 package syscall
13
14 import (
15 "internal/itoa"
16 "unsafe"
17 )
18
19
20
21
22
23
24 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
25
26
27
28
29
30
31
32
33
34 func runtime_entersyscall()
35
36
37 func runtime_exitsyscall()
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
61 return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
62 }
63
64
65
66
67 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
68 runtime_entersyscall()
69
70
71
72
73
74
75
76
77
78
79
80
81 r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
82 runtime_exitsyscall()
83 return
84 }
85
86
87
88
89 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
90 runtime_entersyscall()
91 r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
92 runtime_exitsyscall()
93 return
94 }
95
96 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
97
98
101
102 func Access(path string, mode uint32) (err error) {
103 return Faccessat(_AT_FDCWD, path, mode, 0)
104 }
105
106 func Chmod(path string, mode uint32) (err error) {
107 return Fchmodat(_AT_FDCWD, path, mode, 0)
108 }
109
110 func Chown(path string, uid int, gid int) (err error) {
111 return Fchownat(_AT_FDCWD, path, uid, gid, 0)
112 }
113
114 func Creat(path string, mode uint32) (fd int, err error) {
115 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
116 }
117
118 func isGroupMember(gid int) bool {
119 groups, err := Getgroups()
120 if err != nil {
121 return false
122 }
123
124 for _, g := range groups {
125 if g == gid {
126 return true
127 }
128 }
129 return false
130 }
131
132
133
134 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
135 if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
136 return EINVAL
137 }
138
139
140
141
142
143
144
145 if flags == 0 {
146 return faccessat(dirfd, path, mode)
147 }
148
149 var st Stat_t
150 if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
151 return err
152 }
153
154 mode &= 7
155 if mode == 0 {
156 return nil
157 }
158
159 var uid int
160 if flags&_AT_EACCESS != 0 {
161 uid = Geteuid()
162 } else {
163 uid = Getuid()
164 }
165
166 if uid == 0 {
167 if mode&1 == 0 {
168
169 return nil
170 }
171 if st.Mode&0111 != 0 {
172
173 return nil
174 }
175 return EACCES
176 }
177
178 var fmode uint32
179 if uint32(uid) == st.Uid {
180 fmode = (st.Mode >> 6) & 7
181 } else {
182 var gid int
183 if flags&_AT_EACCESS != 0 {
184 gid = Getegid()
185 } else {
186 gid = Getgid()
187 }
188
189 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
190 fmode = (st.Mode >> 3) & 7
191 } else {
192 fmode = st.Mode & 7
193 }
194 }
195
196 if fmode&mode == mode {
197 return nil
198 }
199
200 return EACCES
201 }
202
203
204
205 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
206
207
208
209 if flags&^_AT_SYMLINK_NOFOLLOW != 0 {
210 return EINVAL
211 } else if flags&_AT_SYMLINK_NOFOLLOW != 0 {
212 return EOPNOTSUPP
213 }
214 return fchmodat(dirfd, path, mode)
215 }
216
217
218
219 func Link(oldpath string, newpath string) (err error) {
220 return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0)
221 }
222
223 func Mkdir(path string, mode uint32) (err error) {
224 return Mkdirat(_AT_FDCWD, path, mode)
225 }
226
227 func Mknod(path string, mode uint32, dev int) (err error) {
228 return Mknodat(_AT_FDCWD, path, mode, dev)
229 }
230
231 func Open(path string, mode int, perm uint32) (fd int, err error) {
232 return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm)
233 }
234
235
236
237 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
238 return openat(dirfd, path, flags|O_LARGEFILE, mode)
239 }
240
241 func Pipe(p []int) error {
242 return Pipe2(p, 0)
243 }
244
245
246
247 func Pipe2(p []int, flags int) error {
248 if len(p) != 2 {
249 return EINVAL
250 }
251 var pp [2]_C_int
252 err := pipe2(&pp, flags)
253 if err == nil {
254 p[0] = int(pp[0])
255 p[1] = int(pp[1])
256 }
257 return err
258 }
259
260
261
262 func Readlink(path string, buf []byte) (n int, err error) {
263 return readlinkat(_AT_FDCWD, path, buf)
264 }
265
266 func Rename(oldpath string, newpath string) (err error) {
267 return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath)
268 }
269
270 func Rmdir(path string) error {
271 return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR)
272 }
273
274
275
276 func Symlink(oldpath string, newpath string) (err error) {
277 return symlinkat(oldpath, _AT_FDCWD, newpath)
278 }
279
280 func Unlink(path string) error {
281 return unlinkat(_AT_FDCWD, path, 0)
282 }
283
284
285
286 func Unlinkat(dirfd int, path string) error {
287 return unlinkat(dirfd, path, 0)
288 }
289
290 func Utimes(path string, tv []Timeval) (err error) {
291 if len(tv) != 2 {
292 return EINVAL
293 }
294 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
295 }
296
297
298
299 func UtimesNano(path string, ts []Timespec) (err error) {
300 if len(ts) != 2 {
301 return EINVAL
302 }
303 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
304 }
305
306 func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
307 if len(tv) != 2 {
308 return EINVAL
309 }
310 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
311 }
312
313 func Futimes(fd int, tv []Timeval) (err error) {
314
315
316 return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
317 }
318
319 const ImplementsGetwd = true
320
321
322
323 func Getwd() (wd string, err error) {
324 var buf [PathMax]byte
325 n, err := Getcwd(buf[0:])
326 if err != nil {
327 return "", err
328 }
329
330 if n < 1 || n > len(buf) || buf[n-1] != 0 {
331 return "", EINVAL
332 }
333
334
335
336 if buf[0] != '/' {
337 return "", ENOENT
338 }
339
340 return string(buf[0 : n-1]), nil
341 }
342
343 func Getgroups() (gids []int, err error) {
344 n, err := getgroups(0, nil)
345 if err != nil {
346 return nil, err
347 }
348 if n == 0 {
349 return nil, nil
350 }
351
352
353 if n < 0 || n > 1<<20 {
354 return nil, EINVAL
355 }
356
357 a := make([]_Gid_t, n)
358 n, err = getgroups(n, &a[0])
359 if err != nil {
360 return nil, err
361 }
362 gids = make([]int, n)
363 for i, v := range a[0:n] {
364 gids[i] = int(v)
365 }
366 return
367 }
368
369 var cgo_libc_setgroups unsafe.Pointer
370
371 func Setgroups(gids []int) (err error) {
372 n := uintptr(len(gids))
373 if n == 0 {
374 if cgo_libc_setgroups == nil {
375 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 {
376 err = errnoErr(e1)
377 }
378 return
379 }
380 if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 {
381 err = errnoErr(Errno(ret))
382 }
383 return
384 }
385
386 a := make([]_Gid_t, len(gids))
387 for i, v := range gids {
388 a[i] = _Gid_t(v)
389 }
390 if cgo_libc_setgroups == nil {
391 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 {
392 err = errnoErr(e1)
393 }
394 return
395 }
396 if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 {
397 err = errnoErr(Errno(ret))
398 }
399 return
400 }
401
402 type WaitStatus uint32
403
404
405
406
407
408
409
410
411
412
413 const (
414 mask = 0x7F
415 core = 0x80
416 exited = 0x00
417 stopped = 0x7F
418 shift = 8
419 )
420
421 func (w WaitStatus) Exited() bool { return w&mask == exited }
422
423 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
424
425 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
426
427 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
428
429 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
430
431 func (w WaitStatus) ExitStatus() int {
432 if !w.Exited() {
433 return -1
434 }
435 return int(w>>shift) & 0xFF
436 }
437
438 func (w WaitStatus) Signal() Signal {
439 if !w.Signaled() {
440 return -1
441 }
442 return Signal(w & mask)
443 }
444
445 func (w WaitStatus) StopSignal() Signal {
446 if !w.Stopped() {
447 return -1
448 }
449 return Signal(w>>shift) & 0xFF
450 }
451
452 func (w WaitStatus) TrapCause() int {
453 if w.StopSignal() != SIGTRAP {
454 return -1
455 }
456 return int(w>>shift) >> 8
457 }
458
459
460
461 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
462 var status _C_int
463 wpid, err = wait4(pid, &status, options, rusage)
464 if wstatus != nil {
465 *wstatus = WaitStatus(status)
466 }
467 return
468 }
469
470 func Mkfifo(path string, mode uint32) (err error) {
471 return Mknod(path, mode|S_IFIFO, 0)
472 }
473
474 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
475 if sa.Port < 0 || sa.Port > 0xFFFF {
476 return nil, 0, EINVAL
477 }
478 sa.raw.Family = AF_INET
479 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
480 p[0] = byte(sa.Port >> 8)
481 p[1] = byte(sa.Port)
482 sa.raw.Addr = sa.Addr
483 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
484 }
485
486 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
487 if sa.Port < 0 || sa.Port > 0xFFFF {
488 return nil, 0, EINVAL
489 }
490 sa.raw.Family = AF_INET6
491 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
492 p[0] = byte(sa.Port >> 8)
493 p[1] = byte(sa.Port)
494 sa.raw.Scope_id = sa.ZoneId
495 sa.raw.Addr = sa.Addr
496 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
497 }
498
499 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
500 name := sa.Name
501 n := len(name)
502 if n > len(sa.raw.Path) {
503 return nil, 0, EINVAL
504 }
505 if n == len(sa.raw.Path) && name[0] != '@' {
506 return nil, 0, EINVAL
507 }
508 sa.raw.Family = AF_UNIX
509 for i := 0; i < n; i++ {
510 sa.raw.Path[i] = int8(name[i])
511 }
512
513 sl := _Socklen(2)
514 if n > 0 {
515 sl += _Socklen(n) + 1
516 }
517 if sa.raw.Path[0] == '@' {
518 sa.raw.Path[0] = 0
519
520 sl--
521 }
522
523 return unsafe.Pointer(&sa.raw), sl, nil
524 }
525
526 type SockaddrLinklayer struct {
527 Protocol uint16
528 Ifindex int
529 Hatype uint16
530 Pkttype uint8
531 Halen uint8
532 Addr [8]byte
533 raw RawSockaddrLinklayer
534 }
535
536 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
537 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
538 return nil, 0, EINVAL
539 }
540 sa.raw.Family = AF_PACKET
541 sa.raw.Protocol = sa.Protocol
542 sa.raw.Ifindex = int32(sa.Ifindex)
543 sa.raw.Hatype = sa.Hatype
544 sa.raw.Pkttype = sa.Pkttype
545 sa.raw.Halen = sa.Halen
546 sa.raw.Addr = sa.Addr
547 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
548 }
549
550 type SockaddrNetlink struct {
551 Family uint16
552 Pad uint16
553 Pid uint32
554 Groups uint32
555 raw RawSockaddrNetlink
556 }
557
558 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
559 sa.raw.Family = AF_NETLINK
560 sa.raw.Pad = sa.Pad
561 sa.raw.Pid = sa.Pid
562 sa.raw.Groups = sa.Groups
563 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
564 }
565
566 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
567 switch rsa.Addr.Family {
568 case AF_NETLINK:
569 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
570 sa := new(SockaddrNetlink)
571 sa.Family = pp.Family
572 sa.Pad = pp.Pad
573 sa.Pid = pp.Pid
574 sa.Groups = pp.Groups
575 return sa, nil
576
577 case AF_PACKET:
578 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
579 sa := new(SockaddrLinklayer)
580 sa.Protocol = pp.Protocol
581 sa.Ifindex = int(pp.Ifindex)
582 sa.Hatype = pp.Hatype
583 sa.Pkttype = pp.Pkttype
584 sa.Halen = pp.Halen
585 sa.Addr = pp.Addr
586 return sa, nil
587
588 case AF_UNIX:
589 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
590 sa := new(SockaddrUnix)
591 if pp.Path[0] == 0 {
592
593
594
595
596
597 pp.Path[0] = '@'
598 }
599
600
601
602
603
604
605 n := 0
606 for n < len(pp.Path) && pp.Path[n] != 0 {
607 n++
608 }
609 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
610 sa.Name = string(bytes)
611 return sa, nil
612
613 case AF_INET:
614 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
615 sa := new(SockaddrInet4)
616 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
617 sa.Port = int(p[0])<<8 + int(p[1])
618 sa.Addr = pp.Addr
619 return sa, nil
620
621 case AF_INET6:
622 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
623 sa := new(SockaddrInet6)
624 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
625 sa.Port = int(p[0])<<8 + int(p[1])
626 sa.ZoneId = pp.Scope_id
627 sa.Addr = pp.Addr
628 return sa, nil
629 }
630 return nil, EAFNOSUPPORT
631 }
632
633 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
634 var rsa RawSockaddrAny
635 var len _Socklen = SizeofSockaddrAny
636 nfd, err = accept4(fd, &rsa, &len, flags)
637 if err != nil {
638 return
639 }
640 if len > SizeofSockaddrAny {
641 panic("RawSockaddrAny too small")
642 }
643 sa, err = anyToSockaddr(&rsa)
644 if err != nil {
645 Close(nfd)
646 nfd = 0
647 }
648 return
649 }
650
651 func Getsockname(fd int) (sa Sockaddr, err error) {
652 var rsa RawSockaddrAny
653 var len _Socklen = SizeofSockaddrAny
654 if err = getsockname(fd, &rsa, &len); err != nil {
655 return
656 }
657 return anyToSockaddr(&rsa)
658 }
659
660 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
661 vallen := _Socklen(4)
662 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
663 return value, err
664 }
665
666 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
667 var value IPMreq
668 vallen := _Socklen(SizeofIPMreq)
669 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
670 return &value, err
671 }
672
673 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
674 var value IPMreqn
675 vallen := _Socklen(SizeofIPMreqn)
676 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
677 return &value, err
678 }
679
680 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
681 var value IPv6Mreq
682 vallen := _Socklen(SizeofIPv6Mreq)
683 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
684 return &value, err
685 }
686
687 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
688 var value IPv6MTUInfo
689 vallen := _Socklen(SizeofIPv6MTUInfo)
690 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
691 return &value, err
692 }
693
694 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
695 var value ICMPv6Filter
696 vallen := _Socklen(SizeofICMPv6Filter)
697 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
698 return &value, err
699 }
700
701 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
702 var value Ucred
703 vallen := _Socklen(SizeofUcred)
704 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
705 return &value, err
706 }
707
708 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
709 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
710 }
711
712 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
713 var msg Msghdr
714 msg.Name = (*byte)(unsafe.Pointer(rsa))
715 msg.Namelen = uint32(SizeofSockaddrAny)
716 var iov Iovec
717 if len(p) > 0 {
718 iov.Base = &p[0]
719 iov.SetLen(len(p))
720 }
721 var dummy byte
722 if len(oob) > 0 {
723 if len(p) == 0 {
724 var sockType int
725 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
726 if err != nil {
727 return
728 }
729
730 if sockType != SOCK_DGRAM {
731 iov.Base = &dummy
732 iov.SetLen(1)
733 }
734 }
735 msg.Control = &oob[0]
736 msg.SetControllen(len(oob))
737 }
738 msg.Iov = &iov
739 msg.Iovlen = 1
740 if n, err = recvmsg(fd, &msg, flags); err != nil {
741 return
742 }
743 oobn = int(msg.Controllen)
744 recvflags = int(msg.Flags)
745 return
746 }
747
748 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
749 var msg Msghdr
750 msg.Name = (*byte)(ptr)
751 msg.Namelen = uint32(salen)
752 var iov Iovec
753 if len(p) > 0 {
754 iov.Base = &p[0]
755 iov.SetLen(len(p))
756 }
757 var dummy byte
758 if len(oob) > 0 {
759 if len(p) == 0 {
760 var sockType int
761 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
762 if err != nil {
763 return 0, err
764 }
765
766 if sockType != SOCK_DGRAM {
767 iov.Base = &dummy
768 iov.SetLen(1)
769 }
770 }
771 msg.Control = &oob[0]
772 msg.SetControllen(len(oob))
773 }
774 msg.Iov = &iov
775 msg.Iovlen = 1
776 if n, err = sendmsg(fd, &msg, flags); err != nil {
777 return 0, err
778 }
779 if len(oob) > 0 && len(p) == 0 {
780 n = 0
781 }
782 return n, nil
783 }
784
785
786 func BindToDevice(fd int, device string) (err error) {
787 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
788 }
789
790
791
792 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
793
794
795
796
797
798
799 var buf [sizeofPtr]byte
800
801
802
803
804
805
806 n := 0
807 if addr%sizeofPtr != 0 {
808 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
809 if err != nil {
810 return 0, err
811 }
812 n += copy(out, buf[addr%sizeofPtr:])
813 out = out[n:]
814 }
815
816
817 for len(out) > 0 {
818
819
820 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
821 if err != nil {
822 return n, err
823 }
824 copied := copy(out, buf[0:])
825 n += copied
826 out = out[copied:]
827 }
828
829 return n, nil
830 }
831
832 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
833 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
834 }
835
836 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
837 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
838 }
839
840 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
841
842
843
844
845 n := 0
846 if addr%sizeofPtr != 0 {
847 var buf [sizeofPtr]byte
848 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
849 if err != nil {
850 return 0, err
851 }
852 n += copy(buf[addr%sizeofPtr:], data)
853 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
854 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
855 if err != nil {
856 return 0, err
857 }
858 data = data[n:]
859 }
860
861
862 for len(data) > sizeofPtr {
863 word := *((*uintptr)(unsafe.Pointer(&data[0])))
864 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
865 if err != nil {
866 return n, err
867 }
868 n += sizeofPtr
869 data = data[sizeofPtr:]
870 }
871
872
873 if len(data) > 0 {
874 var buf [sizeofPtr]byte
875 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
876 if err != nil {
877 return n, err
878 }
879 copy(buf[0:], data)
880 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
881 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
882 if err != nil {
883 return n, err
884 }
885 n += len(data)
886 }
887
888 return n, nil
889 }
890
891 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
892 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
893 }
894
895 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
896 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
897 }
898
899 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
900 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
901 }
902
903 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
904 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
905 }
906
907 func PtraceSetOptions(pid int, options int) (err error) {
908 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
909 }
910
911 func PtraceGetEventMsg(pid int) (msg uint, err error) {
912 var data _C_long
913 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
914 msg = uint(data)
915 return
916 }
917
918 func PtraceCont(pid int, signal int) (err error) {
919 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
920 }
921
922 func PtraceSyscall(pid int, signal int) (err error) {
923 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
924 }
925
926 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
927
928 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
929
930 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
931
932
933
934 func Reboot(cmd int) (err error) {
935 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
936 }
937
938 func ReadDirent(fd int, buf []byte) (n int, err error) {
939 return Getdents(fd, buf)
940 }
941
942 func direntIno(buf []byte) (uint64, bool) {
943 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
944 }
945
946 func direntReclen(buf []byte) (uint64, bool) {
947 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
948 }
949
950 func direntNamlen(buf []byte) (uint64, bool) {
951 reclen, ok := direntReclen(buf)
952 if !ok {
953 return 0, false
954 }
955 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
956 }
957
958
959
960 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
961
962
963 if data == "" {
964 return mount(source, target, fstype, flags, nil)
965 }
966 datap, err := BytePtrFromString(data)
967 if err != nil {
968 return err
969 }
970 return mount(source, target, fstype, flags, datap)
971 }
972
973
974
975
976
977
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000 func Getpgrp() (pid int) {
1001 pid, _ = Getpgid(0)
1002 return
1003 }
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1055 if cgo_libc_setegid != nil {
1056 return minus1, minus1, ENOTSUP
1057 }
1058 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1059 return r1, r2, Errno(errno)
1060 }
1061
1062
1063
1064
1065
1066 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1067 if cgo_libc_setegid != nil {
1068 return minus1, minus1, ENOTSUP
1069 }
1070 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1071 return r1, r2, Errno(errno)
1072 }
1073
1074
1075
1076
1077 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1078
1079 var cgo_libc_setegid unsafe.Pointer
1080
1081 const minus1 = ^uintptr(0)
1082
1083 func Setegid(egid int) (err error) {
1084 if cgo_libc_setegid == nil {
1085 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1086 err = errnoErr(e1)
1087 }
1088 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1089 err = errnoErr(Errno(ret))
1090 }
1091 return
1092 }
1093
1094 var cgo_libc_seteuid unsafe.Pointer
1095
1096 func Seteuid(euid int) (err error) {
1097 if cgo_libc_seteuid == nil {
1098 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1099 err = errnoErr(e1)
1100 }
1101 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1102 err = errnoErr(Errno(ret))
1103 }
1104 return
1105 }
1106
1107 var cgo_libc_setgid unsafe.Pointer
1108
1109 func Setgid(gid int) (err error) {
1110 if cgo_libc_setgid == nil {
1111 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1112 err = errnoErr(e1)
1113 }
1114 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1115 err = errnoErr(Errno(ret))
1116 }
1117 return
1118 }
1119
1120 var cgo_libc_setregid unsafe.Pointer
1121
1122 func Setregid(rgid, egid int) (err error) {
1123 if cgo_libc_setregid == nil {
1124 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1125 err = errnoErr(e1)
1126 }
1127 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1128 err = errnoErr(Errno(ret))
1129 }
1130 return
1131 }
1132
1133 var cgo_libc_setresgid unsafe.Pointer
1134
1135 func Setresgid(rgid, egid, sgid int) (err error) {
1136 if cgo_libc_setresgid == nil {
1137 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1138 err = errnoErr(e1)
1139 }
1140 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1141 err = errnoErr(Errno(ret))
1142 }
1143 return
1144 }
1145
1146 var cgo_libc_setresuid unsafe.Pointer
1147
1148 func Setresuid(ruid, euid, suid int) (err error) {
1149 if cgo_libc_setresuid == nil {
1150 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1151 err = errnoErr(e1)
1152 }
1153 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1154 err = errnoErr(Errno(ret))
1155 }
1156 return
1157 }
1158
1159 var cgo_libc_setreuid unsafe.Pointer
1160
1161 func Setreuid(ruid, euid int) (err error) {
1162 if cgo_libc_setreuid == nil {
1163 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1164 err = errnoErr(e1)
1165 }
1166 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1167 err = errnoErr(Errno(ret))
1168 }
1169 return
1170 }
1171
1172 var cgo_libc_setuid unsafe.Pointer
1173
1174 func Setuid(uid int) (err error) {
1175 if cgo_libc_setuid == nil {
1176 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1177 err = errnoErr(e1)
1178 }
1179 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1180 err = errnoErr(Errno(ret))
1181 }
1182 return
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 var mapper = &mmapper{
1205 active: make(map[*byte][]byte),
1206 mmap: mmap,
1207 munmap: munmap,
1208 }
1209
1210 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1211 return mapper.Mmap(fd, offset, length, prot, flags)
1212 }
1213
1214 func Munmap(b []byte) (err error) {
1215 return mapper.Munmap(b)
1216 }
1217
1218
1219
1220
1221
1222
1223
1224
View as plain text