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 "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 Accept(fd int) (nfd int, sa Sockaddr, err error) {
634 var rsa RawSockaddrAny
635 var len _Socklen = SizeofSockaddrAny
636 nfd, err = accept4(fd, &rsa, &len, 0)
637 if err != nil {
638 return
639 }
640 sa, err = anyToSockaddr(&rsa)
641 if err != nil {
642 Close(nfd)
643 nfd = 0
644 }
645 return
646 }
647
648 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
649 var rsa RawSockaddrAny
650 var len _Socklen = SizeofSockaddrAny
651 nfd, err = accept4(fd, &rsa, &len, flags)
652 if err != nil {
653 return
654 }
655 if len > SizeofSockaddrAny {
656 panic("RawSockaddrAny too small")
657 }
658 sa, err = anyToSockaddr(&rsa)
659 if err != nil {
660 Close(nfd)
661 nfd = 0
662 }
663 return
664 }
665
666 func Getsockname(fd int) (sa Sockaddr, err error) {
667 var rsa RawSockaddrAny
668 var len _Socklen = SizeofSockaddrAny
669 if err = getsockname(fd, &rsa, &len); err != nil {
670 return
671 }
672 return anyToSockaddr(&rsa)
673 }
674
675 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
676 vallen := _Socklen(4)
677 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
678 return value, err
679 }
680
681 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
682 var value IPMreq
683 vallen := _Socklen(SizeofIPMreq)
684 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
685 return &value, err
686 }
687
688 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
689 var value IPMreqn
690 vallen := _Socklen(SizeofIPMreqn)
691 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
692 return &value, err
693 }
694
695 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
696 var value IPv6Mreq
697 vallen := _Socklen(SizeofIPv6Mreq)
698 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
699 return &value, err
700 }
701
702 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
703 var value IPv6MTUInfo
704 vallen := _Socklen(SizeofIPv6MTUInfo)
705 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
706 return &value, err
707 }
708
709 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
710 var value ICMPv6Filter
711 vallen := _Socklen(SizeofICMPv6Filter)
712 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
713 return &value, err
714 }
715
716 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
717 var value Ucred
718 vallen := _Socklen(SizeofUcred)
719 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
720 return &value, err
721 }
722
723 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
724 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
725 }
726
727 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
728 var msg Msghdr
729 msg.Name = (*byte)(unsafe.Pointer(rsa))
730 msg.Namelen = uint32(SizeofSockaddrAny)
731 var iov Iovec
732 if len(p) > 0 {
733 iov.Base = &p[0]
734 iov.SetLen(len(p))
735 }
736 var dummy byte
737 if len(oob) > 0 {
738 if len(p) == 0 {
739 var sockType int
740 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
741 if err != nil {
742 return
743 }
744
745 if sockType != SOCK_DGRAM {
746 iov.Base = &dummy
747 iov.SetLen(1)
748 }
749 }
750 msg.Control = &oob[0]
751 msg.SetControllen(len(oob))
752 }
753 msg.Iov = &iov
754 msg.Iovlen = 1
755 if n, err = recvmsg(fd, &msg, flags); err != nil {
756 return
757 }
758 oobn = int(msg.Controllen)
759 recvflags = int(msg.Flags)
760 return
761 }
762
763 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
764 var msg Msghdr
765 msg.Name = (*byte)(ptr)
766 msg.Namelen = uint32(salen)
767 var iov Iovec
768 if len(p) > 0 {
769 iov.Base = &p[0]
770 iov.SetLen(len(p))
771 }
772 var dummy byte
773 if len(oob) > 0 {
774 if len(p) == 0 {
775 var sockType int
776 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
777 if err != nil {
778 return 0, err
779 }
780
781 if sockType != SOCK_DGRAM {
782 iov.Base = &dummy
783 iov.SetLen(1)
784 }
785 }
786 msg.Control = &oob[0]
787 msg.SetControllen(len(oob))
788 }
789 msg.Iov = &iov
790 msg.Iovlen = 1
791 if n, err = sendmsg(fd, &msg, flags); err != nil {
792 return 0, err
793 }
794 if len(oob) > 0 && len(p) == 0 {
795 n = 0
796 }
797 return n, nil
798 }
799
800
801 func BindToDevice(fd int, device string) (err error) {
802 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
803 }
804
805
806
807 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
808
809
810
811
812
813
814 var buf [sizeofPtr]byte
815
816
817
818
819
820
821 n := 0
822 if addr%sizeofPtr != 0 {
823 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
824 if err != nil {
825 return 0, err
826 }
827 n += copy(out, buf[addr%sizeofPtr:])
828 out = out[n:]
829 }
830
831
832 for len(out) > 0 {
833
834
835 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
836 if err != nil {
837 return n, err
838 }
839 copied := copy(out, buf[0:])
840 n += copied
841 out = out[copied:]
842 }
843
844 return n, nil
845 }
846
847 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
848 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
849 }
850
851 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
852 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
853 }
854
855 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
856
857
858
859
860 n := 0
861 if addr%sizeofPtr != 0 {
862 var buf [sizeofPtr]byte
863 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
864 if err != nil {
865 return 0, err
866 }
867 n += copy(buf[addr%sizeofPtr:], data)
868 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
869 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
870 if err != nil {
871 return 0, err
872 }
873 data = data[n:]
874 }
875
876
877 for len(data) > sizeofPtr {
878 word := *((*uintptr)(unsafe.Pointer(&data[0])))
879 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
880 if err != nil {
881 return n, err
882 }
883 n += sizeofPtr
884 data = data[sizeofPtr:]
885 }
886
887
888 if len(data) > 0 {
889 var buf [sizeofPtr]byte
890 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
891 if err != nil {
892 return n, err
893 }
894 copy(buf[0:], data)
895 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
896 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
897 if err != nil {
898 return n, err
899 }
900 n += len(data)
901 }
902
903 return n, nil
904 }
905
906 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
907 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
908 }
909
910 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
911 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
912 }
913
914 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
915 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
916 }
917
918 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
919 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
920 }
921
922 func PtraceSetOptions(pid int, options int) (err error) {
923 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
924 }
925
926 func PtraceGetEventMsg(pid int) (msg uint, err error) {
927 var data _C_long
928 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
929 msg = uint(data)
930 return
931 }
932
933 func PtraceCont(pid int, signal int) (err error) {
934 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
935 }
936
937 func PtraceSyscall(pid int, signal int) (err error) {
938 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
939 }
940
941 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
942
943 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
944
945 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
946
947
948
949 func Reboot(cmd int) (err error) {
950 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
951 }
952
953 func ReadDirent(fd int, buf []byte) (n int, err error) {
954 return Getdents(fd, buf)
955 }
956
957 func direntIno(buf []byte) (uint64, bool) {
958 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
959 }
960
961 func direntReclen(buf []byte) (uint64, bool) {
962 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
963 }
964
965 func direntNamlen(buf []byte) (uint64, bool) {
966 reclen, ok := direntReclen(buf)
967 if !ok {
968 return 0, false
969 }
970 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
971 }
972
973
974
975 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
976
977
978 if data == "" {
979 return mount(source, target, fstype, flags, nil)
980 }
981 datap, err := BytePtrFromString(data)
982 if err != nil {
983 return err
984 }
985 return mount(source, target, fstype, flags, datap)
986 }
987
988
989
990
991
992
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 func Getpgrp() (pid int) {
1016 pid, _ = Getpgid(0)
1017 return
1018 }
1019
1020
1021
1022
1023
1024
1025
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 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1070 if cgo_libc_setegid != nil {
1071 return minus1, minus1, ENOTSUP
1072 }
1073 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1074 return r1, r2, Errno(errno)
1075 }
1076
1077
1078
1079
1080
1081 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1082 if cgo_libc_setegid != nil {
1083 return minus1, minus1, ENOTSUP
1084 }
1085 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1086 return r1, r2, Errno(errno)
1087 }
1088
1089
1090
1091
1092 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1093
1094 var cgo_libc_setegid unsafe.Pointer
1095
1096 const minus1 = ^uintptr(0)
1097
1098 func Setegid(egid int) (err error) {
1099 if cgo_libc_setegid == nil {
1100 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1101 err = errnoErr(e1)
1102 }
1103 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1104 err = errnoErr(Errno(ret))
1105 }
1106 return
1107 }
1108
1109 var cgo_libc_seteuid unsafe.Pointer
1110
1111 func Seteuid(euid int) (err error) {
1112 if cgo_libc_seteuid == nil {
1113 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1114 err = errnoErr(e1)
1115 }
1116 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1117 err = errnoErr(Errno(ret))
1118 }
1119 return
1120 }
1121
1122 var cgo_libc_setgid unsafe.Pointer
1123
1124 func Setgid(gid int) (err error) {
1125 if cgo_libc_setgid == nil {
1126 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1127 err = errnoErr(e1)
1128 }
1129 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1130 err = errnoErr(Errno(ret))
1131 }
1132 return
1133 }
1134
1135 var cgo_libc_setregid unsafe.Pointer
1136
1137 func Setregid(rgid, egid int) (err error) {
1138 if cgo_libc_setregid == nil {
1139 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1140 err = errnoErr(e1)
1141 }
1142 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1143 err = errnoErr(Errno(ret))
1144 }
1145 return
1146 }
1147
1148 var cgo_libc_setresgid unsafe.Pointer
1149
1150 func Setresgid(rgid, egid, sgid int) (err error) {
1151 if cgo_libc_setresgid == nil {
1152 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1153 err = errnoErr(e1)
1154 }
1155 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1156 err = errnoErr(Errno(ret))
1157 }
1158 return
1159 }
1160
1161 var cgo_libc_setresuid unsafe.Pointer
1162
1163 func Setresuid(ruid, euid, suid int) (err error) {
1164 if cgo_libc_setresuid == nil {
1165 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1166 err = errnoErr(e1)
1167 }
1168 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1169 err = errnoErr(Errno(ret))
1170 }
1171 return
1172 }
1173
1174 var cgo_libc_setreuid unsafe.Pointer
1175
1176 func Setreuid(ruid, euid int) (err error) {
1177 if cgo_libc_setreuid == nil {
1178 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1179 err = errnoErr(e1)
1180 }
1181 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1182 err = errnoErr(Errno(ret))
1183 }
1184 return
1185 }
1186
1187 var cgo_libc_setuid unsafe.Pointer
1188
1189 func Setuid(uid int) (err error) {
1190 if cgo_libc_setuid == nil {
1191 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1192 err = errnoErr(e1)
1193 }
1194 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1195 err = errnoErr(Errno(ret))
1196 }
1197 return
1198 }
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219 var mapper = &mmapper{
1220 active: make(map[*byte][]byte),
1221 mmap: mmap,
1222 munmap: munmap,
1223 }
1224
1225 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1226 return mapper.Mmap(fd, offset, length, prot, flags)
1227 }
1228
1229 func Munmap(b []byte) (err error) {
1230 return mapper.Munmap(b)
1231 }
1232
1233
1234
1235
1236
1237
1238
1239
View as plain text