OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/gnu-dev/fsf-gcc-snapshot-1-mar-12/or1k-gcc/libgo/go/syscall
    from Rev 747 to Rev 783
    Reverse comparison

Rev 747 → Rev 783

/exec_bsd.go
0,0 → 1,223
// Copyright 2011 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.
 
// +build darwin freebsd netbsd openbsd
 
package syscall
 
import (
"unsafe"
)
 
type SysProcAttr struct {
Chroot string // Chroot.
Credential *Credential // Credential.
Ptrace bool // Enable tracing.
Setsid bool // Create session.
Setpgid bool // Set process group ID to new pid (SYSV setpgrp)
Setctty bool // Set controlling terminal to fd 0
Noctty bool // Detach fd 0 from controlling terminal
}
 
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
// If a dup or exec fails, write the errno error to pipe.
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
// Declare all variables at top in case any
// declarations require heap allocation (e.g., err1).
var (
r1 Pid_t
err1 Errno
nextfd int
i int
)
 
// guard against side effects of shuffling fds below.
fd := append([]int(nil), attr.Files...)
 
// About to call fork.
// No more allocation or calls of non-assembly functions.
r1, err1 = raw_fork()
if err1 != 0 {
return 0, err1
}
 
if r1 != 0 {
// parent; return PID
return int(r1), 0
}
 
// Fork succeeded, now in child.
 
// Enable tracing if requested.
if sys.Ptrace {
err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil)
if err1 != 0 {
goto childerror
}
}
 
// Session ID
if sys.Setsid {
err1 = raw_setsid()
if err1 != 0 {
goto childerror
}
}
 
// Set process group
if sys.Setpgid {
err1 = raw_setpgid(0, 0)
if err1 != 0 {
goto childerror
}
}
 
// Chroot
if chroot != nil {
err1 = raw_chroot(chroot)
if err1 != 0 {
goto childerror
}
}
 
// User and groups
if cred := sys.Credential; cred != nil {
ngroups := len(cred.Groups)
if ngroups == 0 {
err2 := setgroups(0, nil)
if err2 == nil {
err1 = 0
} else {
err1 = err2.(Errno)
}
} else {
groups := make([]Gid_t, ngroups)
for i, v := range cred.Groups {
groups[i] = Gid_t(v)
}
err2 := setgroups(ngroups, &groups[0])
if err2 == nil {
err1 = 0
} else {
err1 = err2.(Errno)
}
}
if err1 != 0 {
goto childerror
}
err2 := Setgid(int(cred.Gid))
if err2 != nil {
err1 = err2.(Errno)
goto childerror
}
err2 = Setuid(int(cred.Uid))
if err2 != nil {
err1 = err2.(Errno)
goto childerror
}
}
 
// Chdir
if dir != nil {
err1 = raw_chdir(dir)
if err1 != 0 {
goto childerror
}
}
 
// Pass 1: look for fd[i] < i and move those up above len(fd)
// so that pass 2 won't stomp on an fd it needs later.
nextfd = int(len(fd))
if pipe < nextfd {
err1 = raw_dup2(pipe, nextfd)
if err1 != 0 {
goto childerror
}
raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
pipe = nextfd
nextfd++
}
for i = 0; i < len(fd); i++ {
if fd[i] >= 0 && fd[i] < int(i) {
err1 = raw_dup2(fd[i], nextfd)
if err1 != 0 {
goto childerror
}
raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
fd[i] = nextfd
nextfd++
if nextfd == pipe { // don't stomp on pipe
nextfd++
}
}
}
 
// Pass 2: dup fd[i] down onto i.
for i = 0; i < len(fd); i++ {
if fd[i] == -1 {
raw_close(i)
continue
}
if fd[i] == int(i) {
// dup2(i, i) won't clear close-on-exec flag on Linux,
// probably not elsewhere either.
_, err1 = raw_fcntl(fd[i], F_SETFD, 0)
if err1 != 0 {
goto childerror
}
continue
}
// The new fd is created NOT close-on-exec,
// which is exactly what we want.
err1 = raw_dup2(fd[i], i)
if err1 != 0 {
goto childerror
}
}
 
// By convention, we don't close-on-exec the fds we are
// started with, so if len(fd) < 3, close 0, 1, 2 as needed.
// Programs that know they inherit fds >= 3 will need
// to set them close-on-exec.
for i = len(fd); i < 3; i++ {
raw_close(i)
}
 
// Detach fd 0 from tty
if sys.Noctty {
_, err1 = raw_ioctl(0, TIOCNOTTY, 0)
if err1 != 0 {
goto childerror
}
}
 
// Make fd 0 the tty
if sys.Setctty {
_, err1 = raw_ioctl(0, TIOCSCTTY, 0)
if err1 != 0 {
goto childerror
}
}
 
// Time to exec.
err1 = raw_execve(argv0, &argv[0], &envv[0])
 
childerror:
// send error code on pipe
raw_write(pipe, (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
for {
raw_exit(253)
}
 
// Calling panic is not actually safe,
// but the for loop above won't break
// and this shuts up the compiler.
panic("unreached")
}
/sockcmsg_unix.go
0,0 → 1,115
// Copyright 2011 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.
 
// +build darwin freebsd linux netbsd openbsd
 
// Socket control messages
 
package syscall
 
import (
"unsafe"
)
 
// Round the length of a raw sockaddr up to align it propery.
func cmsgAlignOf(salen int) int {
salign := int(sizeofPtr)
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
// aligned access to BSD subsystem.
if darwinAMD64 {
salign = 4
}
if salen == 0 {
return salign
}
return (salen + salign - 1) & ^(salign - 1)
}
 
// CmsgLen returns the value to store in the Len field of the Cmsghdr
// structure, taking into account any necessary alignment.
func CmsgLen(datalen int) int {
return cmsgAlignOf(SizeofCmsghdr) + datalen
}
 
// CmsgSpace returns the number of bytes an ancillary element with
// payload of the passed data length occupies.
func CmsgSpace(datalen int) int {
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
}
 
func cmsgData(cmsg *Cmsghdr) unsafe.Pointer {
return unsafe.Pointer(uintptr(unsafe.Pointer(cmsg)) + uintptr(SizeofCmsghdr))
}
 
type SocketControlMessage struct {
Header Cmsghdr
Data []byte
}
 
func ParseSocketControlMessage(buf []byte) ([]SocketControlMessage, error) {
var (
h *Cmsghdr
dbuf []byte
e error
cmsgs []SocketControlMessage
)
 
for len(buf) >= CmsgLen(0) {
h, dbuf, e = socketControlMessageHeaderAndData(buf)
if e != nil {
break
}
m := SocketControlMessage{}
m.Header = *h
m.Data = dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]
cmsgs = append(cmsgs, m)
buf = buf[cmsgAlignOf(int(h.Len)):]
}
 
return cmsgs, e
}
 
func socketControlMessageHeaderAndData(buf []byte) (*Cmsghdr, []byte, error) {
h := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
if int(h.Len) < SizeofCmsghdr || int(h.Len) > len(buf) {
return nil, nil, EINVAL
}
return h, buf[cmsgAlignOf(SizeofCmsghdr):], nil
}
 
// UnixRights encodes a set of open file descriptors into a socket
// control message for sending to another process.
func UnixRights(fds ...int) []byte {
datalen := len(fds) * 4
buf := make([]byte, CmsgSpace(datalen))
cmsg := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
cmsg.Level = SOL_SOCKET
cmsg.Type = SCM_RIGHTS
cmsg.SetLen(CmsgLen(datalen))
 
data := uintptr(cmsgData(cmsg))
for _, fd := range fds {
*(*int32)(unsafe.Pointer(data)) = int32(fd)
data += 4
}
 
return buf
}
 
// ParseUnixRights decodes a socket control message that contains an
// integer array of open file descriptors from another process.
func ParseUnixRights(msg *SocketControlMessage) ([]int, error) {
if msg.Header.Level != SOL_SOCKET {
return nil, EINVAL
}
if msg.Header.Type != SCM_RIGHTS {
return nil, EINVAL
}
fds := make([]int, len(msg.Data)>>2)
for i, j := 0, 0; i < len(msg.Data); i += 4 {
fds[j] = int(*(*int32)(unsafe.Pointer(&msg.Data[i])))
j++
}
return fds, nil
}
/libcall_linux_amd64.go
0,0 → 1,13
// Copyright 2012 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.
 
// GNU/Linux library calls amd64 specific.
 
package syscall
 
//sys Ioperm(from int, num int, on int) (err error)
//ioperm(from _C_long, num _C_long, on int) int
 
//sys Iopl(level int) (err error)
//iopl(level int) int
/syscall_errno.go
0,0 → 1,26
// 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.
 
package syscall
 
// An Errno is an unsigned number describing an error condition.
// It implements the error interface. The zero Errno is by convention
// a non-error, so code to convert from Errno to error should use:
// err = nil
// if errno != 0 {
// err = errno
// }
type Errno uintptr
 
func (e Errno) Error() string {
return Errstr(int(e))
}
 
func (e Errno) Temporary() bool {
return e == EINTR || e == EMFILE || e.Timeout()
}
 
func (e Errno) Timeout() bool {
return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
}
/mksyscall.awk
0,0 → 1,264
# Copyright 2011 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.
 
# This AWK script reads a Go file with comments describing syscall
# functions and the C routines they map to. It generates the Go code
# which calls the C routines.
 
# The syscall functins are marked by lines beginning with "//sys" and
# read like func declarations if //sys is replaced by func, but:
# * The parameter lists must give a name for each argument.
# This includes return parameters.
# * The parameter lists must give a type for each argument:
# the (x, y, z int) shorthand is not allowed.
# * If the return parameter is an error, it must be named err.
 
# A line beginning with //sysnb is like //sys, except that the
# goroutine will not be suspended during the execution of the library
# call. This must only be used for library calls which can never
# block, as otherwise the library call could cause all goroutines to
# hang.
 
# After the //sys or //sysnb line comes a second line which describes
# the C function. The name must be the name of the function in the C
# library, and may be the same as the Go function. The limitations on
# the argument list are the same as for the //sys line, but there must
# be at most one result parameter, and it must be given as just a
# type, without a name.
 
BEGIN {
print "// This file was automatically generated by mksyscall.awk"
print ""
print "package syscall"
print ""
print "import \"unsafe\""
print ""
status = 0
}
 
/^\/\/sys/ {
if ($1 == "//sysnb") {
blocking = 0
} else {
blocking = 1
}
 
line = $0
 
if (match(line, "//sys(nb)?[ ]*[a-zA-Z0-9_]+\\([^()]*\\) *(\\(([^()]+)\\))?") == 0) {
print "unmatched line:", $0 | "cat 1>&2"
status = 1
next
}
 
# Sets a[1] = //sysnb, a[2] == function name.
split(line, a, "[ (]*")
gofnname = a[2]
 
off = match(line, "\\([^()]*\\)")
end = index(substr(line, off, length(line) - off + 1), ")")
gofnparams = substr(line, off + 1, end - 2)
 
line = substr(line, off + end, length(line) - (off + end) + 1)
off = match(line, "\\([^()]*\\)")
if (off == 0) {
gofnresults = ""
} else {
end = index(substr(line, off, length(line) - off + 1), ")")
gofnresults = substr(line, off + 1, end - 2)
}
 
getline
line = $0
 
if (match(line, "//[a-zA-Z0-9_]+\\([^()]*\\)") == 0) {
print "unmatched C line", $0, "after", gofnname | "cat 1>&2"
status = 1
next
}
 
split(line, a, "[ (]*")
cfnname = substr(a[1], 3, length(a[1]) - 2)
 
off = match(line, "\\([^()]*\\)")
end = index(substr(line, off, length(line) - off + 1), ")")
cfnparams = substr(line, off + 1, end - 2)
 
line = substr(line, off + end + 1, length(line) - (off + end) + 1)
while (substr(line, 1, 1) == " ") {
line = substr(line, 2, length(line) - 1)
}
end = index(line, " ")
if (end != 0) {
line = substr(line, 1, end)
}
cfnresult = line
 
printf("// Automatically generated wrapper for %s/%s\n", gofnname, cfnname)
printf("//extern %s\n", cfnname)
printf("func c_%s(%s) %s\n", cfnname, cfnparams, cfnresult)
printf("func %s(%s) %s%s%s%s{\n",
gofnname, gofnparams, gofnresults == "" ? "" : "(", gofnresults,
gofnresults == "" ? "" : ")", gofnresults == "" ? "" : " ")
 
loc = gofnname "/" cfnname ":"
 
split(gofnparams, goargs, ", *")
split(cfnparams, cargs, ", *")
args = ""
carg = 1
for (goarg = 1; goargs[goarg] != ""; goarg++) {
if (cargs[carg] == "") {
print loc, "not enough C parameters"
}
 
if (args != "") {
args = args ", "
}
 
if (split(goargs[goarg], a) != 2) {
print loc, "bad parameter:", goargs[goarg] | "cat 1>&2"
status = 1
next
}
 
goname = a[1]
gotype = a[2]
 
if (split(cargs[carg], a) != 2) {
print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
status = 1
next
}
 
ctype = a[2]
 
if (gotype ~ /^\*/) {
if (gotype != ctype) {
print loc, "Go/C pointer type mismatch:", gotype, ctype | "cat 1>&2"
status = 1
next
}
args = args goname
} else if (gotype == "string") {
if (ctype != "*byte") {
print loc, "Go string not matched to C *byte:", gotype, ctype | "cat 1>&2"
status = 1
next
}
printf("\t_p%d := StringBytePtr(%s)\n", goarg, goname)
args = sprintf("%s_p%d", args, goarg)
} else if (gotype ~ /^\[\](.*)/) {
if (ctype !~ /^\*/ || cargs[carg + 1] == "") {
print loc, "bad C type for slice:", gotype, ctype | "cat 1>&2"
status = 1
next
}
 
# Convert a slice into a pair of pointer, length.
# Don't try to take the address of the zeroth element of a
# nil slice.
printf("\tvar _p%d %s\n", goarg, ctype)
printf("\tif len(%s) > 0 {\n", goname)
printf("\t\t_p%d = (%s)(unsafe.Pointer(&%s[0]))\n", goarg, ctype, goname)
printf("\t} else {\n")
printf("\t\t_p%d = (%s)(unsafe.Pointer(&_zero))\n", goarg, ctype)
printf("\t}\n")
 
++carg
if (split(cargs[carg], cparam) != 2) {
print loc, "bad C parameter:", cargs[carg] | "cat 1>&2"
status = 1
next
}
 
args = sprintf("%s_p%d, %s(len(%s))", args, goarg, cparam[2], goname)
} else if (gotype == "uintptr" && ctype ~ /^\*/) {
args = sprintf("%s(%s)(unsafe.Pointer(%s))", args, ctype, goname)
} else {
args = sprintf("%s%s(%s)", args, ctype, goname)
}
 
carg++
}
 
if (cargs[carg] != "") {
print loc, "too many C parameters" | "cat 1>&2"
status = 1
next
}
 
if (blocking) {
print "\tentersyscall()"
}
 
printf("\t")
if (gofnresults != "") {
printf("_r := ")
}
printf("c_%s(%s)\n", cfnname, args)
 
if (gofnresults != "") {
fields = split(gofnresults, goresults, ", *")
if (fields > 2) {
print loc, "too many Go results" | "cat 1>&2"
status = 1
next
}
usedr = 0
for (goresult = 1; goresults[goresult] != ""; goresult++) {
if (split(goresults[goresult], goparam) != 2) {
print loc, "bad result:", goresults[goresult] | "cat 1>&2"
status = 1
next
}
 
goname = goparam[1]
gotype = goparam[2]
 
if (goname == "err") {
if (cfnresult ~ /^\*/) {
print "\tif _r == nil {"
} else {
print "\tif _r < 0 {"
}
print "\t\terr = GetErrno()"
print "\t}"
} else if (gotype == "uintptr" && cfnresult ~ /^\*/) {
printf("\t%s = (%s)(unsafe.Pointer(_r))\n", goname, gotype)
} else {
if (usedr) {
print loc, "two parameters but no errno parameter" | "cat 1>&2"
status = 1
next
}
printf("\t%s = (%s)(_r)\n", goname, gotype)
usedr = 1
}
}
}
 
if (blocking) {
print "\texitsyscall()"
}
 
if (gofnresults != "") {
print "\treturn"
}
 
print "}"
 
print ""
 
next
}
 
