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.
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.
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)
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)
32
//sys pipe(p *[2]_C_int) (errno int)
33
func Pipe(p []int) (errno int) {
44
//sys utimes(path string, times *[2]Timeval) (errno int)
45
func Utimes(path string, tv []Timeval) (errno int) {
49
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
52
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (errno int)
53
func Futimesat(dirfd int, path string, tv []Timeval) (errno int) {
57
return futimesat(dirfd, StringBytePtr(path), (*[2]Timeval)(unsafe.Pointer(&tv[0])))
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)
66
const ImplementsGetwd = true
68
//sys Getcwd(buf []byte) (n int, errno int)
69
func Getwd() (wd string, errno int) {
71
n, err := Getcwd(buf[0:])
75
// Getcwd returns the number of bytes written to buf, including the NUL.
76
if n < 1 || n > len(buf) || buf[n-1] != 0 {
79
return string(buf[0 : n-1]), 0
82
func Getgroups() (gids []int, errno int) {
83
n, err := getgroups(0, nil)
91
// Sanity check group count. Max is 1<<16 on Linux.
92
if n < 0 || n > 1<<20 {
96
a := make([]_Gid_t, n)
97
n, err = getgroups(n, &a[0])
101
gids = make([]int, n)
102
for i, v := range a[0:n] {
108
func Setgroups(gids []int) (errno int) {
110
return setgroups(0, nil)
113
a := make([]_Gid_t, len(gids))
114
for i, v := range gids {
117
return setgroups(len(a), &a[0])
120
type WaitStatus uint32
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.
139
func (w WaitStatus) Exited() bool { return w&mask == exited }
141
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
143
func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
145
func (w WaitStatus) Continued() bool { return w == 0xFFFF }
147
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
149
func (w WaitStatus) ExitStatus() int {
153
return int(w>>shift) & 0xFF
156
func (w WaitStatus) Signal() int {
163
func (w WaitStatus) StopSignal() int {
167
return int(w>>shift) & 0xFF
170
func (w WaitStatus) TrapCause() int {
171
if w.StopSignal() != SIGTRAP {
174
return int(w>>shift) >> 8
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) {
180
wpid, errno = wait4(pid, &status, options, rusage)
182
*wstatus = WaitStatus(status)
187
func Sleep(nsec int64) (errno int) {
188
tv := NsecToTimeval(nsec)
189
_, err := Select(0, nil, nil, nil, &tv)
193
// For testing: clients can set this flag to force
194
// creation of IPv6 sockets to return EAFNOSUPPORT.
195
var SocketDisableIPv6 bool
197
type Sockaddr interface {
198
sockaddr() (ptr uintptr, len _Socklen, errno int) // lowercase; only we can define Sockaddrs
201
type SockaddrInet4 struct {
207
func (sa *SockaddrInet4) sockaddr() (uintptr, _Socklen, int) {
208
if sa.Port < 0 || sa.Port > 0xFFFF {
211
sa.raw.Family = AF_INET
212
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
213
p[0] = byte(sa.Port >> 8)
215
for i := 0; i < len(sa.Addr); i++ {
216
sa.raw.Addr[i] = sa.Addr[i]
218
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, 0
221
type SockaddrInet6 struct {
227
func (sa *SockaddrInet6) sockaddr() (uintptr, _Socklen, int) {
228
if sa.Port < 0 || sa.Port > 0xFFFF {
231
sa.raw.Family = AF_INET6
232
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
233
p[0] = byte(sa.Port >> 8)
235
for i := 0; i < len(sa.Addr); i++ {
236
sa.raw.Addr[i] = sa.Addr[i]
238
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, 0
241
type SockaddrUnix struct {
246
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
249
if n >= len(sa.raw.Path) || n == 0 {
252
sa.raw.Family = AF_UNIX
253
for i := 0; i < n; i++ {
254
sa.raw.Path[i] = int8(name[i])
256
// length is family (uint16), name, NUL.
257
sl := 2 + _Socklen(n) + 1
258
if sa.raw.Path[0] == '@' {
260
// Don't count trailing NUL for abstract address.
264
return uintptr(unsafe.Pointer(&sa.raw)), sl, 0
267
type SockaddrLinklayer struct {
274
raw RawSockaddrLinklayer
277
func (sa *SockaddrLinklayer) sockaddr() (uintptr, _Socklen, int) {
278
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
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]
290
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrLinklayer, 0
293
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
294
switch rsa.Addr.Family {
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
303
for i := 0; i < len(sa.Addr); i++ {
304
sa.Addr[i] = pp.Addr[i]
309
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
310
sa := new(SockaddrUnix)
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.
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.
326
for n < len(pp.Path) && pp.Path[n] != 0 {
329
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
330
sa.Name = string(bytes)
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]
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]
353
return nil, EAFNOSUPPORT
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)
363
sa, errno = anyToSockaddr(&rsa)
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 {
377
return anyToSockaddr(&rsa)
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 {
386
return anyToSockaddr(&rsa)
389
func Bind(fd int, sa Sockaddr) (errno int) {
390
ptr, n, err := sa.sockaddr()
394
return bind(fd, ptr, n)
397
func Connect(fd int, sa Sockaddr) (errno int) {
398
ptr, n, err := sa.sockaddr()
402
return connect(fd, ptr, n)
405
func Socket(domain, typ, proto int) (fd, errno int) {
406
if domain == AF_INET6 && SocketDisableIPv6 {
407
return -1, EAFNOSUPPORT
409
fd, errno = socket(domain, typ, proto)
413
func Socketpair(domain, typ, proto int) (fd [2]int, errno int) {
414
errno = socketpair(domain, typ, proto, &fd)
418
func SetsockoptInt(fd, level, opt int, value int) (errno int) {
420
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4)
423
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
424
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), unsafe.Sizeof(*tv))
427
func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
428
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), unsafe.Sizeof(*l))
431
func SetsockoptIpMreq(fd, level, opt int, mreq *IpMreq) (errno int) {
432
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
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))
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 {
445
from, errno = anyToSockaddr(&rsa)
449
func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
450
ptr, n, err := to.sockaddr()
454
return sendto(fd, p, flags, ptr, n)
457
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, errno int) {
459
var rsa RawSockaddrAny
460
msg.Name = (*byte)(unsafe.Pointer(&rsa))
461
msg.Namelen = uint32(SizeofSockaddrAny)
464
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
469
// receive at least one normal byte
474
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
475
msg.SetControllen(len(oob))
479
if n, errno = recvmsg(fd, &msg, flags); errno != 0 {
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)
491
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (errno int) {
496
ptr, nsock, err = to.sockaddr()
502
msg.Name = (*byte)(unsafe.Pointer(ptr))
503
msg.Namelen = uint32(nsock)
506
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
511
// send at least one normal byte
516
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
517
msg.SetControllen(len(oob))
521
if errno = sendmsg(fd, &msg, flags); errno != 0 {
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)
532
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (errno int)
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.
538
// The ptrace syscall differs from glibc's ptrace.
539
// Peeks returns the word in *data, not as the return value.
541
var buf [sizeofPtr]byte
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
549
if addr%sizeofPtr != 0 {
550
errno = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
554
n += copy(out, buf[addr%sizeofPtr:])
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])))
566
copied := copy(out, buf[0:])
574
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, errno int) {
575
return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
578
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, errno int) {
579
return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
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.
588
if addr%sizeofPtr != 0 {
589
var buf [sizeofPtr]byte
590
errno = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
594
n += copy(buf[addr%sizeofPtr:], data)
595
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
596
errno = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
604
for len(data) > sizeofPtr {
605
word := *((*uintptr)(unsafe.Pointer(&data[0])))
606
errno = ptrace(pokeReq, pid, addr+uintptr(n), word)
611
data = data[sizeofPtr:]
616
var buf [sizeofPtr]byte
617
errno = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
622
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
623
errno = ptrace(pokeReq, pid, addr+uintptr(n), word)
633
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, errno int) {
634
return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
637
func PtracePokeData(pid int, addr uintptr, data []byte) (count int, errno int) {
638
return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
641
func PtraceGetRegs(pid int, regsout *PtraceRegs) (errno int) {
642
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
645
func PtraceSetRegs(pid int, regs *PtraceRegs) (errno int) {
646
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
649
func PtraceSetOptions(pid int, options int) (errno int) {
650
return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
653
func PtraceGetEventMsg(pid int) (msg uint, errno int) {
655
errno = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
660
func PtraceCont(pid int, signal int) (errno int) {
661
return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
664
func PtraceSingleStep(pid int) (errno int) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
666
func PtraceAttach(pid int) (errno int) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
668
func PtraceDetach(pid int) (errno int) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
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)
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)
857
// SchedGetPriorityMax
858
// SchedGetPriorityMin
862
// SchedRrGetInterval