2009-06-01 23:14:57 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// Linux system calls.
|
|
|
|
// This file is compiled as ordinary Go code,
|
|
|
|
// but it is also input to mksyscall,
|
|
|
|
// which parses the //sys lines and generates system call stubs.
|
|
|
|
// Note that sometimes we use a lowercase //sys name and
|
|
|
|
// wrap it in our own nicer implementation.
|
|
|
|
|
|
|
|
package syscall
|
|
|
|
|
2009-08-12 14:19:17 -06:00
|
|
|
import "unsafe"
|
2009-06-01 23:14:57 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Wrapped
|
|
|
|
*/
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys open(path string, mode int, perm uint32) (fd int, err error)
|
|
|
|
func Open(path string, mode int, perm uint32) (fd int, err error) {
|
2010-04-30 00:34:06 -06:00
|
|
|
return open(path, mode|O_LARGEFILE, perm)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
|
|
|
|
func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
|
2010-05-03 12:11:01 -06:00
|
|
|
return openat(dirfd, path, flags|O_LARGEFILE, mode)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb pipe(p *[2]_C_int) (err error)
|
|
|
|
func Pipe(p []int) (err error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if len(p) != 2 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
var pp [2]_C_int
|
2011-11-13 20:44:52 -07:00
|
|
|
err = pipe(&pp)
|
2009-12-15 16:40:16 -07:00
|
|
|
p[0] = int(pp[0])
|
|
|
|
p[1] = int(pp[1])
|
|
|
|
return
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys utimes(path string, times *[2]Timeval) (err error)
|
|
|
|
func Utimes(path string, tv []Timeval) (err error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if len(tv) != 2 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
|
|
|
|
func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if len(tv) != 2 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
syscall: return EINVAL when string arguments have NUL characters
Since NUL usually terminates strings in underlying syscalls, allowing
it when converting string arguments is a security risk, especially
when dealing with filenames. For example, a program might reason that
filename like "/root/..\x00/" is a subdirectory or "/root/" and allow
access to it, while underlying syscall will treat "\x00" as an end of
that string and the actual filename will be "/root/..", which might
be unexpected. Returning EINVAL when string arguments have NUL in
them makes sure this attack vector is unusable.
R=golang-dev, r, bradfitz, fullung, rsc, minux.ma
CC=golang-dev
https://golang.org/cl/6458050
2012-08-05 15:24:32 -06:00
|
|
|
pathp, err := BytePtrFromString(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
2010-05-19 18:47:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Futimes(fd int, tv []Timeval) (err error) {
|
2010-05-19 18:47:57 -06:00
|
|
|
// Believe it or not, this is the best we can do on Linux
|
|
|
|
// (and is what glibc does).
|
2011-04-02 15:24:03 -06:00
|
|
|
return Utimes("/proc/self/fd/"+itoa(fd), tv)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2009-11-05 11:55:57 -07:00
|
|
|
const ImplementsGetwd = true
|
2009-06-01 23:14:57 -06:00
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys Getcwd(buf []byte) (n int, err error)
|
|
|
|
func Getwd() (wd string, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var buf [PathMax]byte
|
2010-05-27 15:51:47 -06:00
|
|
|
n, err := Getcwd(buf[0:])
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return "", err
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
// Getcwd returns the number of bytes written to buf, including the NUL.
|
2009-11-05 11:55:57 -07:00
|
|
|
if n < 1 || n > len(buf) || buf[n-1] != 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return "", EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return string(buf[0 : n-1]), nil
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Getgroups() (gids []int, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
n, err := getgroups(0, nil)
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
if n == 0 {
|
2011-11-13 20:44:52 -07:00
|
|
|
return nil, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sanity check group count. Max is 1<<16 on Linux.
|
|
|
|
if n < 0 || n > 1<<20 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return nil, EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
a := make([]_Gid_t, n)
|
|
|
|
n, err = getgroups(n, &a[0])
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
gids = make([]int, n)
|
2009-06-01 23:14:57 -06:00
|
|
|
for i, v := range a[0:n] {
|
2009-11-09 13:07:39 -07:00
|
|
|
gids[i] = int(v)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Setgroups(gids []int) (err error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if len(gids) == 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return setgroups(0, nil)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
a := make([]_Gid_t, len(gids))
|
2009-06-01 23:14:57 -06:00
|
|
|
for i, v := range gids {
|
2009-11-09 13:07:39 -07:00
|
|
|
a[i] = _Gid_t(v)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return setgroups(len(a), &a[0])
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type WaitStatus uint32
|
|
|
|
|
|
|
|
// Wait status is 7 bits at bottom, either 0 (exited),
|
|
|
|
// 0x7F (stopped), or a signal number that caused an exit.
|
|
|
|
// The 0x80 bit is whether there was a core dump.
|
|
|
|
// An extra number (exit code, signal causing a stop)
|
|
|
|
// is in the high bits. At least that's the idea.
|
|
|
|
// There are various irregularities. For example, the
|
|
|
|
// "continued" status is 0xFFFF, distinguishing itself
|
|
|
|
// from stopped via the core dump bit.
|
|
|
|
|
|
|
|
const (
|
2009-12-15 16:40:16 -07:00
|
|
|
mask = 0x7F
|
|
|
|
core = 0x80
|
|
|
|
exited = 0x00
|
|
|
|
stopped = 0x7F
|
|
|
|
shift = 8
|
2009-06-01 23:14:57 -06:00
|
|
|
)
|
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
2009-06-01 23:14:57 -06:00
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
|
2009-06-01 23:14:57 -06:00
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
|
2009-06-01 23:14:57 -06:00
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
func (w WaitStatus) Continued() bool { return w == 0xFFFF }
|
2009-06-01 23:14:57 -06:00
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
|
2009-06-01 23:14:57 -06:00
|
|
|
|
|
|
|
func (w WaitStatus) ExitStatus() int {
|
|
|
|
if !w.Exited() {
|
2009-11-09 13:07:39 -07:00
|
|
|
return -1
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return int(w>>shift) & 0xFF
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
func (w WaitStatus) Signal() Signal {
|
2009-06-01 23:14:57 -06:00
|
|
|
if !w.Signaled() {
|
2009-11-09 13:07:39 -07:00
|
|
|
return -1
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
return Signal(w & mask)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
func (w WaitStatus) StopSignal() Signal {
|
2009-06-01 23:14:57 -06:00
|
|
|
if !w.Stopped() {
|
2009-11-09 13:07:39 -07:00
|
|
|
return -1
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
return Signal(w>>shift) & 0xFF
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2009-07-13 20:20:38 -06:00
|
|
|
func (w WaitStatus) TrapCause() int {
|
|
|
|
if w.StopSignal() != SIGTRAP {
|
2009-11-09 13:07:39 -07:00
|
|
|
return -1
|
2009-07-13 20:20:38 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return int(w>>shift) >> 8
|
2009-07-13 20:20:38 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
|
|
|
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var status _C_int
|
2011-11-13 20:44:52 -07:00
|
|
|
wpid, err = wait4(pid, &status, options, rusage)
|
2009-06-01 23:14:57 -06:00
|
|
|
if wstatus != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
*wstatus = WaitStatus(status)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Mkfifo(path string, mode uint32) (err error) {
|
2011-10-04 14:58:31 -06:00
|
|
|
return Mknod(path, mode|S_IFIFO, 0)
|
|
|
|
}
|
|
|
|
|
2009-06-01 23:14:57 -06:00
|
|
|
// For testing: clients can set this flag to force
|
|
|
|
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
|
|
|
var SocketDisableIPv6 bool
|
|
|
|
|
|
|
|
type Sockaddr interface {
|
2011-11-13 20:44:52 -07:00
|
|
|
sockaddr() (ptr uintptr, len _Socklen, err error) // lowercase; only we can define Sockaddrs
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type SockaddrInet4 struct {
|
2009-12-15 16:40:16 -07:00
|
|
|
Port int
|
|
|
|
Addr [4]byte
|
|
|
|
raw RawSockaddrInet4
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func (sa *SockaddrInet4) sockaddr() (uintptr, _Socklen, error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
2009-11-09 13:07:39 -07:00
|
|
|
return 0, 0, EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
sa.raw.Family = AF_INET
|
|
|
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
|
|
|
p[0] = byte(sa.Port >> 8)
|
|
|
|
p[1] = byte(sa.Port)
|
2009-06-01 23:14:57 -06:00
|
|
|
for i := 0; i < len(sa.Addr); i++ {
|
2009-11-09 13:07:39 -07:00
|
|
|
sa.raw.Addr[i] = sa.Addr[i]
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type SockaddrInet6 struct {
|
2011-05-22 11:09:07 -06:00
|
|
|
Port int
|
|
|
|
ZoneId uint32
|
|
|
|
Addr [16]byte
|
|
|
|
raw RawSockaddrInet6
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func (sa *SockaddrInet6) sockaddr() (uintptr, _Socklen, error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
2009-11-09 13:07:39 -07:00
|
|
|
return 0, 0, EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
sa.raw.Family = AF_INET6
|
|
|
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
|
|
|
p[0] = byte(sa.Port >> 8)
|
|
|
|
p[1] = byte(sa.Port)
|
2011-05-22 11:09:07 -06:00
|
|
|
sa.raw.Scope_id = sa.ZoneId
|
2009-06-01 23:14:57 -06:00
|
|
|
for i := 0; i < len(sa.Addr); i++ {
|
2009-11-09 13:07:39 -07:00
|
|
|
sa.raw.Addr[i] = sa.Addr[i]
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type SockaddrUnix struct {
|
2009-12-15 16:40:16 -07:00
|
|
|
Name string
|
|
|
|
raw RawSockaddrUnix
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
name := sa.Name
|
|
|
|
n := len(name)
|
2009-06-01 23:14:57 -06:00
|
|
|
if n >= len(sa.raw.Path) || n == 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return 0, 0, EINVAL
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
sa.raw.Family = AF_UNIX
|
2009-06-01 23:14:57 -06:00
|
|
|
for i := 0; i < n; i++ {
|
2009-11-09 13:07:39 -07:00
|
|
|
sa.raw.Path[i] = int8(name[i])
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-01-18 09:10:22 -07:00
|
|
|
// length is family (uint16), name, NUL.
|
|
|
|
sl := 2 + _Socklen(n) + 1
|
2009-06-01 23:14:57 -06:00
|
|
|
if sa.raw.Path[0] == '@' {
|
2009-11-09 13:07:39 -07:00
|
|
|
sa.raw.Path[0] = 0
|
2011-01-18 09:10:22 -07:00
|
|
|
// Don't count trailing NUL for abstract address.
|
|
|
|
sl--
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
return uintptr(unsafe.Pointer(&sa.raw)), sl, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2010-10-12 07:48:56 -06:00
|
|
|
type SockaddrLinklayer struct {
|
|
|
|
Protocol uint16
|
|
|
|
Ifindex int
|
|
|
|
Hatype uint16
|
|
|
|
Pkttype uint8
|
|
|
|
Halen uint8
|
|
|
|
Addr [8]byte
|
|
|
|
raw RawSockaddrLinklayer
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func (sa *SockaddrLinklayer) sockaddr() (uintptr, _Socklen, error) {
|
2010-10-12 07:48:56 -06:00
|
|
|
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
|
|
|
|
return 0, 0, EINVAL
|
|
|
|
}
|
|
|
|
sa.raw.Family = AF_PACKET
|
|
|
|
sa.raw.Protocol = sa.Protocol
|
|
|
|
sa.raw.Ifindex = int32(sa.Ifindex)
|
|
|
|
sa.raw.Hatype = sa.Hatype
|
|
|
|
sa.raw.Pkttype = sa.Pkttype
|
|
|
|
sa.raw.Halen = sa.Halen
|
|
|
|
for i := 0; i < len(sa.Addr); i++ {
|
|
|
|
sa.raw.Addr[i] = sa.Addr[i]
|
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrLinklayer, nil
|
2010-10-12 07:48:56 -06:00
|
|
|
}
|
|
|
|
|
2011-05-18 17:33:41 -06:00
|
|
|
type SockaddrNetlink struct {
|
|
|
|
Family uint16
|
|
|
|
Pad uint16
|
|
|
|
Pid uint32
|
|
|
|
Groups uint32
|
|
|
|
raw RawSockaddrNetlink
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func (sa *SockaddrNetlink) sockaddr() (uintptr, _Socklen, error) {
|
2011-05-18 17:33:41 -06:00
|
|
|
sa.raw.Family = AF_NETLINK
|
|
|
|
sa.raw.Pad = sa.Pad
|
|
|
|
sa.raw.Pid = sa.Pid
|
|
|
|
sa.raw.Groups = sa.Groups
|
2011-11-13 20:44:52 -07:00
|
|
|
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrNetlink, nil
|
2011-05-18 17:33:41 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
switch rsa.Addr.Family {
|
2011-05-18 17:33:41 -06:00
|
|
|
case AF_NETLINK:
|
|
|
|
pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
|
|
|
|
sa := new(SockaddrNetlink)
|
|
|
|
sa.Family = pp.Family
|
|
|
|
sa.Pad = pp.Pad
|
|
|
|
sa.Pid = pp.Pid
|
|
|
|
sa.Groups = pp.Groups
|
2011-11-13 20:44:52 -07:00
|
|
|
return sa, nil
|
2011-05-18 17:33:41 -06:00
|
|
|
|
2010-10-12 07:48:56 -06:00
|
|
|
case AF_PACKET:
|
|
|
|
pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
|
|
|
|
sa := new(SockaddrLinklayer)
|
|
|
|
sa.Protocol = pp.Protocol
|
|
|
|
sa.Ifindex = int(pp.Ifindex)
|
|
|
|
sa.Hatype = pp.Hatype
|
|
|
|
sa.Pkttype = pp.Pkttype
|
|
|
|
sa.Halen = pp.Halen
|
|
|
|
for i := 0; i < len(sa.Addr); i++ {
|
|
|
|
sa.Addr[i] = pp.Addr[i]
|
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return sa, nil
|
2010-10-12 07:48:56 -06:00
|
|
|
|
2009-06-01 23:14:57 -06:00
|
|
|
case AF_UNIX:
|
2009-12-15 16:40:16 -07:00
|
|
|
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
|
|
|
|
sa := new(SockaddrUnix)
|
2009-06-01 23:14:57 -06:00
|
|
|
if pp.Path[0] == 0 {
|
|
|
|
// "Abstract" Unix domain socket.
|
|
|
|
// Rewrite leading NUL as @ for textual display.
|
|
|
|
// (This is the standard convention.)
|
|
|
|
// Not friendly to overwrite in place,
|
|
|
|
// but the callers below don't care.
|
2009-11-09 13:07:39 -07:00
|
|
|
pp.Path[0] = '@'
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Assume path ends at NUL.
|
|
|
|
// This is not technically the Linux semantics for
|
|
|
|
// abstract Unix domain sockets--they are supposed
|
|
|
|
// to be uninterpreted fixed-size binary blobs--but
|
|
|
|
// everyone uses this convention.
|
2009-12-15 16:40:16 -07:00
|
|
|
n := 0
|
2009-06-01 23:14:57 -06:00
|
|
|
for n < len(pp.Path) && pp.Path[n] != 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
n++
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2010-07-01 18:49:28 -06:00
|
|
|
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
|
|
|
|
sa.Name = string(bytes)
|
2011-11-13 20:44:52 -07:00
|
|
|
return sa, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
|
|
|
|
case AF_INET:
|
2009-12-15 16:40:16 -07:00
|
|
|
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
|
|
|
sa := new(SockaddrInet4)
|
|
|
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
|
|
|
sa.Port = int(p[0])<<8 + int(p[1])
|
2009-06-01 23:14:57 -06:00
|
|
|
for i := 0; i < len(sa.Addr); i++ {
|
2009-11-09 13:07:39 -07:00
|
|
|
sa.Addr[i] = pp.Addr[i]
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return sa, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
|
|
|
|
case AF_INET6:
|
2009-12-15 16:40:16 -07:00
|
|
|
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
|
|
|
|
sa := new(SockaddrInet6)
|
|
|
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
|
|
|
sa.Port = int(p[0])<<8 + int(p[1])
|
2011-05-22 11:09:07 -06:00
|
|
|
sa.ZoneId = pp.Scope_id
|
2009-06-01 23:14:57 -06:00
|
|
|
for i := 0; i < len(sa.Addr); i++ {
|
2009-11-09 13:07:39 -07:00
|
|
|
sa.Addr[i] = pp.Addr[i]
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
return sa, nil
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return nil, EAFNOSUPPORT
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var rsa RawSockaddrAny
|
|
|
|
var len _Socklen = SizeofSockaddrAny
|
2011-11-13 20:44:52 -07:00
|
|
|
nfd, err = accept(fd, &rsa, &len)
|
|
|
|
if err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
sa, err = anyToSockaddr(&rsa)
|
|
|
|
if err != nil {
|
2009-12-15 16:40:16 -07:00
|
|
|
Close(nfd)
|
|
|
|
nfd = 0
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Getsockname(fd int) (sa Sockaddr, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var rsa RawSockaddrAny
|
|
|
|
var len _Socklen = SizeofSockaddrAny
|
2011-11-13 20:44:52 -07:00
|
|
|
if err = getsockname(fd, &rsa, &len); err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-06-17 22:44:26 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return anyToSockaddr(&rsa)
|
2009-06-17 22:44:26 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Getpeername(fd int) (sa Sockaddr, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var rsa RawSockaddrAny
|
|
|
|
var len _Socklen = SizeofSockaddrAny
|
2011-11-13 20:44:52 -07:00
|
|
|
if err = getpeername(fd, &rsa, &len); err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-06-17 22:44:26 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return anyToSockaddr(&rsa)
|
2009-06-17 22:44:26 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Bind(fd int, sa Sockaddr) (err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
ptr, n, err := sa.sockaddr()
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return err
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return bind(fd, ptr, n)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Connect(fd int, sa Sockaddr) (err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
ptr, n, err := sa.sockaddr()
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return err
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return connect(fd, ptr, n)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Socket(domain, typ, proto int) (fd int, err error) {
|
2009-06-01 23:14:57 -06:00
|
|
|
if domain == AF_INET6 && SocketDisableIPv6 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return -1, EAFNOSUPPORT
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
fd, err = socket(domain, typ, proto)
|
2009-12-15 16:40:16 -07:00
|
|
|
return
|
2010-06-30 15:58:21 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
|
2012-09-23 22:06:22 -06:00
|
|
|
var fdx [2]int32
|
|
|
|
err = socketpair(domain, typ, proto, &fdx)
|
|
|
|
if err == nil {
|
|
|
|
fd[0] = int(fdx[0])
|
|
|
|
fd[1] = int(fdx[1])
|
|
|
|
}
|
2010-06-30 15:58:21 -06:00
|
|
|
return
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func GetsockoptInt(fd, level, opt int) (value int, err error) {
|
2011-03-23 12:33:48 -06:00
|
|
|
var n int32
|
|
|
|
vallen := _Socklen(4)
|
2011-11-13 20:44:52 -07:00
|
|
|
err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), &vallen)
|
|
|
|
return int(n), err
|
2011-03-23 12:33:48 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
|
2011-10-01 03:45:06 -06:00
|
|
|
vallen := _Socklen(4)
|
2011-11-13 20:44:52 -07:00
|
|
|
err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), &vallen)
|
|
|
|
return value, err
|
2011-10-01 03:45:06 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
|
2011-10-01 03:45:06 -06:00
|
|
|
var value IPMreq
|
|
|
|
vallen := _Socklen(SizeofIPMreq)
|
2011-11-13 20:44:52 -07:00
|
|
|
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
|
|
|
|
return &value, err
|
2011-10-01 03:45:06 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
|
2011-10-01 03:45:06 -06:00
|
|
|
var value IPMreqn
|
|
|
|
vallen := _Socklen(SizeofIPMreqn)
|
2011-11-13 20:44:52 -07:00
|
|
|
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
|
|
|
|
return &value, err
|
2011-10-01 03:45:06 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
|
2011-10-01 03:45:06 -06:00
|
|
|
var value IPv6Mreq
|
|
|
|
vallen := _Socklen(SizeofIPv6Mreq)
|
2011-11-13 20:44:52 -07:00
|
|
|
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
|
|
|
|
return &value, err
|
2011-10-01 03:45:06 -06:00
|
|
|
}
|
|
|
|
|
2012-09-12 07:38:21 -06:00
|
|
|
func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
|
|
|
|
var value Ucred
|
|
|
|
vallen := _Socklen(SizeofUcred)
|
|
|
|
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
|
|
|
|
return &value, err
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptInt(fd, level, opt int, value int) (err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var n = int32(value)
|
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4)
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
|
2011-10-01 03:45:06 -06:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), 4)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), unsafe.Sizeof(*tv))
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), unsafe.Sizeof(*l))
|
2009-06-01 23:14:57 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
|
2011-06-02 08:10:17 -06:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
|
2011-10-01 03:45:06 -06:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
|
2011-02-03 12:15:35 -07:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(mreq)), unsafe.Sizeof(*mreq))
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func SetsockoptString(fd, level, opt int, s string) (err error) {
|
2011-06-17 14:12:14 -06:00
|
|
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&[]byte(s)[0])), uintptr(len(s)))
|
2010-03-24 23:36:38 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var rsa RawSockaddrAny
|
|
|
|
var len _Socklen = SizeofSockaddrAny
|
2011-11-13 20:44:52 -07:00
|
|
|
if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-11-01 12:13:27 -07:00
|
|
|
}
|
2011-11-13 20:44:52 -07:00
|
|
|
from, err = anyToSockaddr(&rsa)
|
2009-12-15 16:40:16 -07:00
|
|
|
return
|
2009-11-01 12:13:27 -07:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
ptr, n, err := to.sockaddr()
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return err
|
2009-11-01 12:13:27 -07:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
return sendto(fd, p, flags, ptr, n)
|
2009-11-01 12:13:27 -07:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
2010-12-07 11:40:14 -07:00
|
|
|
var msg Msghdr
|
|
|
|
var rsa RawSockaddrAny
|
|
|
|
msg.Name = (*byte)(unsafe.Pointer(&rsa))
|
|
|
|
msg.Namelen = uint32(SizeofSockaddrAny)
|
|
|
|
var iov Iovec
|
|
|
|
if len(p) > 0 {
|
|
|
|
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
|
|
|
|
iov.SetLen(len(p))
|
|
|
|
}
|
|
|
|
var dummy byte
|
|
|
|
if len(oob) > 0 {
|
|
|
|
// receive at least one normal byte
|
|
|
|
if len(p) == 0 {
|
|
|
|
iov.Base = &dummy
|
|
|
|
iov.SetLen(1)
|
|
|
|
}
|
|
|
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
|
|
|
msg.SetControllen(len(oob))
|
|
|
|
}
|
|
|
|
msg.Iov = &iov
|
|
|
|
msg.Iovlen = 1
|
2011-11-13 20:44:52 -07:00
|
|
|
if n, err = recvmsg(fd, &msg, flags); err != nil {
|
2010-12-07 11:40:14 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
oobn = int(msg.Controllen)
|
|
|
|
recvflags = int(msg.Flags)
|
2011-01-19 12:34:53 -07:00
|
|
|
// source address is only specified if the socket is unconnected
|
2011-05-18 17:33:41 -06:00
|
|
|
if rsa.Addr.Family != AF_UNSPEC {
|
2011-11-13 20:44:52 -07:00
|
|
|
from, err = anyToSockaddr(&rsa)
|
2011-01-19 12:34:53 -07:00
|
|
|
}
|
2010-12-07 11:40:14 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
|
2010-12-07 11:40:14 -07:00
|
|
|
var ptr uintptr
|
2011-06-20 16:40:20 -06:00
|
|
|
var salen _Socklen
|
2010-12-07 11:40:14 -07:00
|
|
|
if to != nil {
|
2011-11-13 20:44:52 -07:00
|
|
|
var err error
|
2011-06-20 16:40:20 -06:00
|
|
|
ptr, salen, err = to.sockaddr()
|
2011-11-13 20:44:52 -07:00
|
|
|
if err != nil {
|
2010-12-07 11:40:14 -07:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var msg Msghdr
|
|
|
|
msg.Name = (*byte)(unsafe.Pointer(ptr))
|
2011-06-20 16:40:20 -06:00
|
|
|
msg.Namelen = uint32(salen)
|
2010-12-07 11:40:14 -07:00
|
|
|
var iov Iovec
|
|
|
|
if len(p) > 0 {
|
|
|
|
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
|
|
|
|
iov.SetLen(len(p))
|
|
|
|
}
|
|
|
|
var dummy byte
|
|
|
|
if len(oob) > 0 {
|
|
|
|
// send at least one normal byte
|
|
|
|
if len(p) == 0 {
|
|
|
|
iov.Base = &dummy
|
|
|
|
iov.SetLen(1)
|
|
|
|
}
|
|
|
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
|
|
|
msg.SetControllen(len(oob))
|
|
|
|
}
|
|
|
|
msg.Iov = &iov
|
|
|
|
msg.Iovlen = 1
|
2011-11-13 20:44:52 -07:00
|
|
|
if err = sendmsg(fd, &msg, flags); err != nil {
|
2010-12-07 11:40:14 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2010-05-20 10:43:13 -06:00
|
|
|
// BindToDevice binds the socket associated with fd to device.
|
2011-11-13 20:44:52 -07:00
|
|
|
func BindToDevice(fd int, device string) (err error) {
|
2010-05-20 10:43:13 -06:00
|
|
|
return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
|
2009-07-14 11:53:04 -06:00
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
|
2009-07-14 11:53:04 -06:00
|
|
|
// The peek requests are machine-size oriented, so we wrap it
|
|
|
|
// to retrieve arbitrary-length data.
|
|
|
|
|
|
|
|
// The ptrace syscall differs from glibc's ptrace.
|
|
|
|
// Peeks returns the word in *data, not as the return value.
|
|
|
|
|
2009-12-15 16:40:16 -07:00
|
|
|
var buf [sizeofPtr]byte
|
2009-07-14 11:53:04 -06:00
|
|
|
|
|
|
|
// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
|
|
|
|
// access (PEEKUSER warns that it might), but if we don't
|
|
|
|
// align our reads, we might straddle an unmapped page
|
|
|
|
// boundary and not get the bytes leading up to the page
|
|
|
|
// boundary.
|
2009-12-15 16:40:16 -07:00
|
|
|
n := 0
|
2009-11-09 22:23:52 -07:00
|
|
|
if addr%sizeofPtr != 0 {
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
n += copy(out, buf[addr%sizeofPtr:])
|
|
|
|
out = out[n:]
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remainder.
|
|
|
|
for len(out) > 0 {
|
2012-03-13 18:29:07 -06:00
|
|
|
// We use an internal buffer to guarantee alignment.
|
2009-07-14 11:53:04 -06:00
|
|
|
// It's not documented if this is necessary, but we're paranoid.
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
|
|
|
|
if err != nil {
|
|
|
|
return n, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2010-05-27 15:51:47 -06:00
|
|
|
copied := copy(out, buf[0:])
|
2009-12-15 16:40:16 -07:00
|
|
|
n += copied
|
|
|
|
out = out[copied:]
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
return n, nil
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
|
2009-07-14 11:53:04 -06:00
|
|
|
// As for ptracePeek, we need to align our accesses to deal
|
|
|
|
// with the possibility of straddling an invalid page.
|
|
|
|
|
|
|
|
// Leading edge.
|
2009-12-15 16:40:16 -07:00
|
|
|
n := 0
|
2009-11-09 22:23:52 -07:00
|
|
|
if addr%sizeofPtr != 0 {
|
2009-12-15 16:40:16 -07:00
|
|
|
var buf [sizeofPtr]byte
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
n += copy(buf[addr%sizeofPtr:], data)
|
|
|
|
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
data = data[n:]
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Interior.
|
|
|
|
for len(data) > sizeofPtr {
|
2009-12-15 16:40:16 -07:00
|
|
|
word := *((*uintptr)(unsafe.Pointer(&data[0])))
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(pokeReq, pid, addr+uintptr(n), word)
|
|
|
|
if err != nil {
|
|
|
|
return n, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
n += sizeofPtr
|
|
|
|
data = data[sizeofPtr:]
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Trailing edge.
|
|
|
|
if len(data) > 0 {
|
2009-12-15 16:40:16 -07:00
|
|
|
var buf [sizeofPtr]byte
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
|
|
|
|
if err != nil {
|
|
|
|
return n, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2010-05-27 15:51:47 -06:00
|
|
|
copy(buf[0:], data)
|
2009-12-15 16:40:16 -07:00
|
|
|
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(pokeReq, pid, addr+uintptr(n), word)
|
|
|
|
if err != nil {
|
|
|
|
return n, err
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
2009-12-15 16:40:16 -07:00
|
|
|
n += len(data)
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
return n, nil
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceSetOptions(pid int, options int) (err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceGetEventMsg(pid int) (msg uint, err error) {
|
2009-12-15 16:40:16 -07:00
|
|
|
var data _C_long
|
2011-11-13 20:44:52 -07:00
|
|
|
err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
|
2009-12-15 16:40:16 -07:00
|
|
|
msg = uint(data)
|
|
|
|
return
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceCont(pid int, signal int) (err error) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
|
2009-07-14 11:53:04 -06:00
|
|
|
}
|
|
|
|
|
2012-08-31 17:17:14 -06:00
|
|
|
func PtraceSyscall(pid int, signal int) (err error) {
|
|
|
|
return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
|
2009-07-14 11:53:04 -06:00
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
|
2009-07-14 11:53:04 -06:00
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
|
2009-07-14 11:53:04 -06:00
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
|
|
|
|
func Reboot(cmd int) (err error) {
|
2011-03-09 06:45:08 -07:00
|
|
|
return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
|
|
|
|
}
|
|
|
|
|
2011-04-06 13:44:40 -06:00
|
|
|
func clen(n []byte) int {
|
|
|
|
for i := 0; i < len(n); i++ {
|
|
|
|
if n[i] == 0 {
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return len(n)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func ReadDirent(fd int, buf []byte) (n int, err error) {
|
2011-04-06 13:44:40 -06:00
|
|
|
return Getdents(fd, buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
|
|
|
origlen := len(buf)
|
|
|
|
count = 0
|
|
|
|
for max != 0 && len(buf) > 0 {
|
|
|
|
dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
|
|
|
|
buf = buf[dirent.Reclen:]
|
|
|
|
if dirent.Ino == 0 { // File absent in directory.
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
|
|
|
|
var name = string(bytes[0:clen(bytes[:])])
|
|
|
|
if name == "." || name == ".." { // Useless names
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
max--
|
|
|
|
count++
|
|
|
|
names = append(names, name)
|
|
|
|
}
|
|
|
|
return origlen - len(buf), count, names
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
|
|
|
|
func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
|
2011-10-14 10:19:45 -06:00
|
|
|
// Certain file systems get rather angry and EINVAL if you give
|
|
|
|
// them an empty string of data, rather than NULL.
|
|
|
|
if data == "" {
|
|
|
|
return mount(source, target, fstype, flags, nil)
|
|
|
|
}
|
syscall: return EINVAL when string arguments have NUL characters
Since NUL usually terminates strings in underlying syscalls, allowing
it when converting string arguments is a security risk, especially
when dealing with filenames. For example, a program might reason that
filename like "/root/..\x00/" is a subdirectory or "/root/" and allow
access to it, while underlying syscall will treat "\x00" as an end of
that string and the actual filename will be "/root/..", which might
be unexpected. Returning EINVAL when string arguments have NUL in
them makes sure this attack vector is unusable.
R=golang-dev, r, bradfitz, fullung, rsc, minux.ma
CC=golang-dev
https://golang.org/cl/6458050
2012-08-05 15:24:32 -06:00
|
|
|
datap, err := BytePtrFromString(data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return mount(source, target, fstype, flags, datap)
|
2011-10-14 10:19:45 -06:00
|
|
|
}
|
|
|
|
|
2009-06-01 23:14:57 -06:00
|
|
|
// Sendto
|
|
|
|
// Recvfrom
|
|
|
|
// Socketpair
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Direct access
|
|
|
|
*/
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys Access(path string, mode uint32) (err error)
|
|
|
|
//sys Acct(path string) (err error)
|
|
|
|
//sys Adjtimex(buf *Timex) (state int, err error)
|
|
|
|
//sys Chdir(path string) (err error)
|
|
|
|
//sys Chmod(path string, mode uint32) (err error)
|
|
|
|
//sys Chroot(path string) (err error)
|
|
|
|
//sys Close(fd int) (err error)
|
|
|
|
//sys Creat(path string, mode uint32) (fd int, err error)
|
|
|
|
//sysnb Dup(oldfd int) (fd int, err error)
|
2012-02-12 22:11:36 -07:00
|
|
|
//sysnb Dup2(oldfd int, newfd int) (err error)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb EpollCreate(size int) (fd int, err error)
|
2011-12-19 13:57:49 -07:00
|
|
|
//sysnb EpollCreate1(flag int) (fd int, err error)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
|
|
|
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
2009-06-01 23:14:57 -06:00
|
|
|
//sys Exit(code int) = SYS_EXIT_GROUP
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
|
|
|
//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
|
|
|
|
//sys Fchdir(fd int) (err error)
|
|
|
|
//sys Fchmod(fd int, mode uint32) (err error)
|
|
|
|
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
|
|
|
|
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
|
|
|
|
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
|
|
|
//sys Fdatasync(fd int) (err error)
|
|
|
|
//sys Flock(fd int, how int) (err error)
|
|
|
|
//sys Fsync(fd int) (err error)
|
|
|
|
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
|
|
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
2011-03-16 20:03:01 -06:00
|
|
|
//sysnb Getpgrp() (pid int)
|
|
|
|
//sysnb Getpid() (pid int)
|
|
|
|
//sysnb Getppid() (ppid int)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
2011-03-16 20:03:01 -06:00
|
|
|
//sysnb Gettid() (tid int)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
|
|
|
|
//sysnb InotifyInit() (fd int, err error)
|
|
|
|
//sysnb InotifyInit1(flags int) (fd int, err error)
|
|
|
|
//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
//sysnb Kill(pid int, sig Signal) (err error)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
|
|
|
|
//sys Link(oldpath string, newpath string) (err error)
|
|
|
|
//sys Mkdir(path string, mode uint32) (err error)
|
|
|
|
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
|
|
|
|
//sys Mknod(path string, mode uint32, dev int) (err error)
|
|
|
|
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
|
|
|
|
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
|
|
|
|
//sys Pause() (err error)
|
|
|
|
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
|
2012-07-30 16:21:24 -06:00
|
|
|
//sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys Read(fd int, p []byte) (n int, err error)
|
|
|
|
//sys Readlink(path string, buf []byte) (n int, err error)
|
|
|
|
//sys Rename(oldpath string, newpath string) (err error)
|
|
|
|
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
|
|
|
//sys Rmdir(path string) (err error)
|
|
|
|
//sys Setdomainname(p []byte) (err error)
|
|
|
|
//sys Sethostname(p []byte) (err error)
|
|
|
|
//sysnb Setpgid(pid int, pgid int) (err error)
|
|
|
|
//sysnb Setsid() (pid int, err error)
|
|
|
|
//sysnb Settimeofday(tv *Timeval) (err error)
|
|
|
|
//sysnb Setuid(uid int) (err error)
|
|
|
|
//sys Symlink(oldpath string, newpath string) (err error)
|
2009-06-01 23:14:57 -06:00
|
|
|
//sys Sync()
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb Sysinfo(info *Sysinfo_t) (err error)
|
|
|
|
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
|
2012-02-14 11:07:14 -07:00
|
|
|
//sysnb Tgkill(tgid int, tid int, sig Signal) (err error)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb Times(tms *Tms) (ticks uintptr, err error)
|
2011-03-16 20:03:01 -06:00
|
|
|
//sysnb Umask(mask int) (oldmask int)
|
2011-11-13 20:44:52 -07:00
|
|
|
//sysnb Uname(buf *Utsname) (err error)
|
|
|
|
//sys Unlink(path string) (err error)
|
|
|
|
//sys Unlinkat(dirfd int, path string) (err error)
|
|
|
|
//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
|
|
|
|
//sys Unshare(flags int) (err error)
|
|
|
|
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
|
|
|
//sys Utime(path string, buf *Utimbuf) (err error)
|
|
|
|
//sys Write(fd int, p []byte) (n int, err error)
|
|
|
|
//sys exitThread(code int) (err error) = SYS_EXIT
|
|
|
|
//sys read(fd int, p *byte, np int) (n int, err error)
|
|
|
|
//sys write(fd int, p *byte, np int) (n int, err error)
|
2009-06-01 23:14:57 -06:00
|
|
|
|
2011-04-06 21:07:32 -06:00
|
|
|
// mmap varies by architecture; see syscall_linux_*.go.
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys munmap(addr uintptr, length uintptr) (err error)
|
2011-04-06 15:52:02 -06:00
|
|
|
|
|
|
|
var mapper = &mmapper{
|
|
|
|
active: make(map[*byte][]byte),
|
|
|
|
mmap: mmap,
|
|
|
|
munmap: munmap,
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
2011-04-06 15:52:02 -06:00
|
|
|
return mapper.Mmap(fd, offset, length, prot, flags)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
func Munmap(b []byte) (err error) {
|
2011-04-06 15:52:02 -06:00
|
|
|
return mapper.Munmap(b)
|
|
|
|
}
|
|
|
|
|
2011-11-13 20:44:52 -07:00
|
|
|
//sys Madvise(b []byte, advice int) (err error)
|
|
|
|
//sys Mprotect(b []byte, prot int) (err error)
|
|
|
|
//sys Mlock(b []byte) (err error)
|
|
|
|
//sys Munlock(b []byte) (err error)
|
|
|
|
//sys Mlockall(flags int) (err error)
|
|
|
|
//sys Munlockall() (err error)
|
2011-04-21 08:23:11 -06:00
|
|
|
|
2009-06-01 23:14:57 -06:00
|
|
|
/*
|
|
|
|
* Unimplemented
|
|
|
|
*/
|
|
|
|
// AddKey
|
|
|
|
// AfsSyscall
|
|
|
|
// Alarm
|
|
|
|
// ArchPrctl
|
|
|
|
// Brk
|
|
|
|
// Capget
|
|
|
|
// Capset
|
|
|
|
// ClockGetres
|
|
|
|
// ClockGettime
|
|
|
|
// ClockNanosleep
|
|
|
|
// ClockSettime
|
|
|
|
// Clone
|
|
|
|
// CreateModule
|
|
|
|
// DeleteModule
|
|
|
|
// EpollCtlOld
|
|
|
|
// EpollPwait
|
|
|
|
// EpollWaitOld
|
|
|
|
// Eventfd
|
|
|
|
// Execve
|
|
|
|
// Fadvise64
|
|
|
|
// Fgetxattr
|
|
|
|
// Flistxattr
|
|
|
|
// Fork
|
|
|
|
// Fremovexattr
|
|
|
|
// Fsetxattr
|
|
|
|
// Futex
|
|
|
|
// GetKernelSyms
|
|
|
|
// GetMempolicy
|
|
|
|
// GetRobustList
|
|
|
|
// GetThreadArea
|
|
|
|
// Getitimer
|
|
|
|
// Getpmsg
|
|
|
|
// Getpriority
|
|
|
|
// Getxattr
|
|
|
|
// IoCancel
|
|
|
|
// IoDestroy
|
|
|
|
// IoGetevents
|
|
|
|
// IoSetup
|
|
|
|
// IoSubmit
|
|
|
|
// Ioctl
|
|
|
|
// IoprioGet
|
|
|
|
// IoprioSet
|
|
|
|
// KexecLoad
|
|
|
|
// Keyctl
|
|
|
|
// Lgetxattr
|
|
|
|
// Listxattr
|
|
|
|
// Llistxattr
|
|
|
|
// LookupDcookie
|
|
|
|
// Lremovexattr
|
|
|
|
// Lsetxattr
|
|
|
|
// Mbind
|
|
|
|
// MigratePages
|
|
|
|
// Mincore
|
|
|
|
// ModifyLdt
|
|
|
|
// Mount
|
|
|
|
// MovePages
|
|
|
|
// Mprotect
|
|
|
|
// MqGetsetattr
|
|
|
|
// MqNotify
|
|
|
|
// MqOpen
|
|
|
|
// MqTimedreceive
|
|
|
|
// MqTimedsend
|
|
|
|
// MqUnlink
|
|
|
|
// Mremap
|
|
|
|
// Msgctl
|
|
|
|
// Msgget
|
|
|
|
// Msgrcv
|
|
|
|
// Msgsnd
|
|
|
|
// Msync
|
|
|
|
// Newfstatat
|
|
|
|
// Nfsservctl
|
|
|
|
// Personality
|
|
|
|
// Poll
|
|
|
|
// Ppoll
|
|
|
|
// Prctl
|
|
|
|
// Pselect6
|
|
|
|
// Ptrace
|
|
|
|
// Putpmsg
|
|
|
|
// QueryModule
|
|
|
|
// Quotactl
|
|
|
|
// Readahead
|
|
|
|
// Readv
|
|
|
|
// RemapFilePages
|
|
|
|
// Removexattr
|
|
|
|
// RequestKey
|
|
|
|
// RestartSyscall
|
|
|
|
// RtSigaction
|
|
|
|
// RtSigpending
|
|
|
|
// RtSigprocmask
|
|
|
|
// RtSigqueueinfo
|
|
|
|
// RtSigreturn
|
|
|
|
// RtSigsuspend
|
|
|
|
// RtSigtimedwait
|
|
|
|
// SchedGetPriorityMax
|
|
|
|
// SchedGetPriorityMin
|
|
|
|
// SchedGetaffinity
|
|
|
|
// SchedGetparam
|
|
|
|
// SchedGetscheduler
|
|
|
|
// SchedRrGetInterval
|
|
|
|
// SchedSetaffinity
|
|
|
|
// SchedSetparam
|
|
|
|
// SchedYield
|
|
|
|
// Security
|
|
|
|
// Semctl
|
|
|
|
// Semget
|
|
|
|
// Semop
|
|
|
|
// Semtimedop
|
|
|
|
// SetMempolicy
|
|
|
|
// SetRobustList
|
|
|
|
// SetThreadArea
|
|
|
|
// SetTidAddress
|
|
|
|
// Setpriority
|
|
|
|
// Setxattr
|
|
|
|
// Shmat
|
|
|
|
// Shmctl
|
|
|
|
// Shmdt
|
|
|
|
// Shmget
|
|
|
|
// Sigaltstack
|
|
|
|
// Signalfd
|
|
|
|
// Swapoff
|
|
|
|
// Swapon
|
|
|
|
// Sysfs
|
|
|
|
// TimerCreate
|
|
|
|
// TimerDelete
|
|
|
|
// TimerGetoverrun
|
|
|
|
// TimerGettime
|
|
|
|
// TimerSettime
|
|
|
|
// Timerfd
|
|
|
|
// Tkill (obsolete)
|
|
|
|
// Tuxcall
|
|
|
|
// Umount2
|
|
|
|
// Uselib
|
|
|
|
// Utimensat
|
|
|
|
// Vfork
|
|
|
|
// Vhangup
|
|
|
|
// Vmsplice
|
|
|
|
// Vserver
|
|
|
|
// Waitid
|
|
|
|
// Writev
|
|
|
|
// _Sysctl
|