{ next }
 
END {
if (status != 0) {
print "*** mksyscall.awk failed" | "cat 1>&2"
exit status
}
}
/socket_bsd.go
0,0 → 1,78
// socket_bsd.go -- Socket handling specific to *BSD based systems.
 
// Copyright 2010 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.
 
package syscall
 
const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 28
const SizeofSockaddrUnix = 110
 
type RawSockaddrInet4 struct {
Len uint8;
Family uint8;
Port uint16;
Addr [4]byte /* in_addr */;
Zero [8]uint8;
}
 
func (sa *RawSockaddrInet4) setLen() Socklen_t {
sa.Len = SizeofSockaddrInet4
return SizeofSockaddrInet4
}
 
type RawSockaddrInet6 struct {
Len uint8;
Family uint8;
Port uint16;
Flowinfo uint32;
Addr [16]byte /* in6_addr */;
Scope_id uint32;
}
 
func (sa *RawSockaddrInet6) setLen() Socklen_t {
sa.Len = SizeofSockaddrInet6
return SizeofSockaddrInet6
}
 
type RawSockaddrUnix struct {
Len uint8;
Family uint8;
Path [108]int8;
}
 
func (sa *RawSockaddrUnix) setLen(n int) {
sa.Len = uint8(3 + n) // 2 for Family, Len; 1 for NUL.
}
 
func (sa *RawSockaddrUnix) getLen() (int, error) {
if sa.Len < 3 || sa.Len > SizeofSockaddrUnix {
return 0, EINVAL
}
n := int(sa.Len) - 3 // subtract leading Family, Len, terminating NUL.
for i := 0; i < n; i++ {
if sa.Path[i] == 0 {
// found early NUL; assume Len is overestimating.
n = i
break
}
}
return n, nil
}
 
type RawSockaddr struct {
Len uint8;
Family uint8;
Data [14]int8;
}
 
// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) (err error) {
return ENOSYS
}
 
func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
return nil, EAFNOSUPPORT
}
/libcall_linux_386.go
0,0 → 1,13
// Copyright 2012 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.
 
// GNU/Linux library calls 386 specific.
 
package syscall
 
//sys Ioperm(from int, num int, on int) (err error)
//ioperm(from _C_long, num _C_long, on int) int
 
//sys Iopl(level int) (err error)
//iopl(level int) int
/wait.c
0,0 → 1,104
/* wait.c -- functions for getting wait status values.
 
Copyright 2011 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.
 
We use C code to extract the wait status so that we can easily be
OS-independent. */
 
#include <stdint.h>
#include <sys/wait.h>
 
extern _Bool Exited (uint32_t *w)
__asm__ ("libgo_syscall.syscall.Exited.N32_libgo_syscall.syscall.WaitStatus");
 
_Bool
Exited (uint32_t *w)
{
return WIFEXITED (*w) != 0;
}
 
extern _Bool Signaled (uint32_t *w)
__asm__ ("libgo_syscall.syscall.Signaled.N32_libgo_syscall.syscall.WaitStatus");
 
_Bool
Signaled (uint32_t *w)
{
return WIFSIGNALED (*w) != 0;
}
 
extern _Bool Stopped (uint32_t *w)
__asm__ ("libgo_syscall.syscall.Stopped.N32_libgo_syscall.syscall.WaitStatus");
 
_Bool
Stopped (uint32_t *w)
{
return WIFSTOPPED (*w) != 0;
}
 
extern _Bool Continued (uint32_t *w)
__asm__ ("libgo_syscall.syscall.Continued.N32_libgo_syscall.syscall.WaitStatus");
 
_Bool
Continued (uint32_t *w)
{
return WIFCONTINUED (*w) != 0;
}
 
extern _Bool CoreDump (uint32_t *w)
__asm__ ("libgo_syscall.syscall.CoreDump.N32_libgo_syscall.syscall.WaitStatus");
 
_Bool
CoreDump (uint32_t *w)
{
return WCOREDUMP (*w) != 0;
}
 
extern int ExitStatus (uint32_t *w)
__asm__ ("libgo_syscall.syscall.ExitStatus.N32_libgo_syscall.syscall.WaitStatus");
 
int
ExitStatus (uint32_t *w)
{
if (!WIFEXITED (*w))
return -1;
return WEXITSTATUS (*w);
}
 
extern int Signal (uint32_t *w)
__asm__ ("libgo_syscall.syscall.Signal.N32_libgo_syscall.syscall.WaitStatus");
 
int
Signal (uint32_t *w)
{
if (!WIFSIGNALED (*w))
return -1;
return WTERMSIG (*w);
}
 
extern int StopSignal (uint32_t *w)
__asm__ ("libgo_syscall.syscall.StopSignal.N32_libgo_syscall.syscall.WaitStatus");
 
int
StopSignal (uint32_t *w)
{
if (!WIFSTOPPED (*w))
return -1;
return WSTOPSIG (*w);
}
 
extern int TrapCause (uint32_t *w)
__asm__ ("libgo_syscall.syscall.TrapCause.N32_libgo_syscall.syscall.WaitStatus");
 
int
TrapCause (uint32_t *w __attribute__ ((unused)))
{
#ifndef __linux__
return -1;
#else
if (!WIFSTOPPED (*w) || WSTOPSIG (*w) != SIGTRAP)
return -1;
return *w >> 16;
#endif
}
/sleep_rtems.go
0,0 → 1,13
// sleep_rtems.go -- Sleep on RTEMS.
 
// Copyright 2010 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.
 
package syscall
 
func Sleep(nsec int64) (err error) {
ts := NsecToTimespec(nsec)
err = Nanosleep(&ts, nil)
return
}
/socket_irix.go
0,0 → 1,130
// socket_irix.go -- Socket handling specific to IRIX 6.
 
// Copyright 2011 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.
 
package syscall
 
const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 28
const SizeofSockaddrUnix = 110
 
type RawSockaddrInet4 struct {
Family uint16
Port uint16
Addr [4]byte /* in_addr */
Zero [8]uint8
}
 
func (sa *RawSockaddrInet4) setLen() Socklen_t {
return SizeofSockaddrInet4
}
 
type RawSockaddrInet6 struct {
Family uint16
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
 
func (sa *RawSockaddrInet6) setLen() Socklen_t {
return SizeofSockaddrInet6
}
 
type RawSockaddrUnix struct {
Family uint16
Path [108]int8
}
 
func (sa *RawSockaddrUnix) setLen(int) {
}
 
func (sa *RawSockaddrUnix) getLen() (int, error) {
if sa.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.
sa.Path[0] = '@'
}
 
// Assume path ends at NUL.
// This is not technically the GNU/Linux semantics for
// abstract Unix domain sockets--they are supposed
// to be uninterpreted fixed-size binary blobs--but
// everyone uses this convention.
n := 0
for n < len(sa.Path)-3 && sa.Path[n] != 0 {
n++
}
 
return n, nil
}
 
type RawSockaddr struct {
Family uint16
Data [14]int8
}
 
// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) (err error) {
return ENOSYS
}
 
// <netdb.h> only provides struct addrinfo, AI_* and EAI_* if _NO_XOPEN4
// && _NO_XOPEN5, but -D_XOPEN_SOURCE=500 is required for msg_control etc.
// in struct msghgr, so simply provide them here.
type Addrinfo struct {
Ai_flags int32
Ai_family int32
Ai_socktype int32
Ai_protocol int32
Ai_addrlen int32
Ai_canonname *uint8
Ai_addr *_sockaddr
Ai_next *Addrinfo
}
 
const (
AI_PASSIVE = 0x00000001
AI_CANONNAME = 0x00000002
AI_NUMERICHOST = 0x00000004
AI_NUMERICSERV = 0x00000008
AI_ALL = 0x00000100
AI_ADDRCONFIG = 0x00000400
AI_V4MAPPED = 0x00000800
AI_DEFAULT = (AI_V4MAPPED | AI_ADDRCONFIG)
)
 
const (
EAI_ADDRFAMILY = 1
EAI_AGAIN = 2
EAI_BADFLAGS = 3
EAI_FAIL = 4
EAI_FAMILY = 5
EAI_MEMORY = 6
EAI_NODATA = 7
EAI_NONAME = 8
EAI_SERVICE = 9
EAI_SOCKTYPE = 10
EAI_SYSTEM = 11
EAI_BADHINTS = 12
EAI_OVERFLOW = 13
EAI_MAX = 14
)
 
func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
return nil, EAFNOSUPPORT
}
 
// <netinet/in.h.h> only provides IPV6_* etc. if _NO_XOPEN4 && _NO_XOPEN5,
// so as above simply provide them here.
const (
IPV6_UNICAST_HOPS = 48
IPV6_MULTICAST_IF = IP_MULTICAST_IF
IPV6_MULTICAST_HOPS = IP_MULTICAST_TTL
IPV6_MULTICAST_LOOP = IP_MULTICAST_LOOP
)
/socket_solaris.go
0,0 → 1,80
// socket_solaris.go -- Socket handling specific to Solaris.
 
// Copyright 2010 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.
 
package syscall
 
const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 32
const SizeofSockaddrUnix = 110
 
type RawSockaddrInet4 struct {
Family uint16
Port uint16
Addr [4]byte /* in_addr */
Zero [8]uint8
}
 
func (sa *RawSockaddrInet4) setLen() Socklen_t {
return SizeofSockaddrInet4
}
 
type RawSockaddrInet6 struct {
Family uint16
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
Src_id uint32
}
 
func (sa *RawSockaddrInet6) setLen() Socklen_t {
return SizeofSockaddrInet6
}
 
type RawSockaddrUnix struct {
Family uint16
Path [108]int8
}
 
func (sa *RawSockaddrUnix) setLen(int) {
}
 
func (sa *RawSockaddrUnix) getLen() (int, error) {
if sa.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.
sa.Path[0] = '@'
}
 
// Assume path ends at NUL.
// This is not technically the GNU/Linux semantics for
// abstract Unix domain sockets--they are supposed
// to be uninterpreted fixed-size binary blobs--but
// everyone uses this convention.
n := 0
for n < len(sa.Path) - 3 && sa.Path[n] != 0 {
n++
}
 
return n, nil
}
 
type RawSockaddr struct {
Family uint16
Data [14]int8
}
 
// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) (err error) {
return ENOSYS
}
 
func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
return nil, EAFNOSUPPORT
}
/libcall_posix.go
0,0 → 1,384
// Copyright 2011 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.
 
// POSIX library calls.
// This file is compiled as ordinary Go code,
// but it is also input to mksyscall,
// which parses the //sys lines and generates library call stubs.
// Note that sometimes we use a lowercase //sys name and
// wrap it in our own nicer implementation.
 
package syscall
 
import "unsafe"
 
/*
* Wrapped
*/
 
//sysnb pipe(p *[2]int) (err error)
//pipe(p *[2]int) int
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]int
err = pipe(&pp)
p[0] = pp[0]
p[1] = pp[1]
return
}
 
//sys utimes(path string, times *[2]Timeval) (err error)
//utimes(path *byte, times *[2]Timeval) int
func Utimes(path string, tv []Timeval) (err error) {
if len(tv) != 2 {
return EINVAL
}
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
}
 
//sys getcwd(buf *byte, size Size_t) (err error)
//getcwd(buf *byte, size Size_t) *byte
 
const ImplementsGetwd = true
 
func Getwd() (ret string, err error) {
for len := Size_t(4096); ; len *= 2 {
b := make([]byte, len)
err := getcwd(&b[0], len)
if err == nil {
i := 0
for b[i] != 0 {
i++
}
return string(b[0:i]), nil
}
if err != ERANGE {
return "", err
}
}
}
 
//sysnb getgroups(size int, list *Gid_t) (nn int, err error)
//getgroups(size int, list *Gid_t) int
 
func Getgroups() (gids []int, err error) {
n, err := getgroups(0, nil)
if err != nil {
return nil, err
}
if n == 0 {
return nil, nil
}
 
// Sanity check group count. Max is 1<<16 on GNU/Linux.
if n < 0 || n > 1<<20 {
return nil, EINVAL
}
 
a := make([]Gid_t, n)
n, err = getgroups(n, &a[0])
if err != nil {
return nil, err
}
gids = make([]int, n)
for i, v := range a[0:n] {
gids[i] = int(v)
}
return
}
 
//sysnb setgroups(n int, list *Gid_t) (err error)
//setgroups(n Size_t, list *Gid_t) int
 
func Setgroups(gids []int) (err error) {
if len(gids) == 0 {
return setgroups(0, nil)
}
 
a := make([]Gid_t, len(gids))
for i, v := range gids {
a[i] = Gid_t(v)
}
return setgroups(len(a), &a[0])
}
 
type WaitStatus uint32
 
// The WaitStatus methods are implemented in C, to pick up the macros
// #defines in <sys/wait.h>.
 
func (w WaitStatus) Exited() bool
func (w WaitStatus) Signaled() bool
func (w WaitStatus) Stopped() bool
func (w WaitStatus) Continued() bool
func (w WaitStatus) CoreDump() bool
func (w WaitStatus) ExitStatus() int
func (w WaitStatus) Signal() int
func (w WaitStatus) StopSignal() int
func (w WaitStatus) TrapCause() int
 
//sys Mkfifo(path string, mode uint32) (err error)
//mkfifo(path *byte, mode Mode_t) int
 
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) int
 
const nfdbits = unsafe.Sizeof(fds_bits_type) * 8
 
type FdSet struct {
Bits [(FD_SETSIZE + nfdbits - 1) / nfdbits]fds_bits_type
}
 
func FDSet(fd int, set *FdSet) {
set.Bits[fd/nfdbits] |= (1 << (uint)(fd%nfdbits))
}
 
func FDClr(fd int, set *FdSet) {
set.Bits[fd/nfdbits] &^= (1 << (uint)(fd%nfdbits))
}
 
func FDIsSet(fd int, set *FdSet) bool {
if set.Bits[fd/nfdbits]&(1<<(uint)(fd%nfdbits)) != 0 {
return true
} else {
return false
}
}
 
func FDZero(set *FdSet) {
for i := range set.Bits {
set.Bits[i] = 0
}
}
 
//sys Access(path string, mode uint32) (err error)
//access(path *byte, mode int) int
 
//sys Chdir(path string) (err error)
//chdir(path *byte) int
 
//sys Chmod(path string, mode uint32) (err error)
//chmod(path *byte, mode Mode_t) int
 
//sys Chown(path string, uid int, gid int) (err error)
//chown(path *byte, uid Uid_t, gid Gid_t) int
 
//sys Chroot(path string) (err error)
//chroot(path *byte) int
 
//sys Close(fd int) (err error)
//close(fd int) int
 
//sys Creat(path string, mode uint32) (fd int, err error)
//creat(path *byte, mode Mode_t) int
 
//sysnb Dup(oldfd int) (fd int, err error)
//dup(oldfd int) int
 
//sysnb Dup2(oldfd int, newfd int) (err error)
//dup2(oldfd int, newfd int) int
 
//sys Exit(code int)
//exit(code int)
 
//sys Fchdir(fd int) (err error)
//fchdir(fd int) int
 
//sys Fchmod(fd int, mode uint32) (err error)
//fchmod(fd int, mode Mode_t) int
 
//sys Fchown(fd int, uid int, gid int) (err error)
//fchown(fd int, uid Uid_t, gid Gid_t) int
 
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//fcntl(fd int, cmd int, arg int) int
 
//sys Fdatasync(fd int) (err error)
//fdatasync(fd int) int
 
//sys Fsync(fd int) (err error)
//fsync(fd int) int
 
//sysnb Getegid() (egid int)
//getegid() Gid_t
 
//sysnb Geteuid() (euid int)
//geteuid() Uid_t
 
//sysnb Getgid() (gid int)
//getgid() Gid_t
 
//sysnb Getpagesize() (pagesize int)
//getpagesize() int
 
//sysnb Getpgid(pid int) (pgid int, err error)
//getpgid(pid Pid_t) Pid_t
 
//sysnb Getpgrp() (pid int)
//getpgrp() Pid_t
 
//sysnb Getpid() (pid int)
//getpid() Pid_t
 
//sysnb Getppid() (ppid int)
//getppid() Pid_t
 
