Source file src/pkg/syscall/syscall_linux.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Linux system calls.
6 // This file is compiled as ordinary Go code,
7 // but it is also input to mksyscall,
8 // which parses the //sys lines and generates system call stubs.
9 // Note that sometimes we use a lowercase //sys name and
10 // wrap it in our own nicer implementation.
11
12 package syscall
13
14 import "unsafe"
15
16 /*
17 * Wrapped
18 */
19
20 //sys open(path string, mode int, perm uint32) (fd int, err error)
21 func Open(path string, mode int, perm uint32) (fd int, err error) {
22 return open(path, mode|O_LARGEFILE, perm)
23 }
24
25 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
26 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
27 return openat(dirfd, path, flags|O_LARGEFILE, mode)
28 }
29
30 //sysnb pipe(p *[2]_C_int) (err error)
31 func Pipe(p []int) (err error) {
32 if len(p) != 2 {
33 return EINVAL
34 }
35 var pp [2]_C_int
36 err = pipe(&pp)
37 p[0] = int(pp[0])
38 p[1] = int(pp[1])
39 return
40 }
41
42 //sys utimes(path string, times *[2]Timeval) (err error)
43 func Utimes(path string, tv []Timeval) (err error) {
44 if len(tv) != 2 {
45 return EINVAL
46 }
47 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
48 }
49
50 //sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
51 func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
52 if len(tv) != 2 {
53 return EINVAL
54 }
55 return futimesat(dirfd, StringBytePtr(path), (*[2]Timeval)(unsafe.Pointer(&tv[0])))
56 }
57
58 func Futimes(fd int, tv []Timeval) (err error) {
59 // Believe it or not, this is the best we can do on Linux
60 // (and is what glibc does).
61 return Utimes("/proc/self/fd/"+itoa(fd), tv)
62 }
63
64 const ImplementsGetwd = true
65
66 //sys Getcwd(buf []byte) (n int, err error)
67 func Getwd() (wd string, err error) {
68 var buf [PathMax]byte
69 n, err := Getcwd(buf[0:])
70 if err != nil {
71 return "", err
72 }
73 // Getcwd returns the number of bytes written to buf, including the NUL.
74 if n < 1 || n > len(buf) || buf[n-1] != 0 {
75 return "", EINVAL
76 }
77 return string(buf[0 : n-1]), nil
78 }
79
80 func Getgroups() (gids []int, err error) {
81 n, err := getgroups(0, nil)
82 if err != nil {
83 return nil, err
84 }
85 if n == 0 {
86 return nil, nil
87 }
88
89 // Sanity check group count. Max is 1<<16 on Linux.
90 if n < 0 || n > 1<<20 {
91 return nil, EINVAL
92 }
93
94 a := make([]_Gid_t, n)
95 n, err = getgroups(n, &a[0])
96 if err != nil {
97 return nil, err
98 }
99 gids = make([]int, n)
100 for i, v := range a[0:n] {
101 gids[i] = int(v)
102 }
103 return
104 }
105
106 func Setgroups(gids []int) (err error) {
107 if len(gids) == 0 {
108 return setgroups(0, nil)
109 }
110
111 a := make([]_Gid_t, len(gids))
112 for i, v := range gids {
113 a[i] = _Gid_t(v)
114 }
115 return setgroups(len(a), &a[0])
116 }
117
118 type WaitStatus uint32
119
120 // Wait status is 7 bits at bottom, either 0 (exited),
121 // 0x7F (stopped), or a signal number that caused an exit.
122 // The 0x80 bit is whether there was a core dump.
123 // An extra number (exit code, signal causing a stop)
124 // is in the high bits. At least that's the idea.
125 // There are various irregularities. For example, the
126 // "continued" status is 0xFFFF, distinguishing itself
127 // from stopped via the core dump bit.
128
129 const (
130 mask = 0x7F
131 core = 0x80
132 exited = 0x00
133 stopped = 0x7F
134 shift = 8
135 )
136
137 func (w WaitStatus) Exited() bool { return w&mask == exited }
138
139 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
140
141 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
142
143 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
144
145 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
146
147 func (w WaitStatus) ExitStatus() int {
148 if !w.Exited() {
149 return -1
150 }
151 return int(w>>shift) & 0xFF
152 }
153
154 func (w WaitStatus) Signal() Signal {
155 if !w.Signaled() {
156 return -1
157 }
158 return Signal(w & mask)
159 }
160
161 func (w WaitStatus) StopSignal() Signal {
162 if !w.Stopped() {
163 return -1
164 }
165 return Signal(w>>shift) & 0xFF
166 }
167
168 func (w WaitStatus) TrapCause() int {
169 if w.StopSignal() != SIGTRAP {
170 return -1
171 }
172 return int(w>>shift) >> 8
173 }
174
175 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
176 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
177 var status _C_int
178 wpid, err = wait4(pid, &status, options, rusage)
179 if wstatus != nil {
180 *wstatus = WaitStatus(status)
181 }
182 return
183 }
184
185 func Mkfifo(path string, mode uint32) (err error) {
186 return Mknod(path, mode|S_IFIFO, 0)
187 }
188
189 // For testing: clients can set this flag to force
190 // creation of IPv6 sockets to return EAFNOSUPPORT.
191 var SocketDisableIPv6 bool
192
193 type Sockaddr interface {
194 sockaddr() (ptr uintptr, len _Socklen, err error) // lowercase; only we can define Sockaddrs
195 }
196
197 type SockaddrInet4 struct {
198 Port int
199 Addr [4]byte
200 raw RawSockaddrInet4
201 }
202
203 func (sa *SockaddrInet4) sockaddr() (uintptr, _Socklen, error) {
204 if sa.Port < 0 || sa.Port > 0xFFFF {
205 return 0, 0, EINVAL
206 }
207 sa.raw.Family = AF_INET
208 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
209 p[0] = byte(sa.Port >> 8)
210 p[1] = byte(sa.Port)
211 for i := 0; i < len(sa.Addr); i++ {
212 sa.raw.Addr[i] = sa.Addr[i]
213 }
214 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, nil
215 }
216
217 type SockaddrInet6 struct {
218 Port int
219 ZoneId uint32
220 Addr [16]byte
221 raw RawSockaddrInet6
222 }
223
224 func (sa *SockaddrInet6) sockaddr() (uintptr, _Socklen, error) {
225 if sa.Port < 0 || sa.Port > 0xFFFF {
226 return 0, 0, EINVAL
227 }
228 sa.raw.Family = AF_INET6
229 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
230 p[0] = byte(sa.Port >> 8)
231 p[1] = byte(sa.Port)
232 sa.raw.Scope_id = sa.ZoneId
233 for i := 0; i < len(sa.Addr); i++ {
234 sa.raw.Addr[i] = sa.Addr[i]
235 }
236 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, nil
237 }
238
239 type SockaddrUnix struct {
240 Name string
241 raw RawSockaddrUnix
242 }
243
244 func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, error) {
245 name := sa.Name
246 n := len(name)
247 if n >= len(sa.raw.Path) || n == 0 {
248 return 0, 0, EINVAL
249 }
250 sa.raw.Family = AF_UNIX
251 for i := 0; i < n; i++ {
252 sa.raw.Path[i] = int8(name[i])
253 }
254 // length is family (uint16), name, NUL.
255 sl := 2 + _Socklen(n) + 1
256 if sa.raw.Path[0] == '@' {
257 sa.raw.Path[0] = 0
258 // Don't count trailing NUL for abstract address.
259 sl--
260 }
261
262 return uintptr(unsafe.Pointer(&sa.raw)), sl, nil
263 }
264
265 type SockaddrLinklayer struct {
266 Protocol uint16
267 Ifindex int
268 Hatype uint16
269 Pkttype uint8
270 Halen uint8
271 Addr [8]byte
272 raw RawSockaddrLinklayer
273 }
274
275 func (sa *SockaddrLinklayer) sockaddr() (uintptr, _Socklen, error) {
276 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
277 return 0, 0, EINVAL
278 }
279 sa.raw.Family = AF_PACKET
280 sa.raw.Protocol = sa.Protocol
281 sa.raw.Ifindex = int32(sa.Ifindex)
282 sa.raw.Hatype = sa.Hatype
283 sa.raw.Pkttype = sa.Pkttype
284 sa.raw.Halen = sa.Halen
285 for i := 0; i < len(sa.Addr); i++ {
286 sa.raw.Addr[i] = sa.Addr[i]
287 }
288 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrLinklayer, nil
289 }
290
291 type SockaddrNetlink struct {
292 Family uint16
293 Pad uint16
294 Pid uint32
295 Groups uint32
296 raw RawSockaddrNetlink
297 }
298
299 func (sa *SockaddrNetlink) sockaddr() (uintptr, _Socklen, error) {
300 sa.raw.Family = AF_NETLINK
301 sa.raw.Pad = sa.Pad
302 sa.raw.Pid = sa.Pid
303 sa.raw.Groups = sa.Groups
304 return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrNetlink, nil
305 }
306
307 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
308 switch rsa.Addr.Family {
309 case AF_NETLINK:
310 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
311 sa := new(SockaddrNetlink)
312 sa.Family = pp.Family
313 sa.Pad = pp.Pad
314 sa.Pid = pp.Pid
315 sa.Groups = pp.Groups
316 return sa, nil
317
318 case AF_PACKET:
319 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
320 sa := new(SockaddrLinklayer)
321 sa.Protocol = pp.Protocol
322 sa.Ifindex = int(pp.Ifindex)
323 sa.Hatype = pp.Hatype
324 sa.Pkttype = pp.Pkttype
325 sa.Halen = pp.Halen
326 for i := 0; i < len(sa.Addr); i++ {
327 sa.Addr[i] = pp.Addr[i]
328 }
329 return sa, nil
330
331 case AF_UNIX:
332 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
333 sa := new(SockaddrUnix)
334 if pp.Path[0] == 0 {
335 // "Abstract" Unix domain socket.
336 // Rewrite leading NUL as @ for textual display.
337 // (This is the standard convention.)
338 // Not friendly to overwrite in place,
339 // but the callers below don't care.
340 pp.Path[0] = '@'
341 }
342
343 // Assume path ends at NUL.
344 // This is not technically the Linux semantics for
345 // abstract Unix domain sockets--they are supposed
346 // to be uninterpreted fixed-size binary blobs--but
347 // everyone uses this convention.
348 n := 0
349 for n < len(pp.Path) && pp.Path[n] != 0 {
350 n++
351 }
352 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
353 sa.Name = string(bytes)
354 return sa, nil
355
356 case AF_INET:
357 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
358 sa := new(SockaddrInet4)
359 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
360 sa.Port = int(p[0])<<8 + int(p[1])
361 for i := 0; i < len(sa.Addr); i++ {
362 sa.Addr[i] = pp.Addr[i]
363 }
364 return sa, nil
365
366 case AF_INET6:
367 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
368 sa := new(SockaddrInet6)
369 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
370 sa.Port = int(p[0])<<8 + int(p[1])
371 sa.ZoneId = pp.Scope_id
372 for i := 0; i < len(sa.Addr); i++ {
373 sa.Addr[i] = pp.Addr[i]
374 }
375 return sa, nil
376 }
377 return nil, EAFNOSUPPORT
378 }
379
380 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
381 var rsa RawSockaddrAny
382 var len _Socklen = SizeofSockaddrAny
383 nfd, err = accept(fd, &rsa, &len)
384 if err != nil {
385 return
386 }
387 sa, err = anyToSockaddr(&rsa)
388 if err != nil {
389 Close(nfd)
390 nfd = 0
391 }
392 return
393 }
394
395 func Getsockname(fd int) (sa Sockaddr, err error) {
396 var rsa RawSockaddrAny
397 var len _Socklen = SizeofSockaddrAny
398 if err = getsockname(fd, &rsa, &len); err != nil {
399 return
400 }
401 return anyToSockaddr(&rsa)
402 }
403
404 func Getpeername(fd int) (sa Sockaddr, err error) {
405 var rsa RawSockaddrAny
406 var len _Socklen = SizeofSockaddrAny
407 if err = getpeername(fd, &rsa, &len); err != nil {
408 return
409 }
410 return anyToSockaddr(&rsa)
411 }
412
413 func Bind(fd int, sa Sockaddr) (err error) {
414 ptr, n, err := sa.sockaddr()
415 if err != nil {
416 return err
417 }
418 return bind(fd, ptr, n)
419 }
420
421 func Connect(fd int, sa Sockaddr) (err error) {
422 ptr, n, err := sa.sockaddr()
423 if err != nil {
424 return err
425 }
426 return connect(fd, ptr, n)
427 }
428
429 func Socket(domain, typ, proto int) (fd int, err error) {
430 if domain == AF_INET6 && SocketDisableIPv6 {
431 return -1, EAFNOSUPPORT
432 }
433 fd, err = socket(domain, typ, proto)
434 return
435 }
436
437 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
438 err = socketpair(domain, typ, proto, &fd)
439 return
440 }
441
442 func GetsockoptInt(fd, level, opt int) (value int, err error) {
443 var n int32
444 vallen := _Socklen(4)
445 err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), &vallen)
446 return int(n), err
447 }
448
449 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
450 vallen := _Socklen(4)
451 err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), &vallen)
452 return value, err
453 }
454
455 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
456 var value IPMreq
457 vallen := _Socklen(SizeofIPMreq)
458 err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
459 return &value, err
460 }
461
462 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
463 var value IPMreqn
464 vallen := _Socklen(SizeofIPMreqn)
465 err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
466 return &value, err
467 }
468
469 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
470 var value IPv6Mreq
471 vallen := _Socklen(SizeofIPv6Mreq)
472 err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
473 return &value, err
474 }
475
476 func SetsockoptInt(fd, level, opt int, value int) (err error) {
477 var n = int32(value)
478 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4)
479 }
480
481 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
482 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), 4)
483 }
484
485 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
486 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), unsafe.Sizeof(*tv))
487 }
488
489 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
490 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), unsafe.Sizeof(*l))
491 }
492
493 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
494 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
495 }
496
497 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
498 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
499 }
500
501 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
502 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
503 }
504
505 func SetsockoptString(fd, level, opt int, s string) (err error) {
506 return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&[]byte(s)[0])), uintptr(len(s)))
507 }
508
509 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
510 var rsa RawSockaddrAny
511 var len _Socklen = SizeofSockaddrAny
512 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
513 return
514 }
515 from, err = anyToSockaddr(&rsa)
516 return
517 }
518
519 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
520 ptr, n, err := to.sockaddr()
521 if err != nil {
522 return err
523 }
524 return sendto(fd, p, flags, ptr, n)
525 }
526
527 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
528 var msg Msghdr
529 var rsa RawSockaddrAny
530 msg.Name = (*byte)(unsafe.Pointer(&rsa))
531 msg.Namelen = uint32(SizeofSockaddrAny)
532 var iov Iovec
533 if len(p) > 0 {
534 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
535 iov.SetLen(len(p))
536 }
537 var dummy byte
538 if len(oob) > 0 {
539 // receive at least one normal byte
540 if len(p) == 0 {
541 iov.Base = &dummy
542 iov.SetLen(1)
543 }
544 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
545 msg.SetControllen(len(oob))
546 }
547 msg.Iov = &iov
548 msg.Iovlen = 1
549 if n, err = recvmsg(fd, &msg, flags); err != nil {
550 return
551 }
552 oobn = int(msg.Controllen)
553 recvflags = int(msg.Flags)
554 // source address is only specified if the socket is unconnected
555 if rsa.Addr.Family != AF_UNSPEC {
556 from, err = anyToSockaddr(&rsa)
557 }
558 return
559 }
560
561 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
562 var ptr uintptr
563 var salen _Socklen
564 if to != nil {
565 var err error
566 ptr, salen, err = to.sockaddr()
567 if err != nil {
568 return err
569 }
570 }
571 var msg Msghdr
572 msg.Name = (*byte)(unsafe.Pointer(ptr))
573 msg.Namelen = uint32(salen)
574 var iov Iovec
575 if len(p) > 0 {
576 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
577 iov.SetLen(len(p))
578 }
579 var dummy byte
580 if len(oob) > 0 {
581 // send at least one normal byte
582 if len(p) == 0 {
583 iov.Base = &dummy
584 iov.SetLen(1)
585 }
586 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
587 msg.SetControllen(len(oob))
588 }
589 msg.Iov = &iov
590 msg.Iovlen = 1
591 if err = sendmsg(fd, &msg, flags); err != nil {
592 return
593 }
594 return
595 }
596
597 // BindToDevice binds the socket associated with fd to device.
598 func BindToDevice(fd int, device string) (err error) {
599 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
600 }
601
602 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
603
604 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
605 // The peek requests are machine-size oriented, so we wrap it
606 // to retrieve arbitrary-length data.
607
608 // The ptrace syscall differs from glibc's ptrace.
609 // Peeks returns the word in *data, not as the return value.
610
611 var buf [sizeofPtr]byte
612
613 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
614 // access (PEEKUSER warns that it might), but if we don't
615 // align our reads, we might straddle an unmapped page
616 // boundary and not get the bytes leading up to the page
617 // boundary.
618 n := 0
619 if addr%sizeofPtr != 0 {
620 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
621 if err != nil {
622 return 0, err
623 }
624 n += copy(out, buf[addr%sizeofPtr:])
625 out = out[n:]
626 }
627
628 // Remainder.
629 for len(out) > 0 {
630 // We use an internal buffer to guarantee alignment.
631 // It's not documented if this is necessary, but we're paranoid.
632 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
633 if err != nil {
634 return n, err
635 }
636 copied := copy(out, buf[0:])
637 n += copied
638 out = out[copied:]
639 }
640
641 return n, nil
642 }
643
644 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
645 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
646 }
647
648 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
649 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
650 }
651
652 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
653 // As for ptracePeek, we need to align our accesses to deal
654 // with the possibility of straddling an invalid page.
655
656 // Leading edge.
657 n := 0
658 if addr%sizeofPtr != 0 {
659 var buf [sizeofPtr]byte
660 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
661 if err != nil {
662 return 0, err
663 }
664 n += copy(buf[addr%sizeofPtr:], data)
665 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
666 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
667 if err != nil {
668 return 0, err
669 }
670 data = data[n:]
671 }
672
673 // Interior.
674 for len(data) > sizeofPtr {
675 word := *((*uintptr)(unsafe.Pointer(&data[0])))
676 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
677 if err != nil {
678 return n, err
679 }
680 n += sizeofPtr
681 data = data[sizeofPtr:]
682 }
683
684 // Trailing edge.
685 if len(data) > 0 {
686 var buf [sizeofPtr]byte
687 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
688 if err != nil {
689 return n, err
690 }
691 copy(buf[0:], data)
692 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
693 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
694 if err != nil {
695 return n, err
696 }
697 n += len(data)
698 }
699
700 return n, nil
701 }
702
703 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
704 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
705 }
706
707 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
708 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
709 }
710
711 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
712 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
713 }
714
715 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
716 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
717 }
718
719 func PtraceSetOptions(pid int, options int) (err error) {
720 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
721 }
722
723 func PtraceGetEventMsg(pid int) (msg uint, err error) {
724 var data _C_long
725 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
726 msg = uint(data)
727 return
728 }
729
730 func PtraceCont(pid int, signal int) (err error) {
731 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
732 }
733
734 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
735
736 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
737
738 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
739
740 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
741 func Reboot(cmd int) (err error) {
742 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
743 }
744
745 func clen(n []byte) int {
746 for i := 0; i < len(n); i++ {
747 if n[i] == 0 {
748 return i
749 }
750 }
751 return len(n)
752 }
753
754 func ReadDirent(fd int, buf []byte) (n int, err error) {
755 return Getdents(fd, buf)
756 }
757
758 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
759 origlen := len(buf)
760 count = 0
761 for max != 0 && len(buf) > 0 {
762 dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
763 buf = buf[dirent.Reclen:]
764 if dirent.Ino == 0 { // File absent in directory.
765 continue
766 }
767 bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
768 var name = string(bytes[0:clen(bytes[:])])
769 if name == "." || name == ".." { // Useless names
770 continue
771 }
772 max--
773 count++
774 names = append(names, name)
775 }
776 return origlen - len(buf), count, names
777 }
778
779 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
780 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
781 // Certain file systems get rather angry and EINVAL if you give
782 // them an empty string of data, rather than NULL.
783 if data == "" {
784 return mount(source, target, fstype, flags, nil)
785 }
786 return mount(source, target, fstype, flags, StringBytePtr(data))
787 }
788
789 // Sendto
790 // Recvfrom
791 // Socketpair
792
793 /*
794 * Direct access
795 */
796 //sys Access(path string, mode uint32) (err error)
797 //sys Acct(path string) (err error)
798 //sys Adjtimex(buf *Timex) (state int, err error)
799 //sys Chdir(path string) (err error)
800 //sys Chmod(path string, mode uint32) (err error)
801 //sys Chroot(path string) (err error)
802 //sys Close(fd int) (err error)
803 //sys Creat(path string, mode uint32) (fd int, err error)
804 //sysnb Dup(oldfd int) (fd int, err error)
805 //sysnb Dup2(oldfd int, newfd int) (err error)
806 //sysnb EpollCreate(size int) (fd int, err error)
807 //sysnb EpollCreate1(flag int) (fd int, err error)
808 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
809 //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
810 //sys Exit(code int) = SYS_EXIT_GROUP
811 //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
812 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
813 //sys Fchdir(fd int) (err error)
814 //sys Fchmod(fd int, mode uint32) (err error)
815 //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
816 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
817 //sys fcntl(fd int, cmd int, arg int) (val int, err error)
818 //sys Fdatasync(fd int) (err error)
819 //sys Flock(fd int, how int) (err error)
820 //sys Fsync(fd int) (err error)
821 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
822 //sysnb Getpgid(pid int) (pgid int, err error)
823 //sysnb Getpgrp() (pid int)
824 //sysnb Getpid() (pid int)
825 //sysnb Getppid() (ppid int)
826 //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
827 //sysnb Getrusage(who int, rusage *Rusage) (err error)
828 //sysnb Gettid() (tid int)
829 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
830 //sysnb InotifyInit() (fd int, err error)
831 //sysnb InotifyInit1(flags int) (fd int, err error)
832 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
833 //sysnb Kill(pid int, sig Signal) (err error)
834 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
835 //sys Link(oldpath string, newpath string) (err error)
836 //sys Mkdir(path string, mode uint32) (err error)
837 //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
838 //sys Mknod(path string, mode uint32, dev int) (err error)
839 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
840 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
841 //sys Pause() (err error)
842 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
843 //sys Read(fd int, p []byte) (n int, err error)
844 //sys Readlink(path string, buf []byte) (n int, err error)
845 //sys Rename(oldpath string, newpath string) (err error)
846 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
847 //sys Rmdir(path string) (err error)
848 //sys Setdomainname(p []byte) (err error)
849 //sys Sethostname(p []byte) (err error)
850 //sysnb Setpgid(pid int, pgid int) (err error)
851 //sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
852 //sysnb Setsid() (pid int, err error)
853 //sysnb Settimeofday(tv *Timeval) (err error)
854 //sysnb Setuid(uid int) (err error)
855 //sys Symlink(oldpath string, newpath string) (err error)
856 //sys Sync()
857 //sysnb Sysinfo(info *Sysinfo_t) (err error)
858 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
859 //sysnb Tgkill(tgid int, tid int, sig Signal) (err error)
860 //sysnb Times(tms *Tms) (ticks uintptr, err error)
861 //sysnb Umask(mask int) (oldmask int)
862 //sysnb Uname(buf *Utsname) (err error)
863 //sys Unlink(path string) (err error)
864 //sys Unlinkat(dirfd int, path string) (err error)
865 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
866 //sys Unshare(flags int) (err error)
867 //sys Ustat(dev int, ubuf *Ustat_t) (err error)
868 //sys Utime(path string, buf *Utimbuf) (err error)
869 //sys Write(fd int, p []byte) (n int, err error)
870 //sys exitThread(code int) (err error) = SYS_EXIT
871 //sys read(fd int, p *byte, np int) (n int, err error)
872 //sys write(fd int, p *byte, np int) (n int, err error)
873
874 // mmap varies by architecture; see syscall_linux_*.go.
875 //sys munmap(addr uintptr, length uintptr) (err error)
876
877 var mapper = &mmapper{
878 active: make(map[*byte][]byte),
879 mmap: mmap,
880 munmap: munmap,
881 }
882
883 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
884 return mapper.Mmap(fd, offset, length, prot, flags)
885 }
886
887 func Munmap(b []byte) (err error) {
888 return mapper.Munmap(b)
889 }
890
891 //sys Madvise(b []byte, advice int) (err error)
892 //sys Mprotect(b []byte, prot int) (err error)
893 //sys Mlock(b []byte) (err error)
894 //sys Munlock(b []byte) (err error)
895 //sys Mlockall(flags int) (err error)
896 //sys Munlockall() (err error)
897
898 /*
899 * Unimplemented
900 */
901 // AddKey
902 // AfsSyscall
903 // Alarm
904 // ArchPrctl
905 // Brk
906 // Capget
907 // Capset
908 // ClockGetres
909 // ClockGettime
910 // ClockNanosleep
911 // ClockSettime
912 // Clone
913 // CreateModule
914 // DeleteModule
915 // EpollCtlOld
916 // EpollPwait
917 // EpollWaitOld
918 // Eventfd
919 // Execve
920 // Fadvise64
921 // Fgetxattr
922 // Flistxattr
923 // Fork
924 // Fremovexattr
925 // Fsetxattr
926 // Futex
927 // GetKernelSyms
928 // GetMempolicy
929 // GetRobustList
930 // GetThreadArea
931 // Getitimer
932 // Getpmsg
933 // Getpriority
934 // Getxattr
935 // IoCancel
936 // IoDestroy
937 // IoGetevents
938 // IoSetup
939 // IoSubmit
940 // Ioctl
941 // IoprioGet
942 // IoprioSet
943 // KexecLoad
944 // Keyctl
945 // Lgetxattr
946 // Listxattr
947 // Llistxattr
948 // LookupDcookie
949 // Lremovexattr
950 // Lsetxattr
951 // Mbind
952 // MigratePages
953 // Mincore
954 // ModifyLdt
955 // Mount
956 // MovePages
957 // Mprotect
958 // MqGetsetattr
959 // MqNotify
960 // MqOpen
961 // MqTimedreceive
962 // MqTimedsend
963 // MqUnlink
964 // Mremap
965 // Msgctl
966 // Msgget
967 // Msgrcv
968 // Msgsnd
969 // Msync
970 // Newfstatat
971 // Nfsservctl
972 // Personality
973 // Poll
974 // Ppoll
975 // Prctl
976 // Pselect6
977 // Ptrace
978 // Putpmsg
979 // QueryModule
980 // Quotactl
981 // Readahead
982 // Readv
983 // RemapFilePages
984 // Removexattr
985 // RequestKey
986 // RestartSyscall
987 // RtSigaction
988 // RtSigpending
989 // RtSigprocmask
990 // RtSigqueueinfo
991 // RtSigreturn
992 // RtSigsuspend
993 // RtSigtimedwait
994 // SchedGetPriorityMax
995 // SchedGetPriorityMin
996 // SchedGetaffinity
997 // SchedGetparam
998 // SchedGetscheduler
999 // SchedRrGetInterval
1000 // SchedSetaffinity
1001 // SchedSetparam
1002 // SchedYield
1003 // Security
1004 // Semctl
1005 // Semget
1006 // Semop
1007 // Semtimedop
1008 // SetMempolicy
1009 // SetRobustList
1010 // SetThreadArea
1011 // SetTidAddress
1012 // Setpriority
1013 // Setxattr
1014 // Shmat
1015 // Shmctl
1016 // Shmdt
1017 // Shmget
1018 // Sigaltstack
1019 // Signalfd
1020 // Swapoff
1021 // Swapon
1022 // Sysfs
1023 // TimerCreate
1024 // TimerDelete
1025 // TimerGetoverrun
1026 // TimerGettime
1027 // TimerSettime
1028 // Timerfd
1029 // Tkill (obsolete)
1030 // Tuxcall
1031 // Umount2
1032 // Uselib
1033 // Utimensat
1034 // Vfork
1035 // Vhangup
1036 // Vmsplice
1037 // Vserver
1038 // Waitid
1039 // Writev
1040 // _Sysctl