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