// FIXME: mksysinfo Rlimit
// //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
// //getrlimit(resource int, rlim *Rlimit) int
 
//sysnb Getrusage(who int, rusage *Rusage) (err error)
//getrusage(who int, rusage *Rusage) int
 
//sysnb gettimeofday(tv *Timeval, tz *byte) (err error)
//gettimeofday(tv *Timeval, tz *byte) int
func Gettimeofday(tv *Timeval) (err error) {
return gettimeofday(tv, nil)
}
 
//sysnb Getuid() (uid int)
//getuid() Uid_t
 
//sysnb Kill(pid int, sig int) (err error)
//kill(pid Pid_t, sig int) int
 
//sys Lchown(path string, uid int, gid int) (err error)
//lchown(path *byte, uid Uid_t, gid Gid_t) int
 
//sys Link(oldpath string, newpath string) (err error)
//link(oldpath *byte, newpath *byte) int
 
//sys Mkdir(path string, mode uint32) (err error)
//mkdir(path *byte, mode Mode_t) int
 
//sys Mknod(path string, mode uint32, dev int) (err error)
//mknod(path *byte, mode Mode_t, dev _dev_t) int
 
//sys Mount(source string, target string, fstype string, flags int, data string) (err error)
//mount(source *byte, target *byte, fstype *byte, flags _C_long, data *byte) int
 
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//nanosleep(time *Timespec, leftover *Timespec) int
 
//sys Pause() (err error)
//pause() int
 
//sys Read(fd int, p []byte) (n int, err error)
//read(fd int, buf *byte, count Size_t) Ssize_t
 
//sys Readlink(path string, buf []byte) (n int, err error)
//readlink(path *byte, buf *byte, bufsiz Size_t) Ssize_t
 
//sys Rename(oldpath string, newpath string) (err error)
//rename(oldpath *byte, newpath *byte) int
 
//sys Rmdir(path string) (err error)
//rmdir(path *byte) int
 
//sys Setdomainname(p []byte) (err error)
//setdomainname(name *byte, len Size_t) int
 
//sys Sethostname(p []byte) (err error)
//sethostname(name *byte, len Size_t) int
 
//sysnb Setgid(gid int) (err error)
//setgid(gid Gid_t) int
 
//sysnb Setregid(rgid int, egid int) (err error)
//setregid(rgid Gid_t, egid Gid_t) int
 
//sysnb Setpgid(pid int, pgid int) (err error)
//setpgid(pid Pid_t, pgid Pid_t) int
 
//sysnb Setreuid(ruid int, euid int) (err error)
//setreuid(ruid Uid_t, euid Uid_t) int
 
// FIXME: mksysinfo Rlimit
// //sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
// //setrlimit(resource int, rlim *Rlimit) int
 
//sysnb Setsid() (pid int, err error)
//setsid() Pid_t
 
//sysnb settimeofday(tv *Timeval, tz *byte) (err error)
//settimeofday(tv *Timeval, tz *byte) int
 
func Settimeofday(tv *Timeval) (err error) {
return settimeofday(tv, nil)
}
 
//sysnb Setuid(uid int) (err error)
//setuid(uid Uid_t) int
 
//sys Symlink(oldpath string, newpath string) (err error)
//symlink(oldpath *byte, newpath *byte) int
 
//sys Sync()
//sync()
 
// FIXME: mksysinfo Time_t
// //sysnb Time(t *Time_t) (tt Time_t, err error)
// //time(t *Time_t) Time_t
 
//sysnb Times(tms *Tms) (ticks uintptr, err error)
//times(tms *Tms) _clock_t
 
//sysnb Umask(mask int) (oldmask int)
//umask(mask Mode_t) Mode_t
 
//sys Unlink(path string) (err error)
//unlink(path *byte) int
 
// FIXME: mksysinfo Utimbuf
// //sys Utime(path string, buf *Utimbuf) (err error)
// //utime(path *byte, buf *Utimbuf) int
 
//sys Write(fd int, p []byte) (n int, err error)
//write(fd int, buf *byte, count Size_t) Ssize_t
 
//sys munmap(addr uintptr, length uintptr) (err error)
//munmap(addr *byte, length Size_t) int
 
//sys Madvise(b []byte, advice int) (err error)
//madvise(addr *byte, len Size_t, advice int) int
 
//sys Mprotect(b []byte, prot int) (err error)
//mprotect(addr *byte, len Size_t, prot int) int
 
//sys Mlock(b []byte) (err error)
//mlock(addr *byte, len Size_t) int
 
//sys Munlock(b []byte) (err error)
//munlock(addr *byte, len Size_t) int
 
//sys Mlockall(flags int) (err error)
//mlockall(flags int) int
 
//sys Munlockall() (err error)
//munlockall() int
 
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
 
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = Timespec_sec_t(nsec / 1e9)
ts.Nsec = Timespec_nsec_t(nsec % 1e9)
return
}
 
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
 
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = Timeval_sec_t(nsec / 1e9)
tv.Usec = Timeval_usec_t(nsec % 1e9 / 1e3)
return
}
 
//sysnb Tcgetattr(fd int, p *Termios) (err error)
//tcgetattr(fd int, p *Termios) int
 
//sys Tcsetattr(fd int, actions int, p *Termios) (err error)
//tcsetattr(fd int, actions int, p *Termios) int
/libcall_solaris_sparc.go
0,0 → 1,8
// Copyright 2011 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.
 
package syscall
 
//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
//ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
/libcall_linux_alpha.go
0,0 → 1,13
// Copyright 2012 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.
 
// GNU/Linux library calls Alpha specific.
 
package syscall
 
//sys Ioperm(from int, num int, on int) (err error)
//ioperm(from _C_long, num _C_long, on int) int
 
//sys Iopl(level int) (err error)
//iopl(level int) int
/exec_unix.go
0,0 → 1,261
// 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.
 
// +build darwin freebsd linux netbsd openbsd
 
// Fork, exec, wait, etc.
 
package syscall
 
import (
"runtime"
"sync"
"unsafe"
)
 
//sysnb raw_fork() (pid Pid_t, err Errno)
//fork() Pid_t
 
//sysnb raw_setsid() (err Errno)
//setsid() Pid_t
 
//sysnb raw_setpgid(pid int, pgid int) (err Errno)
//setpgid(pid Pid_t, pgid Pid_t) int
 
//sysnb raw_chroot(path *byte) (err Errno)
//chroot(path *byte) int
 
//sysnb raw_chdir(path *byte) (err Errno)
//chdir(path *byte) int
 
//sysnb raw_fcntl(fd int, cmd int, arg int) (val int, err Errno)
//fcntl(fd int, cmd int, arg int) int
 
//sysnb raw_close(fd int) (err Errno)
//close(fd int) int
 
//sysnb raw_ioctl(fd int, cmd int, val int) (rval int, err Errno)
//ioctl(fd int, cmd int, val int) int
 
//sysnb raw_execve(argv0 *byte, argv **byte, envv **byte) (err Errno)
//execve(argv0 *byte, argv **byte, envv **byte) int
 
//sysnb raw_write(fd int, buf *byte, count int) (err Errno)
//write(fd int, buf *byte, count Size_t) Ssize_t
 
//sysnb raw_exit(status int)
//_exit(status int)
 
//sysnb raw_dup2(oldfd int, newfd int) (err Errno)
//dup2(oldfd int, newfd int) int
 
// Note: not raw, returns error rather than Errno.
//sys read(fd int, p *byte, np int) (n int, err error)
//read(fd int, buf *byte, count Size_t) Ssize_t
 
// Lock synchronizing creation of new file descriptors with fork.
//
// We want the child in a fork/exec sequence to inherit only the
// file descriptors we intend. To do that, we mark all file
// descriptors close-on-exec and then, in the child, explicitly
// unmark the ones we want the exec'ed program to keep.
// Unix doesn't make this easy: there is, in general, no way to
// allocate a new file descriptor close-on-exec. Instead you
// have to allocate the descriptor and then mark it close-on-exec.
// If a fork happens between those two events, the child's exec
// will inherit an unwanted file descriptor.
//
// This lock solves that race: the create new fd/mark close-on-exec
// operation is done holding ForkLock for reading, and the fork itself
// is done holding ForkLock for writing. At least, that's the idea.
// There are some complications.
//
// Some system calls that create new file descriptors can block
// for arbitrarily long times: open on a hung NFS server or named
// pipe, accept on a socket, and so on. We can't reasonably grab
// the lock across those operations.
//
// It is worse to inherit some file descriptors than others.
// If a non-malicious child accidentally inherits an open ordinary file,
// that's not a big deal. On the other hand, if a long-lived child
// accidentally inherits the write end of a pipe, then the reader
// of that pipe will not see EOF until that child exits, potentially
// causing the parent program to hang. This is a common problem
// in threaded C programs that use popen.
//
// Luckily, the file descriptors that are most important not to
// inherit are not the ones that can take an arbitrarily long time
// to create: pipe returns instantly, and the net package uses
// non-blocking I/O to accept on a listening socket.
// The rules for which file descriptor-creating operations use the
// ForkLock are as follows:
//
// 1) Pipe. Does not block. Use the ForkLock.
// 2) Socket. Does not block. Use the ForkLock.
// 3) Accept. If using non-blocking mode, use the ForkLock.
// Otherwise, live with the race.
// 4) Open. Can block. Use O_CLOEXEC if available (GNU/Linux).
// Otherwise, live with the race.
// 5) Dup. Does not block. Use the ForkLock.
// On GNU/Linux, could use fcntl F_DUPFD_CLOEXEC
// instead of the ForkLock, but only for dup(fd, -1).
 
var ForkLock sync.RWMutex
 
// Convert array of string to array
// of NUL-terminated byte pointer.
func StringSlicePtr(ss []string) []*byte {
bb := make([]*byte, len(ss)+1)
for i := 0; i < len(ss); i++ {
bb[i] = StringBytePtr(ss[i])
}
bb[len(ss)] = nil
return bb
}
 
func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
 
func SetNonblock(fd int, nonblocking bool) (err error) {
flag, err := fcntl(fd, F_GETFL, 0)
if err != nil {
return err
}
if nonblocking {
flag |= O_NONBLOCK
} else {
flag &= ^O_NONBLOCK
}
_, err = fcntl(fd, F_SETFL, flag)
return err
}
 
// Credential holds user and group identities to be assumed
// by a child process started by StartProcess.
type Credential struct {
Uid uint32 // User ID.
Gid uint32 // Group ID.
Groups []uint32 // Supplementary group IDs.
}
 
// ProcAttr holds attributes that will be applied to a new process started
// by StartProcess.
type ProcAttr struct {
Dir string // Current working directory.
Env []string // Environment.
Files []int // File descriptors.
Sys *SysProcAttr
}
 
var zeroProcAttr ProcAttr
var zeroSysProcAttr SysProcAttr
 
func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
var p [2]int
var n int
var err1 Errno
var wstatus WaitStatus
 
if attr == nil {
attr = &zeroProcAttr
}
sys := attr.Sys
if sys == nil {
sys = &zeroSysProcAttr
}
 
p[0] = -1
p[1] = -1
 
// Convert args to C form.
argv0p := StringBytePtr(argv0)
argvp := StringSlicePtr(argv)
envvp := StringSlicePtr(attr.Env)
 
if runtime.GOOS == "freebsd" && len(argv[0]) > len(argv0) {
argvp[0] = argv0p
}
 
var chroot *byte
if sys.Chroot != "" {
chroot = StringBytePtr(sys.Chroot)
}
var dir *byte
if attr.Dir != "" {
dir = StringBytePtr(attr.Dir)
}
 
// Acquire the fork lock so that no other threads
// create new fds that are not yet close-on-exec
// before we fork.
ForkLock.Lock()
 
// Allocate child status pipe close on exec.
if err = Pipe(p[0:]); err != nil {
goto error
}
if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
goto error
}
if _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC); err != nil {
goto error
}
 
// Kick off child.
pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
if err1 != 0 {
goto error
}
ForkLock.Unlock()
 
// Read child error status from pipe.
Close(p[1])
n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
Close(p[0])
if err != nil || n != 0 {
if n == int(unsafe.Sizeof(err1)) {
err = Errno(err1)
}
if err == nil {
err = EPIPE
}
 
// Child failed; wait for it to exit, to make sure
// the zombies don't accumulate.
_, err1 := Wait4(pid, &wstatus, 0, nil)
for err1 == EINTR {
_, err1 = Wait4(pid, &wstatus, 0, nil)
}
return 0, err
}
 
// Read got EOF, so pipe closed on exec, so exec succeeded.
return pid, nil
 
error:
if p[0] >= 0 {
Close(p[0])
Close(p[1])
}
ForkLock.Unlock()
return 0, err
}
 
// Combination of fork and exec, careful to be thread safe.
func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
return forkExec(argv0, argv, attr)
}
 
// StartProcess wraps ForkExec for package os.
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
pid, err = forkExec(argv0, argv, attr)
return pid, 0, err
}
 
// Ordinary exec.
func Exec(argv0 string, argv []string, envv []string) (err error) {
err1 := raw_execve(StringBytePtr(argv0),
&StringSlicePtr(argv)[0],
&StringSlicePtr(envv)[0])
return Errno(err1)
}
/sockcmsg_linux.go
0,0 → 1,38
// Copyright 2011 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.
 
// Socket control messages
 
package syscall
 
import (
"unsafe"
)
 
// UnixCredentials encodes credentials into a socket control message
// for sending to another process. This can be used for
// authentication.
func UnixCredentials(ucred *Ucred) []byte {
buf := make([]byte, CmsgSpace(SizeofUcred))
cmsg := (*Cmsghdr)(unsafe.Pointer(&buf[0]))
cmsg.Level = SOL_SOCKET
cmsg.Type = SCM_CREDENTIALS
cmsg.SetLen(CmsgLen(SizeofUcred))
*((*Ucred)(cmsgData(cmsg))) = *ucred
return buf
}
 
// ParseUnixCredentials decodes a socket control message that contains
// credentials in a Ucred structure. To receive such a message, the
// SO_PASSCRED option must be enabled on the socket.
func ParseUnixCredentials(msg *SocketControlMessage) (*Ucred, error) {
if msg.Header.Level != SOL_SOCKET {
return nil, EINVAL
}
if msg.Header.Type != SCM_CREDENTIALS {
return nil, EINVAL
}
ucred := *(*Ucred)(unsafe.Pointer(&msg.Data[0]))
return &ucred, nil
}
/libcall_solaris_amd64.go
0,0 → 1,10
// Copyright 2011 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.
 
package syscall
 
// 64-bit ptrace(3C) doesn't exist
func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
return ENOSYS
}
/env_plan9.go
0,0 → 1,128
// Copyright 2011 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.
 
// Plan 9 environment variables.
 
package syscall
 
import (
"errors"
"sync"
)
 
var (
// envOnce guards initialization by copyenv, which populates env.
envOnce sync.Once
 
// envLock guards env.
envLock sync.RWMutex
 
// env maps from an environment variable to its value.
env map[string]string
)
 
func readenv(key string) (string, error) {
fd, err := Open("/env/"+key, O_RDONLY)
if err != nil {
return "", err
}
defer Close(fd)
l, _ := Seek(fd, 0, 2)
Seek(fd, 0, 0)
buf := make([]byte, l)
n, err := Read(fd, buf)
if err != nil {
return "", err
}
if n > 0 && buf[n-1] == 0 {
buf = buf[:n-1]
}
return string(buf), nil
}
 
func writeenv(key, value string) error {
fd, err := Create("/env/"+key, O_RDWR, 0666)
if err != nil {
return err
}
defer Close(fd)
_, err = Write(fd, []byte(value))
return err
}
 
func copyenv() {
env = make(map[string]string)
fd, err := Open("/env", O_RDONLY)
if err != nil {
return
}
defer Close(fd)
files, err := readdirnames(fd)
if err != nil {
return
}
for _, key := range files {
v, err := readenv(key)
if err != nil {
continue
}
env[key] = v
}
}
 
func Getenv(key string) (value string, found bool) {
envOnce.Do(copyenv)
if len(key) == 0 {
return "", false
}
 
envLock.RLock()
defer envLock.RUnlock()
 
v, ok := env[key]
if !ok {
return "", false
}
return v, true
}
 
