~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/pkg/syscall/syscall_linux.go

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-04-20 17:36:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110420173648-ifergoxyrm832trd
Tags: upstream-2011.03.07.1
Import upstream version 2011.03.07.1

Show diffs side-by-side

added added

removed removed

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