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