func Setenv(key, value string) error {
envOnce.Do(copyenv)
if len(key) == 0 {
return errors.New("zero length key")
}
 
envLock.Lock()
defer envLock.Unlock()
 
err := writeenv(key, value)
if err != nil {
return err
}
env[key] = value
return nil
}
 
func Clearenv() {
envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
 
envLock.Lock()
defer envLock.Unlock()
 
env = make(map[string]string)
RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
}
 
func Environ() []string {
envOnce.Do(copyenv)
envLock.RLock()
defer envLock.RUnlock()
a := make([]string, len(env))
i := 0
for k, v := range env {
a[i] = k + "=" + v
i++
}
return a
}
/route_netbsd.go
0,0 → 1,35
// Copyright 2011 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.
 
// Routing sockets and messages for NetBSD
 
package syscall
 
import (
"unsafe"
)
 
func (any *anyMessage) toRoutingMessage(buf []byte) RoutingMessage {
switch any.Type {
case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
p := (*RouteMessage)(unsafe.Pointer(any))
rtm := &RouteMessage{}
rtm.Header = p.Header
rtm.Data = buf[SizeofRtMsghdr:any.Msglen]
return rtm
case RTM_IFINFO:
p := (*InterfaceMessage)(unsafe.Pointer(any))
ifm := &InterfaceMessage{}
ifm.Header = p.Header
ifm.Data = buf[SizeofIfMsghdr:any.Msglen]
return ifm
case RTM_NEWADDR, RTM_DELADDR:
p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
ifam := &InterfaceAddrMessage{}
ifam.Header = p.Header
ifam.Data = buf[SizeofIfaMsghdr:any.Msglen]
return ifam
}
return nil
}
/libcall_solaris_386.go
0,0 → 1,12
// Copyright 2011 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.
 
package syscall
 
// 32-bit Solaris 2/x86 needs to use _nuname internally, cf. <sys/utsname.h>.
//sysnb Uname(buf *Utsname) (err error)
//_nuname(buf *Utsname) int
 
//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
//ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
/libcall_support.go
0,0 → 1,12
// Copyright 2011 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.
 
// Declarations for functions which are actually written in C.
 
package syscall
 
func entersyscall()
func exitsyscall()
func GetErrno() Errno
func SetErrno(Errno)
/errstr_nor.go
0,0 → 1,33
// errstr.go -- Error strings when there is no strerror_r.
 
// Copyright 2011 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.
 
package syscall
 
import (
"sync"
"unsafe"
)
 
//sysnb strerror(errnum int) (buf *byte)
//strerror(errnum int) *byte
 
var errstr_lock sync.Mutex
 
func Errstr(errno int) string {
errstr_lock.Lock()
 
bp := strerror(errno)
b := (*[1000]byte)(unsafe.Pointer(bp))
i := 0
for b[i] != 0 {
i++
}
s := string(b[:i])
 
errstr_lock.Unlock()
 
return s
}
/env_windows.go
0,0 → 1,77
// Copyright 2010 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.
 
// Windows environment variables.
 
package syscall
 
import (
"unicode/utf16"
"unsafe"
)
 
func Getenv(key string) (value string, found bool) {
b := make([]uint16, 100)
n, e := GetEnvironmentVariable(StringToUTF16Ptr(key), &b[0], uint32(len(b)))
if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
return "", false
}
if n > uint32(len(b)) {
b = make([]uint16, n)
n, e = GetEnvironmentVariable(StringToUTF16Ptr(key), &b[0], uint32(len(b)))
if n > uint32(len(b)) {
n = 0
}
}
if n == 0 {
return "", false
}
return string(utf16.Decode(b[0:n])), true
}
 
func Setenv(key, value string) error {
var v *uint16
if len(value) > 0 {
v = StringToUTF16Ptr(value)
}
e := SetEnvironmentVariable(StringToUTF16Ptr(key), v)
if e != nil {
return e
}
return nil
}
 
func Clearenv() {
for _, s := range Environ() {
// Environment variables can begin with =
// so start looking for the separator = at j=1.
// http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
for j := 1; j < len(s); j++ {
if s[j] == '=' {
Setenv(s[0:j], "")
break
}
}
}
}
 
func Environ() []string {
s, e := GetEnvironmentStrings()
if e != nil {
return nil
}
defer FreeEnvironmentStrings(s)
r := make([]string, 0, 50) // Empty with room to grow.
for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
if p[i] == 0 {
// empty string marks the end
if i <= from {
break
}
r = append(r, string(utf16.Decode(p[from:i])))
from = i + 1
}
}
return r
}
/exec_stubs.go
0,0 → 1,33
// Copyright 2010 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.
 
// Stubs for fork, exec and wait.
 
package syscall
 
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) {
return -1, ENOSYS
}
 
func Exec(argv0 string, argv []string, envv []string) (err int) {
return ENOSYS
}
 
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
return -1, ENOSYS
}
 
func (w WaitStatus) Exited() bool { return false }
func (w WaitStatus) Signaled() bool { return false }
func (w WaitStatus) Stopped() bool { return false }
func (w WaitStatus) Continued() bool { return false }
func (w WaitStatus) CoreDump() bool { return false }
func (w WaitStatus) ExitStatus() int { return 0 }
func (w WaitStatus) Signal() int { return 0 }
func (w WaitStatus) StopSignal() int { return 0 }
func (w WaitStatus) TrapCause() int { return 0 }
 
func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
return ENOSYS
}
/sleep_select.go
0,0 → 1,13
// sleep_select.go -- Sleep using select.
 
// Copyright 2011 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.
 
package syscall
 
func Sleep(nsec int64) (err error) {
tv := NsecToTimeval(nsec);
_, err = Select(0, nil, nil, nil, &tv);
return err;
}
/str.go
0,0 → 1,20
// 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.
 
package syscall
 
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
if val < 0 {
return "-" + itoa(-val)
}
var buf [32]byte // big enough for int64
i := len(buf) - 1
for val >= 10 {
buf[i] = byte(val%10 + '0')
i--
val /= 10
}
buf[i] = byte(val + '0')
return string(buf[i:])
}
/route_openbsd.go
0,0 → 1,35
// Copyright 2011 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.
 
// Routing sockets and messages for OpenBSD
 
package syscall
 
import (
"unsafe"
)
 
func (any *anyMessage) toRoutingMessage(buf []byte) RoutingMessage {
switch any.Type {
case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
p := (*RouteMessage)(unsafe.Pointer(any))
rtm := &RouteMessage{}
rtm.Header = p.Header
rtm.Data = buf[SizeofRtMsghdr:any.Msglen]
return rtm
case RTM_IFINFO:
p := (*InterfaceMessage)(unsafe.Pointer(any))
ifm := &InterfaceMessage{}
ifm.Header = p.Header
ifm.Data = buf[SizeofIfMsghdr:any.Msglen]
return ifm
case RTM_NEWADDR, RTM_DELADDR:
p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
ifam := &InterfaceAddrMessage{}
ifam.Header = p.Header
ifam.Data = buf[SizeofIfaMsghdr:any.Msglen]
return ifam
}
return nil
}
/libcall_wait4.go
0,0 → 1,20
// 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.
 
// For systems with the wait4 library call.
 
package syscall
 
//sys wait4(pid Pid_t, status *int, options int, rusage *Rusage) (wpid Pid_t, err error)
//wait4(pid Pid_t, status *int, options int, rusage *Rusage) Pid_t
 
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
var status int
r, err := wait4(Pid_t(pid), &status, options, rusage)
wpid = int(r)
if wstatus != nil {
*wstatus = WaitStatus(status)
}
return
}
/syscall_unix.go
0,0 → 1,165
// 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.
 
// +build darwin freebsd linux netbsd openbsd
 
package syscall
 
import (
"runtime"
"sync"
"unsafe"
)
 
var (
Stdin = 0
Stdout = 1
Stderr = 2
)
 
//extern syscall
func c_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32
 
//extern syscall
func c_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64
 
const darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"
 
// Do a system call. We look at the size of uintptr to see how to pass
// the arguments, so that we don't pass a 64-bit value when the function
// expects a 32-bit one.
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
entersyscall()
var r uintptr
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
r = uintptr(r1)
}
err = GetErrno()
exitsyscall()
return r, 0, err
}
 
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
entersyscall()
var r uintptr
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
int32(a4), int32(a5), int32(a6))
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
int64(a4), int64(a5), int64(a6))
r = uintptr(r1)
}
err = GetErrno()
exitsyscall()
return r, 0, err
}
 
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
var r uintptr
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
r = uintptr(r1)
}
err = GetErrno()
return r, 0, err
}
 
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
var r uintptr
if unsafe.Sizeof(r) == 4 {
r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
int32(a4), int32(a5), int32(a6))
r = uintptr(r1)
} else {
r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
int64(a4), int64(a5), int64(a6))
r = uintptr(r1)
}
err = GetErrno()
return r, 0, err
}
 
// Mmap manager, for use by operating system-specific implementations.
// Gccgo only has one implementation but we do this to correspond to gc.
 
type mmapper struct {
sync.Mutex
active map[*byte][]byte // active mappings; key is last byte in mapping
mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
munmap func(addr uintptr, length uintptr) error
}
 
func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
if length <= 0 {
return nil, EINVAL
}
 
// Map the requested memory.
addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
if errno != nil {
return nil, errno
}
 
// Slice memory layout
var sl = struct {
addr uintptr
len int
cap int
}{addr, length, length}
 
// Use unsafe to turn sl into a []byte.
b := *(*[]byte)(unsafe.Pointer(&sl))
 
// Register mapping in m and return it.
p := &b[cap(b)-1]
m.Lock()
defer m.Unlock()
m.active[p] = b
return b, nil
}
 
func (m *mmapper) Munmap(data []byte) (err error) {
if len(data) == 0 || len(data) != cap(data) {
return EINVAL
}
 
// Find the base of the mapping.
p := &data[cap(data)-1]
m.Lock()
defer m.Unlock()
b := m.active[p]
if b == nil || &b[0] != &data[0] {
return EINVAL
}
 
// Unmap the memory and update m.
if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
return errno
}
m.active[p] = nil, false
return nil
}
 
var mapper = &mmapper{
active: make(map[*byte][]byte),
mmap: mmap,
munmap: munmap,
}
 
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
return mapper.Mmap(fd, offset, length, prot, flags)
}
 
func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
/libcall_linux.go
0,0 → 1,317
// 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.
 
// GNU/Linux library calls.
 
package syscall
 
import "unsafe"
 
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
//openat(dirfd int, path *byte, flags int, mode Mode_t) int
 
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
//futimesat(dirfd int, path *byte, times *[2]Timeval) int
func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
if len(tv) != 2 {
return EINVAL
}
return futimesat(dirfd, StringBytePtr(path), (*[2]Timeval)(unsafe.Pointer(&tv[0])))
}
 
func Futimes(fd int, tv []Timeval) (err error) {
// Believe it or not, this is the best we can do on GNU/Linux
// (and is what glibc does).
return Utimes("/proc/self/fd/"+itoa(fd), tv)
}
 
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
//ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
 
//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
//ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
 
func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
// 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.
 
var buf [sizeofPtr]byte
 
// 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.
n := 0
if addr%sizeofPtr != 0 {
err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return 0, err
}
n += copy(out, buf[addr%sizeofPtr:])
out = out[n:]
}
 
// Remainder.
for len(out) > 0 {
// We use an internal buffer to gaurantee alignment.
// It's not documented if this is necessary, but we're paranoid.
err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return n, err
}
copied := copy(out, buf[0:])
n += copied
out = out[copied:]
}
 
return n, nil
}
 
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
}
 
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
}
 
func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
// As for ptracePeek, we need to align our accesses to deal
// with the possibility of straddling an invalid page.
 
// Leading edge.
n := 0
if addr%sizeofPtr != 0 {
var buf [sizeofPtr]byte
err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return 0, err
}
n += copy(buf[addr%sizeofPtr:], data)
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
if err != nil {
return 0, err
}
data = data[n:]
}
 
// Interior.
for len(data) > int(sizeofPtr) {
word := *((*uintptr)(unsafe.Pointer(&data[0])))
err = ptrace(pokeReq, pid, addr+uintptr(n), word)
if err != nil {
return n, err
}
n += int(sizeofPtr)
data = data[sizeofPtr:]
}
 
// Trailing edge.
if len(data) > 0 {
var buf [sizeofPtr]byte
err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
return n, err
}
copy(buf[0:], data)
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
err = ptrace(pokeReq, pid, addr+uintptr(n), word)
if err != nil {
return n, err
}
n += len(data)
}
 
return n, nil
}
 
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
}
 
func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
}
 
func PtraceSetOptions(pid int, options int) (err error) {
return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
}
 
func PtraceGetEventMsg(pid int) (msg uint, err error) {
var data _C_long
err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
msg = uint(data)
return
}
 
func PtraceCont(pid int, signal int) (err error) {
return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
}
 
func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
 
func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
 
func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
 
// FIXME: mksysinfo needs to produce LINUX_REBOOT_MAGIC[12].
 
// //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
// //reboot(magic1 uint, magic2 uint, cmd int, arg *byte) int
// func Reboot(cmd int) (err error) {
// return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
// }
 
//sys Acct(path string) (err error)
//acct(path *byte) int
 
// FIXME: mksysinfo Timex
// //sys Adjtimex(buf *Timex) (state int, err error)
// //adjtimex(buf *Timex) int
 
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//faccessat(dirfd int, pathname *byte, mode int, flags int) int
 
//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
//fallocate(fd int, mode int, offset Offset_t, len Offset_t) int
 
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//fchmodat(dirfd int, pathname *byte, mode Mode_t, flags int) int
 
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//fchownat(dirfd int, path *byte, owner Uid_t, group Gid_t, flags int) int
 
//sys Flock(fd int, how int) (err error)
//flock(fd int, how int) int
 
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//fstatfs(fd int, buf *Statfs_t) int
 
func Gettid() (tid int) {
r1, _, _ := Syscall(SYS_GETTID, 0, 0, 0)
return int(r1)
}
 
// FIXME: mksysinfo linux_dirent
// Or just abandon this function.
// //sys Getdents(fd int, buf []byte) (n int, err error)
// //getdents64(fd int, buf *byte, count uint)
 
//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
//inotify_add_watch(fd int, pathname *byte, mask uint32) int
 
//sysnb InotifyInit() (fd int, err error)
//inotify_init() int
 
// FIXME: Only in glibc 2.9 and later.
// //sysnb InotifyInit1(flags int) (fd int, err error)
// //inotify_init1(flags int) int
 
//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
//inotify_rm_watch(fd int, wd uint32) int
 
//sys Klogctl(typ int, buf []byte) (n int, err error)
//klogctl(typ int, bufp *byte, len int) int
 
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//mkdirat(dirfd int, path *byte, mode Mode_t) int
 
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//mknodat(dirfd int, path *byte, mode Mode_t, dev _dev_t) int
 
//sys PivotRoot(newroot string, putold string) (err error)
//pivot_root(newroot *byte, putold *byte) int
 
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//renameat(olddirfd int, oldpath *byte, newdirfd int, newpath *byte) int
 
//sys sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error)
//sendfile64(outfd int, infd int, offset *Offset_t, count Size_t) Ssize_t
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var soff Offset_t
var psoff *Offset_t
if offset != nil {
psoff = &soff
}
written, err = sendfile(outfd, infd, psoff, count)
if offset != nil {
*offset = int64(soff)
}
return
}
 
//sys Setfsgid(gid int) (err error)
//setfsgid(gid Gid_t) int
 
//sys Setfsuid(uid int) (err error)
//setfsuid(uid Uid_t) int
 
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//setresgid(rgid Gid_t, egid Gid_t, sgid Gid_t) int
 
//sysnb Setresuid(ruid int, eguid int, suid int) (err error)
//setresuid(ruid Uid_t, euid Uid_t, suid Uid_t) int
 
//sys splice(rfd int, roff *_loff_t, wfd int, woff *_loff_t, len int, flags int) (n int64, err error)
//splice(rfd int, roff *_loff_t, wfd int, woff *_loff_t, len Size_t, flags uint) Ssize_t
func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
var lroff _loff_t
var plroff *_loff_t
if roff != nil {
plroff = &lroff
}
var lwoff _loff_t
var plwoff *_loff_t
if woff != nil {
plwoff = &lwoff
}
n, err = splice(rfd, plroff, wfd, plwoff, len, flags)
if roff != nil {
*roff = int64(lroff)
}
if woff != nil {
*woff = int64(lwoff)
}
return
}
 
//sys Statfs(path string, buf *Statfs_t) (err error)
//statfs(path *byte, buf *Statfs_t) int
 
// FIXME: Only in glibc 2.6 and later.
// //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
// //sync_file_range(fd int, off Offset_t, n Offset_t, flags uint) int
 
// FIXME: mksysinfo Sysinfo_t
// //sysnb Sysinfo(info *Sysinfo_t) (err error)
// //sysinfo(info *Sysinfo_t) int
 
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
//tee(rfd int, wfd int, len Size_t, flags uint) Ssize_t
 
// FIXME: Only available as a syscall.
// //sysnb Tgkill(tgid int, tid int, sig int) (err error)
// //tgkill(tgid int, tid int, sig int) int
 
//sys unlinkat(dirfd int, path string, flags int) (err error)
//unlinkat(dirfd int, path *byte, flags int) int
 
func Unlinkat(dirfd int, path string) (err error) {
return unlinkat(dirfd, path, 0)
}
 
//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
//umount2(target *byte, flags int) int
 
//sys Unshare(flags int) (err error)
//unshare(flags int) int
 
// FIXME: mksysinfo Ustat_t
// //sys Ustat(dev int, ubuf *Ustat_t) (err error)
// //ustat(dev _dev_t, ubuf *Ustat_t) int
/libcall_posix_regfile.go
0,0 → 1,38
// 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.
 
// POSIX library calls on systems which do not use the largefile
// interface.
 
package syscall
 
//sys Fstat(fd int, stat *Stat_t) (err error)
//fstat(fd int, stat *Stat_t) int
 
//sys Ftruncate(fd int, length int64) (err error)
//ftruncate(fd int, length Offset_t) int
 
//sys Lstat(path string, stat *Stat_t) (err error)
//lstat(path *byte, stat *Stat_t) int
 
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//mmap(addr *byte, length Size_t, prot int, flags int, fd int, offset Offset_t) *byte
 
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//open(path *byte, mode int, perm Mode_t) int
 
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//pread(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t
 
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//pwrite(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t
 
//sys Seek(fd int, offset int64, whence int) (off int64, err error)
//lseek(fd int, offset Offset_t, whence int) Offset_t
 
//sys Stat(path string, stat *Stat_t) (err error)
//stat(path *byte, stat *Stat_t) int
 
//sys Truncate(path string, length int64) (err error)
//truncate(path *byte, length Offset_t) int
/security_windows.go
0,0 → 1,359
// Copyright 2012 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.
 
package syscall
 
import (
"unsafe"
)
 
const (
STANDARD_RIGHTS_REQUIRED = 0xf0000
STANDARD_RIGHTS_READ = 0x20000
STANDARD_RIGHTS_WRITE = 0x20000
STANDARD_RIGHTS_EXECUTE = 0x20000
STANDARD_RIGHTS_ALL = 0x1F0000
)
 
const (
NameUnknown = 0
NameFullyQualifiedDN = 1
NameSamCompatible = 2
NameDisplay = 3
NameUniqueId = 6
NameCanonical = 7
NameUserPrincipal = 8
NameCanonicalEx = 9
NameServicePrincipal = 10
NameDnsDomain = 12
)
 
// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
 
// TranslateAccountName converts a directory service
// object name from one format to another.
func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
u := StringToUTF16Ptr(username)
b := make([]uint16, 50)
n := uint32(len(b))
e := TranslateName(u, from, to, &b[0], &n)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return "", e
}
// make receive buffers of requested size and try again
b = make([]uint16, n)
e = TranslateName(u, from, to, &b[0], &n)
if e != nil {
return "", e
}
}
return UTF16ToString(b), nil
}
 
type UserInfo10 struct {
Name *uint16
Comment *uint16
UsrComment *uint16
FullName *uint16
}
 
//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
 
const (
// do not reorder
SidTypeUser = 1 << iota
SidTypeGroup
SidTypeDomain
SidTypeAlias
SidTypeWellKnownGroup
SidTypeDeletedAccount
SidTypeInvalid
SidTypeUnknown
SidTypeComputer
SidTypeLabel
)
 
//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
 
// The security identifier (SID) structure is a variable-length
// structure used to uniquely identify users or groups.
type SID struct{}
 
// StringToSid converts a string-format security identifier
// sid into a valid, functional sid.
func StringToSid(s string) (*SID, error) {
var sid *SID
e := ConvertStringSidToSid(StringToUTF16Ptr(s), &sid)
if e != nil {
return nil, e
}
defer LocalFree((Handle)(unsafe.Pointer(sid)))
return sid.Copy()
}
 
// LookupSID retrieves a security identifier sid for the account
// and the name of the domain on which the account was found.
// System specify target computer to search.
func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
if len(account) == 0 {
return nil, "", 0, EINVAL
}
acc := StringToUTF16Ptr(account)
var sys *uint16
if len(system) > 0 {
sys = StringToUTF16Ptr(system)
}
db := make([]uint16, 50)
dn := uint32(len(db))
b := make([]byte, 50)
n := uint32(len(b))
sid = (*SID)(unsafe.Pointer(&b[0]))
e := LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return nil, "", 0, e
}
// make receive buffers of requested size and try again
b = make([]byte, n)
sid = (*SID)(unsafe.Pointer(&b[0]))
db = make([]uint16, dn)
e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
if e != nil {
return nil, "", 0, e
}
}
return sid, UTF16ToString(db), accType, nil
}
 
// String converts sid to a string format
// suitable for display, storage, or transmission.
func (sid *SID) String() (string, error) {
var s *uint16
e := ConvertSidToStringSid(sid, &s)
if e != nil {
return "", e
}
defer LocalFree((Handle)(unsafe.Pointer(s)))
return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
}
 
// Len returns the length, in bytes, of a valid security identifier sid.
func (sid *SID) Len() int {
return int(GetLengthSid(sid))
}
 
// Copy creates a duplicate of security identifier sid.
func (sid *SID) Copy() (*SID, error) {
b := make([]byte, sid.Len())
sid2 := (*SID)(unsafe.Pointer(&b[0]))
e := CopySid(uint32(len(b)), sid2, sid)
if e != nil {
return nil, e
}
return sid2, nil
}
 
// LookupAccount retrieves the name of the account for this sid
// and the name of the first domain on which this sid is found.
// System specify target computer to search for.
func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
var sys *uint16
if len(system) > 0 {
sys = StringToUTF16Ptr(system)
}
b := make([]uint16, 50)
n := uint32(len(b))
db := make([]uint16, 50)
dn := uint32(len(db))
e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return "", "", 0, e
}
// make receive buffers of requested size and try again
b = make([]uint16, n)
db = make([]uint16, dn)
e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
if e != nil {
return "", "", 0, e
}
}
return UTF16ToString(b), UTF16ToString(db), accType, nil
}
 
const (
// do not reorder
TOKEN_ASSIGN_PRIMARY = 1 << iota
TOKEN_DUPLICATE
TOKEN_IMPERSONATE
TOKEN_QUERY
TOKEN_QUERY_SOURCE
TOKEN_ADJUST_PRIVILEGES
TOKEN_ADJUST_GROUPS
TOKEN_ADJUST_DEFAULT
 
TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE |
TOKEN_IMPERSONATE |
TOKEN_QUERY |
TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES |
TOKEN_ADJUST_GROUPS |
TOKEN_ADJUST_DEFAULT
TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
TOKEN_ADJUST_PRIVILEGES |
TOKEN_ADJUST_GROUPS |
TOKEN_ADJUST_DEFAULT
TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
)
 
const (
// do not reorder
TokenUser = 1 + iota
TokenGroups
TokenPrivileges
TokenOwner
TokenPrimaryGroup
TokenDefaultDacl
TokenSource
TokenType
TokenImpersonationLevel
TokenStatistics
TokenRestrictedSids
TokenSessionId
TokenGroupsAndPrivileges
TokenSessionReference
TokenSandBoxInert
TokenAuditPolicy
TokenOrigin
TokenElevationType
TokenLinkedToken
TokenElevation
TokenHasRestrictions
TokenAccessInformation
TokenVirtualizationAllowed
TokenVirtualizationEnabled
TokenIntegrityLevel
TokenUIAccess
TokenMandatoryPolicy
TokenLogonSid
MaxTokenInfoClass
)
 
type SIDAndAttributes struct {
Sid *SID
Attributes uint32
}
 
type Tokenuser struct {
User SIDAndAttributes
}
 
type Tokenprimarygroup struct {
PrimaryGroup *SID
}
 
//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
 
// An access token contains the security information for a logon session.
// The system creates an access token when a user logs on, and every
// process executed on behalf of the user has a copy of the token.
// The token identifies the user, the user's groups, and the user's
// privileges. The system uses the token to control access to securable
// objects and to control the ability of the user to perform various
// system-related operations on the local computer.
type Token Handle
 
// OpenCurrentProcessToken opens the access token
// associated with current process.
func OpenCurrentProcessToken() (Token, error) {
p, e := GetCurrentProcess()
if e != nil {
return 0, e
}
var t Token
e = OpenProcessToken(p, TOKEN_QUERY, &t)
if e != nil {
return 0, e
}
return t, nil
}
 
// Close releases access to access token.
func (t Token) Close() error {
return CloseHandle(Handle(t))
}
 
// getInfo retrieves a specified type of information about an access token.
func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
b := make([]byte, initSize)
var n uint32
e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return nil, e
}
// make receive buffers of requested size and try again
b = make([]byte, n)
e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
if e != nil {
return nil, e
}
}
return unsafe.Pointer(&b[0]), nil
}
 
// GetTokenUser retrieves access token t user account information.
func (t Token) GetTokenUser() (*Tokenuser, error) {
i, e := t.getInfo(TokenUser, 50)
if e != nil {
return nil, e
}
return (*Tokenuser)(i), nil
}
 
// GetTokenPrimaryGroup retrieves access token t primary group information.
// A pointer to a SID structure representing a group that will become
// the primary group of any objects created by a process using this access token.
func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
i, e := t.getInfo(TokenPrimaryGroup, 50)
if e != nil {
return nil, e
}
return (*Tokenprimarygroup)(i), nil
}
 
// GetUserProfileDirectory retrieves path to the
// root directory of the access token t user's profile.
func (t Token) GetUserProfileDirectory() (string, error) {
b := make([]uint16, 100)
n := uint32(len(b))
e := GetUserProfileDirectory(t, &b[0], &n)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return "", e
}
// make receive buffers of requested size and try again
b = make([]uint16, n)
e = GetUserProfileDirectory(t, &b[0], &n)
if e != nil {
return "", e
}
}
return UTF16ToString(b), nil
}
/errstr.go
0,0 → 1,27
// errstr.go -- Error strings.
 
// 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.
 
package syscall
 
//sysnb strerror_r(errnum int, buf []byte) (err error)
//strerror_r(errnum int, buf *byte, buflen Size_t) int
 
func Errstr(errnum int) string {
for len := 128; ; len *= 2 {
b := make([]byte, len)
err := strerror_r(errnum, b)
if err == nil {
i := 0
for b[i] != 0 {
i++
}
return string(b[:i])
}
if err != ERANGE {
return "Errstr failure"
}
}
}
/libcall_waitpid.go
0,0 → 1,20
// 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.
 
// For systems with the waitpid library call.
 
package syscall
 
//sys waitpid(pid Pid_t, status *int, options int) (wpid Pid_t, err error)
//waitpid(pid Pid_t, status *int, options int) Pid_t
 
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
var status int
r, err := waitpid(Pid_t(pid), &status, options)
wpid = int(r)
if wstatus != nil {
*wstatus = WaitStatus(status)
}
return
}
/netlink_linux.go
0,0 → 1,226
// Copyright 2011 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.
 
// Netlink sockets and messages
 
package syscall
 
import (
"unsafe"
)
 
// Round the length of a netlink message up to align it properly.
func nlmAlignOf(msglen int) int {
return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
}
 
// Round the length of a netlink route attribute up to align it
// properly.
func rtaAlignOf(attrlen int) int {
return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
}
 
// NetlinkRouteRequest represents the request message to receive
// routing and link states from the kernel.
type NetlinkRouteRequest struct {
Header NlMsghdr
Data RtGenmsg
}
 
func (rr *NetlinkRouteRequest) toWireFormat() []byte {
b := make([]byte, rr.Header.Len)
b[0] = byte(rr.Header.Len)
b[1] = byte(rr.Header.Len >> 8)
b[2] = byte(rr.Header.Len >> 16)
b[3] = byte(rr.Header.Len >> 24)
b[4] = byte(rr.Header.Type)
b[5] = byte(rr.Header.Type >> 8)
b[6] = byte(rr.Header.Flags)
b[7] = byte(rr.Header.Flags >> 8)
b[8] = byte(rr.Header.Seq)
b[9] = byte(rr.Header.Seq >> 8)
b[10] = byte(rr.Header.Seq >> 16)
b[11] = byte(rr.Header.Seq >> 24)
b[12] = byte(rr.Header.Pid)
b[13] = byte(rr.Header.Pid >> 8)
b[14] = byte(rr.Header.Pid >> 16)
b[15] = byte(rr.Header.Pid >> 24)
b[16] = byte(rr.Data.Family)
return b
}
 
func newNetlinkRouteRequest(proto, seq, family int) []byte {
rr := &NetlinkRouteRequest{}
rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
rr.Header.Type = uint16(proto)
rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
rr.Header.Seq = uint32(seq)
rr.Data.Family = uint8(family)
return rr.toWireFormat()
}
 
// NetlinkRIB returns routing information base, as known as RIB,
// which consists of network facility information, states and
// parameters.
func NetlinkRIB(proto, family int) ([]byte, error) {
var (
lsanl SockaddrNetlink
tab []byte
)
 
s, e := Socket(AF_NETLINK, SOCK_RAW, 0)
if e != nil {
return nil, e
}
defer Close(s)
 
lsanl.Family = AF_NETLINK
e = Bind(s, &lsanl)
if e != nil {
return nil, e
}
 
seq := 1
wb := newNetlinkRouteRequest(proto, seq, family)
e = Sendto(s, wb, 0, &lsanl)
if e != nil {
return nil, e
}
 
for {
var (
rb []byte
nr int
lsa Sockaddr
)
 
rb = make([]byte, Getpagesize())
nr, _, e = Recvfrom(s, rb, 0)
if e != nil {
return nil, e
}
if nr < NLMSG_HDRLEN {
return nil, EINVAL
}
rb = rb[:nr]
tab = append(tab, rb...)
 
msgs, _ := ParseNetlinkMessage(rb)
for _, m := range msgs {
if lsa, e = Getsockname(s); e != nil {
return nil, e
}
switch v := lsa.(type) {
case *SockaddrNetlink:
if m.Header.Seq != uint32(seq) || m.Header.Pid != v.Pid {
return nil, EINVAL
}
default:
return nil, EINVAL
}
if m.Header.Type == NLMSG_DONE {
goto done
}
if m.Header.Type == NLMSG_ERROR {
return nil, EINVAL
}
}
}
 
done:
return tab, nil
}
 
// NetlinkMessage represents the netlink message.
type NetlinkMessage struct {
Header NlMsghdr
Data []byte
}
 
// ParseNetlinkMessage parses buf as netlink messages and returns
// the slice containing the NetlinkMessage structs.
func ParseNetlinkMessage(buf []byte) ([]NetlinkMessage, error) {
var (
h *NlMsghdr
dbuf []byte
dlen int
e error
msgs []NetlinkMessage
)
 
for len(buf) >= NLMSG_HDRLEN {
h, dbuf, dlen, e = netlinkMessageHeaderAndData(buf)
if e != nil {
break
}
m := NetlinkMessage{}
m.Header = *h
m.Data = dbuf[:int(h.Len)-NLMSG_HDRLEN]
msgs = append(msgs, m)
buf = buf[dlen:]
}
 
return msgs, e
}
 
func netlinkMessageHeaderAndData(buf []byte) (*NlMsghdr, []byte, int, error) {
h := (*NlMsghdr)(unsafe.Pointer(&buf[0]))
if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(buf) {
return nil, nil, 0, EINVAL
}
return h, buf[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
}
 
// NetlinkRouteAttr represents the netlink route attribute.
type NetlinkRouteAttr struct {
Attr RtAttr
Value []byte
}
 
// ParseNetlinkRouteAttr parses msg's payload as netlink route
// attributes and returns the slice containing the NetlinkRouteAttr
// structs.
func ParseNetlinkRouteAttr(msg *NetlinkMessage) ([]NetlinkRouteAttr, error) {
var (
buf []byte
a *RtAttr
alen int
vbuf []byte
e error
attrs []NetlinkRouteAttr
)
 
switch msg.Header.Type {
case RTM_NEWLINK, RTM_DELLINK:
buf = msg.Data[SizeofIfInfomsg:]
case RTM_NEWADDR, RTM_DELADDR:
buf = msg.Data[SizeofIfAddrmsg:]
case RTM_NEWROUTE, RTM_DELROUTE:
buf = msg.Data[SizeofRtMsg:]
default:
return nil, EINVAL
}
 
for len(buf) >= SizeofRtAttr {
a, vbuf, alen, e = netlinkRouteAttrAndValue(buf)
if e != nil {
break
}
ra := NetlinkRouteAttr{}
ra.Attr = *a
ra.Value = vbuf[:int(a.Len)-SizeofRtAttr]
attrs = append(attrs, ra)
buf = buf[alen:]
}
 
return attrs, nil
}
 
func netlinkRouteAttrAndValue(buf []byte) (*RtAttr, []byte, int, error) {
h := (*RtAttr)(unsafe.Pointer(&buf[0]))
if int(h.Len) < SizeofRtAttr || int(h.Len) > len(buf) {
return nil, nil, 0, EINVAL
}
return h, buf[SizeofRtAttr:], rtaAlignOf(int(h.Len)), nil
}
/syscall_linux_amd64.go
0,0 → 1,25
// syscall_linux_amd64.go -- GNU/Linux 386 specific support
 
// 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.
 
package syscall
 
import "unsafe"
 
func (r *PtraceRegs) PC() uint64 {
return r.Rip
}
 
func (r *PtraceRegs) SetPC(pc uint64) {
r.Rip = pc
}
 
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
}
 
func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
}
/route_bsd.go
0,0 → 1,201
// Copyright 2011 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.
 
// +build darwin freebsd netbsd openbsd
 
// Routing sockets and messages
 
package syscall
 
import (
"unsafe"
)
 
// Round the length of a raw sockaddr up to align it properly.
func rsaAlignOf(salen int) int {
salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
// aligned access to BSD subsystem.
if darwinAMD64 {
salign = 4
}
if salen == 0 {
return salign
}
return (salen + salign - 1) & ^(salign - 1)
}
 
// RouteRIB returns routing information base, as known as RIB,
// which consists of network facility information, states and
// parameters.
func RouteRIB(facility, param int) ([]byte, error) {
mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)}
 
// Find size.
n := uintptr(0)
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
return nil, err
}
if n == 0 {
return nil, nil
}
 
tab := make([]byte, n)
if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil {
return nil, err
}
 
return tab[:n], nil
}
 
// RoutingMessage represents a routing message.
type RoutingMessage interface {
sockaddr() []Sockaddr
}
 
const anyMessageLen = int(unsafe.Sizeof(anyMessage{}))
 
type anyMessage struct {
Msglen uint16
Version uint8
Type uint8
}
 
// RouteMessage represents a routing message containing routing
// entries.
type RouteMessage struct {
Header RtMsghdr
Data []byte
}
 
const rtaRtMask = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK
 
func (m *RouteMessage) sockaddr() []Sockaddr {
var (
af int
sas [4]Sockaddr
)
 
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaRtMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_DST, RTAX_GATEWAY:
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if err != nil {
return nil
}
if i == RTAX_DST {
af = int(rsa.Family)
}
sas[i] = sa
case RTAX_NETMASK, RTAX_GENMASK:
switch af {
case AF_INET:
rsa4 := (*RawSockaddrInet4)(unsafe.Pointer(&buf[0]))
sa := new(SockaddrInet4)
for j := 0; rsa4.Len > 0 && j < int(rsa4.Len)-int(unsafe.Offsetof(rsa4.Addr)); j++ {
sa.Addr[j] = rsa4.Addr[j]
}
sas[i] = sa
case AF_INET6:
rsa6 := (*RawSockaddrInet6)(unsafe.Pointer(&buf[0]))
sa := new(SockaddrInet6)
for j := 0; rsa6.Len > 0 && j < int(rsa6.Len)-int(unsafe.Offsetof(rsa6.Addr)); j++ {
sa.Addr[j] = rsa6.Addr[j]
}
sas[i] = sa
}
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
 
return sas[:]
}
 
// InterfaceMessage represents a routing message containing
// network interface entries.
type InterfaceMessage struct {
Header IfMsghdr
Data []byte
}
 
func (m *InterfaceMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&RTA_IFP == 0 {
return nil
}
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(&m.Data[0])))
if err != nil {
return nil
}
return append(sas, sa)
}
 
// InterfaceAddrMessage represents a routing message containing
// network interface address entries.
type InterfaceAddrMessage struct {
Header IfaMsghdr
Data []byte
}
 
const rtaIfaMask = RTA_IFA | RTA_NETMASK | RTA_BRD
 
func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfaMask == 0 {
return nil
}
 
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_IFA:
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if err != nil {
return nil
}
sas = append(sas, sa)
case RTAX_NETMASK:
if rsa.Family == AF_UNSPEC {
rsa.Family = AF_INET // an old fasion, AF_UNSPEC means AF_INET
}
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if err != nil {
return nil
}
sas = append(sas, sa)
case RTAX_BRD:
// nothing to do
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
 
return sas
}
 
// ParseRoutingMessage parses buf as routing messages and returns
// the slice containing the RoutingMessage interfaces.
func ParseRoutingMessage(buf []byte) (msgs []RoutingMessage, err error) {
for len(buf) >= anyMessageLen {
any := (*anyMessage)(unsafe.Pointer(&buf[0]))
if any.Version != RTM_VERSION {
return nil, EINVAL
}
msgs = append(msgs, any.toRoutingMessage(buf))
buf = buf[any.Msglen:]
}
return msgs, nil
}
 
// ParseRoutingMessage parses msg's payload as raw sockaddrs and
// returns the slice containing the Sockaddr interfaces.
func ParseRoutingSockaddr(msg RoutingMessage) (sas []Sockaddr, err error) {
return append(sas, msg.sockaddr()...), nil
}
/libcall_uname.go
0,0 → 1,8
// Copyright 2011 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.
 
package syscall
 
//sysnb Uname(buf *Utsname) (err error)
//uname(buf *Utsname) int
/route_freebsd.go
0,0 → 1,77
// Copyright 2011 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.
 
// Routing sockets and messages for FreeBSD
 
package syscall
 
import (
"unsafe"
)
 
func (any *anyMessage) toRoutingMessage(buf []byte) RoutingMessage {
switch any.Type {
case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
p := (*RouteMessage)(unsafe.Pointer(any))
rtm := &RouteMessage{}
rtm.Header = p.Header
rtm.Data = buf[SizeofRtMsghdr:any.Msglen]
return rtm
case RTM_IFINFO:
p := (*InterfaceMessage)(unsafe.Pointer(any))
ifm := &InterfaceMessage{}
ifm.Header = p.Header
ifm.Data = buf[SizeofIfMsghdr:any.Msglen]
return ifm
case RTM_NEWADDR, RTM_DELADDR:
p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
ifam := &InterfaceAddrMessage{}
ifam.Header = p.Header
ifam.Data = buf[SizeofIfaMsghdr:any.Msglen]
return ifam
case RTM_NEWMADDR, RTM_DELMADDR:
p := (*InterfaceMulticastAddrMessage)(unsafe.Pointer(any))
ifmam := &InterfaceMulticastAddrMessage{}
ifmam.Header = p.Header
ifmam.Data = buf[SizeofIfmaMsghdr:any.Msglen]
return ifmam
}
return nil
}
 
// InterfaceMulticastAddrMessage represents a routing message
// containing network interface address entries.
type InterfaceMulticastAddrMessage struct {
Header IfmaMsghdr
Data []byte
}
 
const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
 
func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfmaMask == 0 {
return nil
}
 
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_IFA:
sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if e != nil {
return nil
}
sas = append(sas, sa)
case RTAX_GATEWAY, RTAX_IFP:
// nothing to do
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
 
return sas
}
/socket.go
0,0 → 1,411
// socket.go -- Socket handling.
 
// 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.
 
// Low-level socket interface.
// Only for implementing net package.
// DO NOT USE DIRECTLY.
 
package syscall
 
import "unsafe"
 
// For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool
 
type Sockaddr interface {
sockaddr() (ptr *RawSockaddrAny, len Socklen_t, err error) // lowercase; only we can define Sockaddrs
}
 
type RawSockaddrAny struct {
Addr RawSockaddr
Pad [12]int8
}
 
const SizeofSockaddrAny = 0x1c
 
type SockaddrInet4 struct {
Port int
Addr [4]byte
raw RawSockaddrInet4
}
 
func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, EINVAL
}
sa.raw.Family = AF_INET
n := sa.raw.setLen()
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
for i := 0; i < len(sa.Addr); i++ {
sa.raw.Addr[i] = sa.Addr[i]
}
return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), n, nil
}
 
type SockaddrInet6 struct {
Port int
ZoneId uint32
Addr [16]byte
raw RawSockaddrInet6
}
 
func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, EINVAL
}
sa.raw.Family = AF_INET6
n := sa.raw.setLen()
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
p[0] = byte(sa.Port >> 8)
p[1] = byte(sa.Port)
sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ {
sa.raw.Addr[i] = sa.Addr[i]
}
return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), n, nil
}
 
type SockaddrUnix struct {
Name string
raw RawSockaddrUnix
}
 
func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
name := sa.Name
n := len(name)
if n >= len(sa.raw.Path) || n == 0 {
return nil, 0, EINVAL
}
sa.raw.Family = AF_UNIX
sa.raw.setLen(n)
for i := 0; i < n; i++ {
sa.raw.Path[i] = int8(name[i])
}
if sa.raw.Path[0] == '@' {
sa.raw.Path[0] = 0
}
 
// length is family (uint16), name, NUL.
return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), 2 + Socklen_t(n) + 1, nil
}
 
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_UNIX:
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
sa := new(SockaddrUnix)
n, err := pp.getLen()
if err != nil {
return nil, err
}
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))
sa.Name = string(bytes[0:n])
return sa, nil
 
case AF_INET:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
sa := new(SockaddrInet4)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
 
case AF_INET6:
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
sa := new(SockaddrInet6)
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
sa.Port = int(p[0])<<8 + int(p[1])
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
}
return anyToSockaddrOS(rsa)
}
 
//sys accept(fd int, sa *RawSockaddrAny, len *Socklen_t) (nfd int, err error)
//accept(fd int, sa *RawSockaddrAny, len *Socklen_t) int
 
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
var rsa RawSockaddrAny
var len Socklen_t = SizeofSockaddrAny
nfd, err = accept(fd, &rsa, &len)
if err != nil {
return
}
sa, err = anyToSockaddr(&rsa)
if err != nil {
Close(nfd)
nfd = 0
}
return
}
 
//sysnb getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
//getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) int
 
func Getsockname(fd int) (sa Sockaddr, err error) {
var rsa RawSockaddrAny
var len Socklen_t = SizeofSockaddrAny
if err = getsockname(fd, &rsa, &len); err != nil {
return
}
return anyToSockaddr(&rsa)
}
 
//sysnb getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
//getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) int
 
func Getpeername(fd int) (sa Sockaddr, err error) {
var rsa RawSockaddrAny
var len Socklen_t = SizeofSockaddrAny
if err = getpeername(fd, &rsa, &len); err != nil {
return
}
return anyToSockaddr(&rsa)
}
 
//sys bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error)
//bind(fd int, sa *RawSockaddrAny, len Socklen_t) int
 
func Bind(fd int, sa Sockaddr) (err error) {
ptr, n, err := sa.sockaddr()
if err != nil {
return err
}
return bind(fd, ptr, n)
}
 
//sys connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) (err error)
//connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) int
 
func Connect(fd int, sa Sockaddr) (err error) {
ptr, n, err := sa.sockaddr()
if err != nil {
return err
}
return connect(fd, ptr, n)
}
 
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//socket(domain int, typ int, protocol int) int
 
func Socket(domain, typ, proto int) (fd int, err error) {
if domain == AF_INET6 && SocketDisableIPv6 {
return -1, EAFNOSUPPORT
}
fd, err = socket(domain, typ, proto)
return
}
 
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int) (err error)
//socketpair(domain int, typ int, protocol int, fd *[2]int) int
 
func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
err = socketpair(domain, typ, proto, &fd)
return
}
 
//sys getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
//getsockopt(s int, level int, name int, val *byte, vallen *Socklen_t) int
 
func GetsockoptInt(fd, level, opt int) (value int, err error) {
var n int32
vallen := Socklen_t(4)
err = getsockopt(fd, level, opt, (uintptr)(unsafe.Pointer(&n)), &vallen)
return int(n), err
}
 
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
vallen := Socklen_t(4)
err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), &vallen)
return value, err
}
 
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
var value IPMreq
vallen := Socklen_t(SizeofIPMreq)
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
return &value, err
}
 
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
var value IPMreqn
vallen := Socklen_t(SizeofIPMreqn)
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
return &value, err
}
 
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
var value IPv6Mreq
vallen := Socklen_t(SizeofIPv6Mreq)
err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
return &value, err
}
 
//sys setsockopt(s int, level int, name int, val *byte, vallen Socklen_t) (err error)
//setsockopt(s int, level int, optname int, val *byte, vallen Socklen_t) int
 
func SetsockoptInt(fd, level, opt int, value int) (err error) {
var n = int32(value)
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 4)
}
 
func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&value[0])), 4)
}
 
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(tv)), Socklen_t(unsafe.Sizeof(*tv)))
}
 
type Linger struct {
Onoff int32
Linger int32
}
 
func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(l)), Socklen_t(unsafe.Sizeof(*l)))
}
 
func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
}
 
func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
}
 
func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
}
 
func SetsockoptString(fd, level, opt int, s string) (err error) {
return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&[]byte(s)[0])), Socklen_t(len(s)))
}
 
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
//recvfrom(fd int, buf *byte, len Size_t, flags int, from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t
 
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
var rsa RawSockaddrAny
var len Socklen_t = SizeofSockaddrAny
if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
return
}
from, err = anyToSockaddr(&rsa)
return
}
 
//sys sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
//sendto(s int, buf *byte, len Size_t, flags int, to *RawSockaddrAny, tolen Socklen_t) Ssize_t
 
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
ptr, n, err := to.sockaddr()
if err != nil {
return err
}
return sendto(fd, p, flags, ptr, n)
}
 
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//recvmsg(s int, msg *Msghdr, flags int) Ssize_t
 
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
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
if n, err = recvmsg(fd, &msg, flags); err != nil {
return
}
oobn = int(msg.Controllen)
recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa)
}
return
}
 
//sys sendmsg(s int, msg *Msghdr, flags int) (err error)
//sendmsg(s int, msg *Msghdr, flags int) Ssize_t
 
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
var ptr *RawSockaddrAny
var salen Socklen_t
if to != nil {
var err error
ptr, salen, err = to.sockaddr()
if err != nil {
return err
}
}
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)
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
if err = sendmsg(fd, &msg, flags); err != nil {
return
}
return
}
 
//sys Listen(fd int, n int) (err error)
//listen(fd int, n int) int
 
//sys Shutdown(fd int, how int) (err error)
//shutdown(fd int, how int) int
 
func (iov *Iovec) SetLen(length int) {
iov.Len = Iovec_len_t(length)
}
 
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = Msghdr_controllen_t(length)
}
 
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = Cmsghdr_len_t(length)
}
/syscall_linux_386.go
0,0 → 1,25
// syscall_linux_386.go -- GNU/Linux 386 specific support
 
// 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.
 
package syscall
 
import "unsafe"
 
func (r *PtraceRegs) PC() uint64 {
return uint64(uint32(r.Eip))
}
 
func (r *PtraceRegs) SetPC(pc uint64) {
r.Eip = int32(pc)
}
 
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
}
 
func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
}
/syscall_stubs.go
0,0 → 1,27
// Copyright 2010 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.
 
// These are stubs.
 
package syscall
 
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
z := -1
return uintptr(z), 0, uintptr(ENOSYS)
}
 
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
z := -1
return uintptr(z), 0, uintptr(ENOSYS)
}
 
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
z := -1
return uintptr(z), 0, uintptr(ENOSYS)
}
 
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
z := -1
return uintptr(z), 0, uintptr(ENOSYS)
}
/env_unix.go
0,0 → 1,109
// Copyright 2010 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.
 
// +build darwin freebsd linux netbsd openbsd
 
// Unix environment variables.
 
package syscall
 
import "sync"
 
var (
// envOnce guards initialization by copyenv, which populates env.
envOnce sync.Once
 
// envLock guards env and envs.
envLock sync.RWMutex
 
// env maps from an environment variable to its first occurrence in envs.
env map[string]int
 
// envs is provided by the runtime. elements are expected to be
// of the form "key=value".
Envs []string
)
 
// setenv_c is provided by the runtime, but is a no-op if cgo isn't
// loaded.
func setenv_c(k, v string)
 
func copyenv() {
env = make(map[string]int)
for i, s := range Envs {
for j := 0; j < len(s); j++ {
if s[j] == '=' {
key := s[:j]
if _, ok := env[key]; !ok {
env[key] = i
}
break
}
}
}
}
 
func Getenv(key string) (value string, found bool) {
envOnce.Do(copyenv)
if len(key) == 0 {
return "", false
}
 
envLock.RLock()
defer envLock.RUnlock()
 
i, ok := env[key]
if !ok {
return "", false
}
s := Envs[i]
for i := 0; i < len(s); i++ {
if s[i] == '=' {
return s[i+1:], true
}
}
return "", false
}
 
func Setenv(key, value string) error {
envOnce.Do(copyenv)
if len(key) == 0 {
return EINVAL
}
 
envLock.Lock()
defer envLock.Unlock()
 
i, ok := env[key]
kv := key + "=" + value
if ok {
Envs[i] = kv
} else {
i = len(Envs)
Envs = append(Envs, kv)
}
env[key] = i
setenv_c(key, value)
return nil
}
 
func Clearenv() {
envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
 
envLock.Lock()
defer envLock.Unlock()
 
env = make(map[string]int)
Envs = []string{}
// TODO(bradfitz): pass through to C
}
 
func Environ() []string {
envOnce.Do(copyenv)
envLock.RLock()
defer envLock.RUnlock()
a := make([]string, len(Envs))
copy(a, Envs)
return a
}
/libcall_irix.go
0,0 → 1,8
// Copyright 2011 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.
 
package syscall
 
//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
//ptrace(request int, pid Pid_t, addr *byte, data *byte) _C_long
/syscall_linux_alpha.go
0,0 → 1,57
// syscall_linux_alpha.go -- GNU/Linux ALPHA specific support
 
// Copyright 2011 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.
 
package syscall
 
import "unsafe"
 
type PtraceRegs struct {
R0 uint64
R1 uint64
R2 uint64
R3 uint64
R4 uint64
R5 uint64
R6 uint64
R7 uint64
R8 uint64
R19 uint64
R20 uint64
R21 uint64
R22 uint64
R23 uint64
R24 uint64
R25 uint64
R26 uint64
R27 uint64
R28 uint64
Hae uint64
Trap_a0 uint64
Trap_a1 uint64
Trap_a2 uint64
Ps uint64
Pc uint64
Gp uint64
R16 uint64
R17 uint64
R18 uint64
}
 
func (r *PtraceRegs) PC() uint64 {
return r.Pc
}
 
func (r *PtraceRegs) SetPC(pc uint64) {
r.Pc = pc
}
 
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
}
 
func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
}
/exec_windows.go
0,0 → 1,327
// 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.
 
// Fork, exec, wait, etc.
 
package syscall
 
import (
"sync"
"unicode/utf16"
"unsafe"
)
 
var ForkLock sync.RWMutex
 
// EscapeArg rewrites command line argument s as prescribed
// in http://msdn.microsoft.com/en-us/library/ms880421.
// This function returns "" (2 double quotes) if s is empty.
// Alternatively, these transformations are done:
// - every back slash (\) is doubled, but only if immediately
// followed by double quote (");
// - every double quote (") is escaped by back slash (\);
// - finally, s is wrapped with double quotes (arg -> "arg"),
// but only if there is space or tab inside s.
func EscapeArg(s string) string {
if len(s) == 0 {
return "\"\""
}
n := len(s)
hasSpace := false
for i := 0; i < len(s); i++ {
switch s[i] {
case '"', '\\':
n++
case ' ', '\t':
hasSpace = true
}
}
if hasSpace {
n += 2
}
if n == len(s) {
return s
}
 
qs := make([]byte, n)
j := 0
if hasSpace {
qs[j] = '"'
j++
}
slashes := 0
for i := 0; i < len(s); i++ {
switch s[i] {
default:
slashes = 0
qs[j] = s[i]
case '\\':
slashes++
qs[j] = s[i]
case '"':
for ; slashes > 0; slashes-- {
qs[j] = '\\'
j++
}
qs[j] = '\\'
j++
qs[j] = s[i]
}
j++
}
if hasSpace {
for ; slashes > 0; slashes-- {
qs[j] = '\\'
j++
}
qs[j] = '"'
j++
}
return string(qs[:j])
}
 
// makeCmdLine builds a command line out of args by escaping "special"
// characters and joining the arguments with spaces.
func makeCmdLine(args []string) string {
var s string
for _, v := range args {
if s != "" {
s += " "
}
s += EscapeArg(v)
}
return s
}
 
// createEnvBlock converts an array of environment strings into
// the representation required by CreateProcess: a sequence of NUL
// terminated strings followed by a nil.
// Last bytes are two UCS-2 NULs, or four NUL bytes.
func createEnvBlock(envv []string) *uint16 {
if len(envv) == 0 {
return &utf16.Encode([]rune("\x00\x00"))[0]
}
length := 0
for _, s := range envv {
length += len(s) + 1
}
length += 1
 
b := make([]byte, length)
i := 0
for _, s := range envv {
l := len(s)
copy(b[i:i+l], []byte(s))
copy(b[i+l:i+l+1], []byte{0})
i = i + l + 1
}
copy(b[i:i+1], []byte{0})
 
return &utf16.Encode([]rune(string(b)))[0]
}
 
func CloseOnExec(fd Handle) {
SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
}
 
func SetNonblock(fd Handle, nonblocking bool) (err error) {
return nil
}
 
// getFullPath retrieves the full path of the specified file.
// Just a wrapper for Windows GetFullPathName api.
func getFullPath(name string) (path string, err error) {
p := StringToUTF16Ptr(name)
buf := make([]uint16, 100)
n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
if err != nil {
return "", err
}
if n > uint32(len(buf)) {
// Windows is asking for bigger buffer.
buf = make([]uint16, n)
n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
if err != nil {
return "", err
}
if n > uint32(len(buf)) {
return "", EINVAL
}
}
return UTF16ToString(buf[:n]), nil
}
 
func isSlash(c uint8) bool {
return c == '\\' || c == '/'
}
 
func normalizeDir(dir string) (name string, err error) {
ndir, err := getFullPath(dir)
if err != nil {
return "", err
}
if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) {
// dir cannot have \\server\share\path form
return "", EINVAL
}
return ndir, nil
}
 
func volToUpper(ch int) int {
if 'a' <= ch && ch <= 'z' {
ch += 'A' - 'a'
}
return ch
}
 
func joinExeDirAndFName(dir, p string) (name string, err error) {
if len(p) == 0 {
return "", EINVAL
}
if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) {
// \\server\share\path form
return p, nil
}
if len(p) > 1 && p[1] == ':' {
// has drive letter
if len(p) == 2 {
return "", EINVAL
}
if isSlash(p[2]) {
return p, nil
} else {
d, err := normalizeDir(dir)
if err != nil {
return "", err
}
if volToUpper(int(p[0])) == volToUpper(int(d[0])) {
return getFullPath(d + "\\" + p[2:])
} else {
return getFullPath(p)
}
}
} else {
// no drive letter
d, err := normalizeDir(dir)
if err != nil {
return "", err
}
if isSlash(p[0]) {
return getFullPath(d[:2] + p)
} else {
return getFullPath(d + "\\" + p)
}
}
// we shouldn't be here
return "", EINVAL
}
 
type ProcAttr struct {
Dir string
Env []string
Files []Handle
Sys *SysProcAttr
}
 
type SysProcAttr struct {
HideWindow bool
CmdLine string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
}
 
var zeroProcAttr ProcAttr
var zeroSysProcAttr SysProcAttr
 
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
if len(argv0) == 0 {
return 0, 0, EWINDOWS
}
if attr == nil {
attr = &zeroProcAttr
}
sys := attr.Sys
if sys == nil {
sys = &zeroSysProcAttr
}
 
if len(attr.Files) > 3 {
return 0, 0, EWINDOWS
}
 
if len(attr.Dir) != 0 {
// StartProcess assumes that argv0 is relative to attr.Dir,
// because it implies Chdir(attr.Dir) before executing argv0.
// Windows CreateProcess assumes the opposite: it looks for
// argv0 relative to the current directory, and, only once the new
// process is started, it does Chdir(attr.Dir). We are adjusting
// for that difference here by making argv0 absolute.
var err error
argv0, err = joinExeDirAndFName(attr.Dir, argv0)
if err != nil {
return 0, 0, err
}
}
argv0p := StringToUTF16Ptr(argv0)
 
var cmdline string
// Windows CreateProcess takes the command line as a single string:
// use attr.CmdLine if set, else build the command line by escaping
// and joining each argument with spaces
if sys.CmdLine != "" {
cmdline = sys.CmdLine
} else {
cmdline = makeCmdLine(argv)
}
 
var argvp *uint16
if len(cmdline) != 0 {
argvp = StringToUTF16Ptr(cmdline)
}
 
var dirp *uint16
if len(attr.Dir) != 0 {
dirp = StringToUTF16Ptr(attr.Dir)
}
 
// Acquire the fork lock so that no other threads
// create new fds that are not yet close-on-exec
// before we fork.
ForkLock.Lock()
defer ForkLock.Unlock()
 
p, _ := GetCurrentProcess()
fd := make([]Handle, len(attr.Files))
for i := range attr.Files {
if attr.Files[i] > 0 {
err := DuplicateHandle(p, Handle(attr.Files[i]), p, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
if err != nil {
return 0, 0, err
}
defer CloseHandle(Handle(fd[i]))
}
}
si := new(StartupInfo)
si.Cb = uint32(unsafe.Sizeof(*si))
si.Flags = STARTF_USESTDHANDLES
if sys.HideWindow {
si.Flags |= STARTF_USESHOWWINDOW
si.ShowWindow = SW_HIDE
}
si.StdInput = fd[0]
si.StdOutput = fd[1]
si.StdErr = fd[2]
 
pi := new(ProcessInformation)
 
err = CreateProcess(argv0p, argvp, nil, nil, true, CREATE_UNICODE_ENVIRONMENT, createEnvBlock(attr.Env), dirp, si, pi)
if err != nil {
return 0, 0, err
}
defer CloseHandle(Handle(pi.Thread))
 
return int(pi.ProcessId), uintptr(pi.Process), nil
}
 
func Exec(argv0 string, argv []string, envv []string) (err error) {
return EWINDOWS
}
/libcall_posix_largefile.go
0,0 → 1,37
// 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.
 
// POSIX library calls on systems which use the largefile interface.
 
package syscall
 
//sys Fstat(fd int, stat *Stat_t) (err error)
//fstat64(fd int, stat *Stat_t) int
 
//sys Ftruncate(fd int, length int64) (err error)
//ftruncate64(fd int, length Offset_t) int
 
//sys Lstat(path string, stat *Stat_t) (err error)
//lstat64(path *byte, stat *Stat_t) int
 
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//mmap64(addr *byte, length Size_t, prot int, flags int, fd int, offset Offset_t) *byte
 
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//open64(path *byte, mode int, perm Mode_t) int
 
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//pread64(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t
 
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//pwrite64(fd int, buf *byte, count Size_t, offset Offset_t) Ssize_t
 
//sys Seek(fd int, offset int64, whence int) (off int64, err error)
//lseek64(fd int, offset Offset_t, whence int) Offset_t
 
//sys Stat(path string, stat *Stat_t) (err error)
//stat64(path *byte, stat *Stat_t) int
 
//sys Truncate(path string, length int64) (err error)
//truncate64(path *byte, length Offset_t) int
/bpf_bsd.go
0,0 → 1,169
// Copyright 2011 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.
 
// +build darwin freebsd netbsd openbsd
 
// Berkeley packet filter for BSD variants
 
package syscall
 
import (
"unsafe"
)
 
func BpfStmt(code, k int) *BpfInsn {
return &BpfInsn{Code: uint16(code), K: uint32(k)}
}
 
func BpfJump(code, k, jt, jf int) *BpfInsn {
return &BpfInsn{Code: uint16(code), Jt: uint8(jt), Jf: uint8(jf), K: uint32(k)}
}
 
func BpfBuflen(fd int) (int, error) {
var l int
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGBLEN, uintptr(unsafe.Pointer(&l)))
if err != 0 {
return 0, Errno(err)
}
return l, nil
}
 
func SetBpfBuflen(fd, l int) (int, error) {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSBLEN, uintptr(unsafe.Pointer(&l)))
if err != 0 {
return 0, Errno(err)
}
return l, nil
}
 
func BpfDatalink(fd int) (int, error) {
var t int
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGDLT, uintptr(unsafe.Pointer(&t)))
if err != 0 {
return 0, Errno(err)
}
return t, nil
}
 
func SetBpfDatalink(fd, t int) (int, error) {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSDLT, uintptr(unsafe.Pointer(&t)))
if err != 0 {
return 0, Errno(err)
}
return t, nil
}
 
func SetBpfPromisc(fd, m int) error {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCPROMISC, uintptr(unsafe.Pointer(&m)))
if err != 0 {
return Errno(err)
}
return nil
}
 
func FlushBpf(fd int) error {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCFLUSH, 0)
if err != 0 {
return Errno(err)
}
return nil
}
 
type ivalue struct {
name [IFNAMSIZ]byte
value int16
}
 
func BpfInterface(fd int, name string) (string, error) {
var iv ivalue
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGETIF, uintptr(unsafe.Pointer(&iv)))
if err != 0 {
return "", Errno(err)
}
return name, nil
}
 
func SetBpfInterface(fd int, name string) error {
var iv ivalue
copy(iv.name[:], []byte(name))
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETIF, uintptr(unsafe.Pointer(&iv)))
if err != 0 {
return Errno(err)
}
return nil
}
 
func BpfTimeout(fd int) (*Timeval, error) {
var tv Timeval
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGRTIMEOUT, uintptr(unsafe.Pointer(&tv)))
if err != 0 {
return nil, Errno(err)
}
return &tv, nil
}
 
func SetBpfTimeout(fd int, tv *Timeval) error {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSRTIMEOUT, uintptr(unsafe.Pointer(tv)))
if err != 0 {
return Errno(err)
}
return nil
}
 
func BpfStats(fd int) (*BpfStat, error) {
var s BpfStat
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGSTATS, uintptr(unsafe.Pointer(&s)))
if err != 0 {
return nil, Errno(err)
}
return &s, nil
}
 
func SetBpfImmediate(fd, m int) error {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCIMMEDIATE, uintptr(unsafe.Pointer(&m)))
if err != 0 {
return Errno(err)
}
return nil
}
 
func SetBpf(fd int, i []BpfInsn) error {
var p BpfProgram
p.Len = uint32(len(i))
p.Insns = (*BpfInsn)(unsafe.Pointer(&i[0]))
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSETF, uintptr(unsafe.Pointer(&p)))
if err != 0 {
return Errno(err)
}
return nil
}
 
func CheckBpfVersion(fd int) error {
var v BpfVersion
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCVERSION, uintptr(unsafe.Pointer(&v)))
if err != 0 {
return Errno(err)
}
if v.Major != BPF_MAJOR_VERSION || v.Minor != BPF_MINOR_VERSION {
return EINVAL
}
return nil
}
 
func BpfHeadercmpl(fd int) (int, error) {
var f int
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGHDRCMPLT, uintptr(unsafe.Pointer(&f)))
if err != 0 {
return 0, Errno(err)
}
return f, nil
}
 
func SetBpfHeadercmpl(fd, f int) error {
_, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSHDRCMPLT, uintptr(unsafe.Pointer(&f)))
if err != 0 {
return Errno(err)
}
return nil
}
/libcall_solaris_sparc64.go
0,0 → 1,10
// Copyright 2011 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.
 
package syscall
 
// 64-bit ptrace(3C) doesn't exist
func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
return ENOSYS
}
/errstr_linux.go
0,0 → 1,23
// errstr_rtems.go -- RTEMS specific error strings.
 
// Copyright 2010 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.
 
package syscall
 
import "unsafe"
 
//sysnb strerror_r(errnum int, b []byte) (errstr *byte)
//strerror_r(errnum int, b *byte, len Size_t) *byte
 
func Errstr(errnum int) string {
a := make([]byte, 128)
p := strerror_r(errnum, a)
b := (*[1000]byte)(unsafe.Pointer(p))
i := 0
for b[i] != 0 {
i++
}
return string(b[:i])
}
/route_darwin.go
0,0 → 1,77
// Copyright 2011 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.
 
// Routing sockets and messages for Darwin
 
package syscall
 
import (
"unsafe"
)
 
func (any *anyMessage) toRoutingMessage(buf []byte) RoutingMessage {
switch any.Type {
case RTM_ADD, RTM_DELETE, RTM_CHANGE, RTM_GET, RTM_LOSING, RTM_REDIRECT, RTM_MISS, RTM_LOCK, RTM_RESOLVE:
p := (*RouteMessage)(unsafe.Pointer(any))
rtm := &RouteMessage{}
rtm.Header = p.Header
rtm.Data = buf[SizeofRtMsghdr:any.Msglen]
return rtm
case RTM_IFINFO:
p := (*InterfaceMessage)(unsafe.Pointer(any))
ifm := &InterfaceMessage{}
ifm.Header = p.Header
ifm.Data = buf[SizeofIfMsghdr:any.Msglen]
return ifm
case RTM_NEWADDR, RTM_DELADDR:
p := (*InterfaceAddrMessage)(unsafe.Pointer(any))
ifam := &InterfaceAddrMessage{}
ifam.Header = p.Header
ifam.Data = buf[SizeofIfaMsghdr:any.Msglen]
return ifam
case RTM_NEWMADDR2, RTM_DELMADDR:
p := (*InterfaceMulticastAddrMessage)(unsafe.Pointer(any))
ifmam := &InterfaceMulticastAddrMessage{}
ifmam.Header = p.Header
ifmam.Data = buf[SizeofIfmaMsghdr2:any.Msglen]
return ifmam
}
return nil
}
 
// InterfaceMulticastAddrMessage represents a routing message
// containing network interface address entries.
type InterfaceMulticastAddrMessage struct {
Header IfmaMsghdr2
Data []byte
}
 
const rtaIfmaMask = RTA_GATEWAY | RTA_IFP | RTA_IFA
 
func (m *InterfaceMulticastAddrMessage) sockaddr() (sas []Sockaddr) {
if m.Header.Addrs&rtaIfmaMask == 0 {
return nil
}
 
buf := m.Data[:]
for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfmaMask&(1<<i) == 0 {
continue
}
rsa := (*RawSockaddr)(unsafe.Pointer(&buf[0]))
switch i {
case RTAX_IFA:
sa, e := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if e != nil {
return nil
}
sas = append(sas, sa)
case RTAX_GATEWAY, RTAX_IFP:
// nothing to do
}
buf = buf[rsaAlignOf(int(rsa.Len)):]
}
 
return sas
}
/errno.c
0,0 → 1,26
/* errno.c -- functions for getting and setting errno
 
Copyright 2010 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. */
 
#include <errno.h>
#include <stdint.h>
 
/* errno is typically a macro. These functions set
and get errno specific to the libc being used. */
 
uintptr_t GetErrno() asm ("libgo_syscall.syscall.GetErrno");
void SetErrno(uintptr_t) asm ("libgo_syscall.syscall.SetErrno");
 
uintptr_t
GetErrno()
{
return (uintptr_t) errno;
}
 
void
SetErrno(uintptr_t value)
{
errno = (int) value;
}
/exec_linux.go
0,0 → 1,248
// Copyright 2011 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.
 
// +build linux
 
package syscall
 
import (
"unsafe"
)
 
//sysnb raw_prctl(option int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err Errno)
//prctl(option int, arg2 _C_long, arg3 _C_long, arg4 _C_long, arg5 _C_long) int
 
type SysProcAttr struct {
Chroot string // Chroot.
Credential *Credential // Credential.
Ptrace bool // Enable tracing.
Setsid bool // Create session.
Setpgid bool // Set process group ID to new pid (SYSV setpgrp)
Setctty bool // Set controlling terminal to fd 0
Noctty bool // Detach fd 0 from controlling terminal
Pdeathsig int // Signal that the process will get when its parent dies (Linux only)
}
 
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
// If a dup or exec fails, write the errno error to pipe.
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
// Declare all variables at top in case any
// declarations require heap allocation (e.g., err1).
var (
r1 Pid_t
err1 Errno
nextfd int
i int
)
 
// guard against side effects of shuffling fds below.
fd := append([]int(nil), attr.Files...)
 
// About to call fork.
// No more allocation or calls of non-assembly functions.
r1, err1 = raw_fork()
if err1 != 0 {
return 0, err1
}
 
if r1 != 0 {
// parent; return PID
return int(r1), 0
}
 
// Fork succeeded, now in child.
 
// Parent death signal
if sys.Pdeathsig != 0 {
_, err1 = raw_prctl(PR_SET_PDEATHSIG, sys.Pdeathsig, 0, 0, 0)
if err1 != 0 {
goto childerror
}
 
// Signal self if parent is already dead. This might cause a
// duplicate signal in rare cases, but it won't matter when
// using SIGKILL.
ppid := Getppid()
if ppid == 1 {
pid = Getpid()
err2 := Kill(pid, sys.Pdeathsig)
if err2 != nil {
err1 = err2.(Errno)
goto childerror
}
}
}
 
// Enable tracing if requested.
if sys.Ptrace {
err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil)
if err1 != 0 {
goto childerror
}
}
 
// Session ID
if sys.Setsid {
err1 = raw_setsid()
if err1 != 0 {
goto childerror
}
}
 
// Set process group
if sys.Setpgid {
err1 = raw_setpgid(0, 0)
if err1 != 0 {
goto childerror
}
}
 
// Chroot
if chroot != nil {
err1 = raw_chroot(chroot)
if err1 != 0 {
goto childerror
}
}
 
// User and groups
if cred := sys.Credential; cred != nil {
ngroups := len(cred.Groups)
if ngroups == 0 {
err2 := setgroups(0, nil)
if err2 == nil {
err1 = 0
} else {
err1 = err2.(Errno)
}
} else {
groups := make([]Gid_t, ngroups)
for i, v := range cred.Groups {
groups[i] = Gid_t(v)
}
err2 := setgroups(ngroups, &groups[0])
if err2 == nil {
err1 = 0
} else {
err1 = err2.(Errno)
}
}
if err1 != 0 {
goto childerror
}
err2 := Setgid(int(cred.Gid))
if err2 != nil {
err1 = err2.(Errno)
goto childerror
}
err2 = Setuid(int(cred.Uid))
if err2 != nil {
err1 = err2.(Errno)
goto childerror
}
}
 
// Chdir
if dir != nil {
err1 = raw_chdir(dir)
if err1 != 0 {
goto childerror
}
}
 
// Pass 1: look for fd[i] < i and move those up above len(fd)
// so that pass 2 won't stomp on an fd it needs later.
nextfd = int(len(fd))
if pipe < nextfd {
err1 = raw_dup2(pipe, nextfd)
if err1 != 0 {
goto childerror
}
raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
pipe = nextfd
nextfd++
}
for i = 0; i < len(fd); i++ {
if fd[i] >= 0 && fd[i] < int(i) {
err1 = raw_dup2(fd[i], nextfd)
if err1 != 0 {
goto childerror
}
raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
fd[i] = nextfd
nextfd++
if nextfd == pipe { // don't stomp on pipe
nextfd++
}
}
}
 
// Pass 2: dup fd[i] down onto i.
for i = 0; i < len(fd); i++ {
if fd[i] == -1 {
raw_close(i)
continue
}
if fd[i] == int(i) {
// dup2(i, i) won't clear close-on-exec flag on Linux,
// probably not elsewhere either.
_, err1 = raw_fcntl(fd[i], F_SETFD, 0)
if err1 != 0 {
goto childerror
}
continue
}
// The new fd is created NOT close-on-exec,
// which is exactly what we want.
err1 = raw_dup2(fd[i], i)
if err1 != 0 {
goto childerror
}
}
 
// By convention, we don't close-on-exec the fds we are
// started with, so if len(fd) < 3, close 0, 1, 2 as needed.
// Programs that know they inherit fds >= 3 will need
// to set them close-on-exec.
for i = len(fd); i < 3; i++ {
raw_close(i)
}
 
// Detach fd 0 from tty
if sys.Noctty {
_, err1 = raw_ioctl(0, TIOCNOTTY, 0)
if err1 != 0 {
goto childerror
}
}
 
// Make fd 0 the tty
if sys.Setctty {
_, err1 = raw_ioctl(0, TIOCSCTTY, 0)
if err1 != 0 {
goto childerror
}
}
 
// Time to exec.
err1 = raw_execve(argv0, &argv[0], &envv[0])
 
childerror:
// send error code on pipe
raw_write(pipe, (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
for {
raw_exit(253)
}
 
// Calling panic is not actually safe,
// but the for loop above won't break
// and this shuts up the compiler.
panic("unreached")
}
/lsf_linux.go
0,0 → 1,78
// Copyright 2011 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 socket filter
 
package syscall
 
import (
"unsafe"
)
 
func LsfStmt(code, k int) *SockFilter {
return &SockFilter{Code: uint16(code), K: uint32(k)}
}
 
func LsfJump(code, k, jt, jf int) *SockFilter {
return &SockFilter{Code: uint16(code), Jt: uint8(jt), Jf: uint8(jf), K: uint32(k)}
}
 
func LsfSocket(ifindex, proto int) (int, error) {
var lsall SockaddrLinklayer
s, e := Socket(AF_PACKET, SOCK_RAW, proto)
if e != nil {
return 0, e
}
p := (*[2]byte)(unsafe.Pointer(&lsall.Protocol))
p[0] = byte(proto >> 8)
p[1] = byte(proto)
lsall.Ifindex = ifindex
e = Bind(s, &lsall)
if e != nil {
Close(s)
return 0, e
}
return s, nil
}
 
type iflags struct {
name [IFNAMSIZ]byte
flags uint16
}
 
func SetLsfPromisc(name string, m bool) error {
s, e := Socket(AF_INET, SOCK_DGRAM, 0)
if e != nil {
return e
}
defer Close(s)
var ifl iflags
copy(ifl.name[:], []byte(name))
_, _, ep := Syscall(SYS_IOCTL, uintptr(s), SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifl)))
if ep != 0 {
return Errno(ep)
}
if m {
ifl.flags |= uint16(IFF_PROMISC)
} else {
ifl.flags &= ^uint16(IFF_PROMISC)
}
_, _, ep = Syscall(SYS_IOCTL, uintptr(s), SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifl)))
if ep != 0 {
return Errno(ep)
}
return nil
}
 
func AttachLsf(fd int, i []SockFilter) error {
var p SockFprog
p.Len = uint16(len(i))
p.Filter = (*SockFilter)(unsafe.Pointer(&i[0]))
return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, uintptr(unsafe.Pointer(&p)), unsafe.Sizeof(p))
}
 
func DetachLsf(fd int) error {
var dummy int
return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, uintptr(unsafe.Pointer(&dummy)), unsafe.Sizeof(dummy))
}
/socket_linux.go
0,0 → 1,177
// socket_linux.go -- Socket handling specific to GNU/Linux.
 
// Copyright 2010 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.
 
package syscall
 
import "unsafe"
 
const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 28
const SizeofSockaddrUnix = 110
const SizeofSockaddrLinklayer = 20
const SizeofSockaddrNetlink = 12
 
type SockaddrLinklayer struct {
Protocol uint16
Ifindex int
Hatype uint16
Pkttype uint8
Halen uint8
Addr [8]byte
raw RawSockaddrLinklayer
}
 
func (sa *SockaddrLinklayer) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
return nil, 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]
}
return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrLinklayer, nil
}
 
type SockaddrNetlink struct {
Family uint16
Pad uint16
Pid uint32
Groups uint32
raw RawSockaddrNetlink
}
 
func (sa *SockaddrNetlink) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
sa.raw.Family = AF_NETLINK
sa.raw.Pad = sa.Pad
sa.raw.Pid = sa.Pid
sa.raw.Groups = sa.Groups
return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrNetlink, nil
}
 
type RawSockaddrInet4 struct {
Family uint16
Port uint16
Addr [4]byte /* in_addr */
Zero [8]uint8
}
 
func (sa *RawSockaddrInet4) setLen() Socklen_t {
return SizeofSockaddrInet4
}
 
type RawSockaddrInet6 struct {
Family uint16
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
 
func (sa *RawSockaddrInet6) setLen() Socklen_t {
return SizeofSockaddrInet6
}
 
type RawSockaddrUnix struct {
Family uint16
Path [108]int8
}
 
func (sa *RawSockaddrUnix) setLen(int) {
}
 
func (sa *RawSockaddrUnix) getLen() (int, error) {
if sa.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.
sa.Path[0] = '@'
}
 
// Assume path ends at NUL.
// This is not technically the GNU/Linux semantics for
// abstract Unix domain sockets--they are supposed
// to be uninterpreted fixed-size binary blobs--but
// everyone uses this convention.
n := 0
for n < len(sa.Path) - 3 && sa.Path[n] != 0 {
n++
}
 
return n, nil
}
 
type RawSockaddrLinklayer struct {
Family uint16
Protocol uint16
Ifindex int32
Hatype uint16
Pkttype uint8
Halen uint8
Addr [8]uint8
}
 
type RawSockaddrNetlink struct {
Family uint16
Pad uint16
Pid uint32
Groups uint32
}
 
type RawSockaddr struct {
Family uint16
Data [14]int8
}
 
// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) (err error) {
return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
}
 
func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
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
return sa, nil
 
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]
}
return sa, nil
}
return nil, EAFNOSUPPORT
}
 
//sysnb EpollCreate(size int) (fd int, err error)
//epoll_create(size int) int
 
//sysnb EpollCreate1(flags int) (fd int, err error)
//epoll_create1(flags int) int
 
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
//epoll_ctl(epfd int, op int, fd int, event *EpollEvent) int
 
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//epoll_wait(epfd int, events *EpollEvent, maxevents int, timeout int) int
/syscall.go
0,0 → 1,53
// 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.
 
// Package syscall contains an interface to the low-level operating system
// primitives. The details vary depending on the underlying system.
// Its primary use is inside other packages that provide a more portable
// interface to the system, such as "os", "time" and "net". Use those
// packages rather than this one if you can.
// For details of the functions and data types in this package consult
// the manuals for the appropriate operating system.
// These calls return err == nil to indicate success; otherwise
// err is an operating system error describing the failure.
// On most systems, that error has type syscall.Errno.
package syscall
 
import "unsafe"
 
// StringByteSlice returns a NUL-terminated slice of bytes
// containing the text of s.
func StringByteSlice(s string) []byte {
a := make([]byte, len(s)+1)
copy(a, s)
return a
}
 
// StringBytePtr returns a pointer to a NUL-terminated array of bytes
// containing the text of s.
func StringBytePtr(s string) *byte { return &StringByteSlice(s)[0] }
 
// Single-word zero for use when we need a valid pointer to 0 bytes.
// See mksyscall.pl.
var _zero uintptr
 
var dummy *byte
 
const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy))
 
func (ts *Timespec) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}
 
func (tv *Timeval) Unix() (sec int64, nsec int64) {
return int64(tv.Sec), int64(tv.Usec) * 1000
}
 
func (ts *Timespec) Nano() int64 {
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
}
 
func (tv *Timeval) Nano() int64 {
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.