mirror of
https://github.com/golang/go
synced 2024-11-18 13:04:46 -07:00
new syscall package: manually maintained files and scripts.
auto-generated files and deletions are in another CL. goals for new syscall: * automate as much as possible * do not let clients do unsafe things * use simple types (int not int64) * fewer files the files are renamed from foo_amd64_linux to foo_linux_amd64, both because it reads better (all the linux are related, all the amd64 less so) and because it made it easier to replace the existing ones. R=r DELTA=2336 (2260 added, 6 deleted, 70 changed) OCL=29709 CL=29723
This commit is contained in:
parent
9e0fec9c9c
commit
602a446b74
120
src/lib/syscall/PORT
Executable file
120
src/lib/syscall/PORT
Executable file
@ -0,0 +1,120 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# The syscall package provides access to the raw system call
|
||||||
|
# interface of the underlying operating system. Porting Go to
|
||||||
|
# a new architecture/operating system combination requires
|
||||||
|
# some manual effort, though there are tools that automate
|
||||||
|
# much of the process. The auto-generated files have names
|
||||||
|
# beginning with z.
|
||||||
|
#
|
||||||
|
# This script prints suggested commands to generate z files
|
||||||
|
# for the current system. Running those commands is not automatic.
|
||||||
|
# This script is documentation more than anything else.
|
||||||
|
#
|
||||||
|
# * asm_${GOOS}_${GOARCH}.s
|
||||||
|
#
|
||||||
|
# This hand-written assembly file implements system call dispatch.
|
||||||
|
# There are three entry points:
|
||||||
|
#
|
||||||
|
# func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
|
||||||
|
# func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
|
||||||
|
# func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
|
||||||
|
#
|
||||||
|
# The first and second are the standard ones; they differ only in
|
||||||
|
# how many arguments can be passed to the kernel.
|
||||||
|
# The third is for low-level use by the ForkExec wrapper;
|
||||||
|
# unlike the first two, it does not call into the scheduler to
|
||||||
|
# let it know that a system call is running.
|
||||||
|
#
|
||||||
|
# * syscall_${GOOS}.go
|
||||||
|
#
|
||||||
|
# This hand-written Go file implements system calls that need
|
||||||
|
# special handling and lists "//sys" comments giving prototypes
|
||||||
|
# for ones that can be auto-generated. Mksyscall reads those
|
||||||
|
# comments to generate the stubs.
|
||||||
|
#
|
||||||
|
# * syscall_${GOOS}_${GOARCH}.go
|
||||||
|
#
|
||||||
|
# Same as syscall_${GOOS}.go except that it contains code specific
|
||||||
|
# to ${GOOS} on one particular architecture.
|
||||||
|
#
|
||||||
|
# * types_${GOOS}.c
|
||||||
|
#
|
||||||
|
# This hand-written C file includes standard C headers and then
|
||||||
|
# creates typedef or enum names beginning with a dollar sign
|
||||||
|
# (use of $ in variable names is a gcc extension). The hardest
|
||||||
|
# part about preparing this file is figuring out which headers to
|
||||||
|
# include and which symbols need to be #defined to get the
|
||||||
|
# actual data structures that pass through to the kernel system calls.
|
||||||
|
# Some C libraries present alternate versions for binary compatibility
|
||||||
|
# and translate them on the way in and out of system calls, but
|
||||||
|
# there is almost always a #define that can get the real ones.
|
||||||
|
# See types_darwin.c and types_linux.c for examples.
|
||||||
|
#
|
||||||
|
# * types_${GOOS}_${GOARCH}.c
|
||||||
|
#
|
||||||
|
# Same as types_${GOOS}_${GOARCH}.go except that it contains
|
||||||
|
# definitions specific to ${GOOS} one one particular architecture.
|
||||||
|
#
|
||||||
|
# * zerror_${GOOS}_${GOARCH}.go
|
||||||
|
#
|
||||||
|
# This machine-generated file defines the system's error numbers,
|
||||||
|
# error strings, and signal numbers. The generator is "mkerrors".
|
||||||
|
# Usually no arguments are needed, but mkerrors will pass its
|
||||||
|
# arguments on to godefs.
|
||||||
|
#
|
||||||
|
# * zsyscall_${GOOS}_${GOARCH}.go
|
||||||
|
#
|
||||||
|
# Generated by mksyscall; see syscall_${GOOS}.go above.
|
||||||
|
#
|
||||||
|
# * zsysnum_${GOOS}_${GOARCH}.go
|
||||||
|
#
|
||||||
|
# Generated by mksysnum_${GOOS}.
|
||||||
|
#
|
||||||
|
# * ztypes_${GOOS}_${GOARCH}.go
|
||||||
|
#
|
||||||
|
# Generated by godefs; see types_${GOOS}.c above.
|
||||||
|
|
||||||
|
GOOSARCH="${GOOS}_${GOARCH}"
|
||||||
|
|
||||||
|
# defaults
|
||||||
|
mksyscall="mksyscall"
|
||||||
|
mkerrors="mkerrors"
|
||||||
|
|
||||||
|
case "$GOOSARCH" in
|
||||||
|
_* | *_ | _)
|
||||||
|
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
darwin_386)
|
||||||
|
mksyscall="mksyscall -l32"
|
||||||
|
mksysnum="mksysnum_darwin /home/rsc/pub/xnu-1228/bsd/kern/syscalls.master"
|
||||||
|
mktypes="godefs -gsyscall -f-m32"
|
||||||
|
;;
|
||||||
|
darwin_amd64)
|
||||||
|
mksysnum="mksysnum_darwin /home/rsc/pub/xnu-1228/bsd/kern/syscalls.master"
|
||||||
|
mktypes="godefs -gsyscall -f-m64"
|
||||||
|
mkerrors="mkerrors"
|
||||||
|
;;
|
||||||
|
linux_amd64)
|
||||||
|
mksysnum="mksysnum_linux /usr/include/asm/unistd_64.h"
|
||||||
|
mktypes="godefs -gsyscall -f-m64"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "$mkerrors >zerrors_$GOOSARCH.go"
|
||||||
|
echo "$mksyscall syscall_$GOOS.go syscall_$GOOSARCH.go >zsyscall_$GOOSARCH.go"
|
||||||
|
echo "$mksysnum >zsysnum_$GOOSARCH.go"
|
||||||
|
echo "$mktypes types_$GOOS.c types_$GOOSARCH.c >ztypes_$GOOSARCH.go"
|
||||||
|
|
||||||
|
port=$(ls *.go | grep -v _)
|
||||||
|
arch=$(ls *_$GOOSARCH.s *_$GOOSARCH.go *_$GOOS.go)
|
||||||
|
all=$(ls $port $arch) # sort them
|
||||||
|
echo gobuild $all
|
30
src/lib/syscall/errstr.go
Normal file
30
src/lib/syscall/errstr.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 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 "syscall"
|
||||||
|
|
||||||
|
func str(val int) string { // do it here rather than with fmt to avoid dependency
|
||||||
|
if val < 0 {
|
||||||
|
return "-" + str(-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:len(buf)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errstr(errno int) string {
|
||||||
|
if errno < 0 || errno >= int(len(errors)) {
|
||||||
|
return "error " + str(errno)
|
||||||
|
}
|
||||||
|
return errors[errno]
|
||||||
|
}
|
||||||
|
|
@ -61,10 +61,6 @@ import (
|
|||||||
|
|
||||||
var ForkLock sync.RWMutex
|
var ForkLock sync.RWMutex
|
||||||
|
|
||||||
func CloseOnExec(fd int64) {
|
|
||||||
Fcntl(fd, F_SETFD, FD_CLOEXEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert array of string to array
|
// Convert array of string to array
|
||||||
// of NUL-terminated byte pointer.
|
// of NUL-terminated byte pointer.
|
||||||
func StringArrayPtr(ss []string) []*byte {
|
func StringArrayPtr(ss []string) []*byte {
|
||||||
@ -76,36 +72,40 @@ func StringArrayPtr(ss []string) []*byte {
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
func Wait4(pid int64, wstatus *WaitStatus, options int64, rusage *Rusage)
|
func CloseOnExec(fd int) {
|
||||||
(wpid, err int64)
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
{
|
|
||||||
var s WaitStatus;
|
|
||||||
r1, r2, err1 := Syscall6(SYS_WAIT4,
|
|
||||||
pid,
|
|
||||||
int64(uintptr(unsafe.Pointer(&s))),
|
|
||||||
options,
|
|
||||||
int64(uintptr(unsafe.Pointer(rusage))), 0, 0);
|
|
||||||
if wstatus != nil {
|
|
||||||
*wstatus = s;
|
|
||||||
}
|
|
||||||
return r1, err1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetNonblock(fd int, nonblocking bool) (errno int) {
|
||||||
|
flag, err := fcntl(fd, F_GETFL, 0);
|
||||||
|
if err != 0 {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if nonblocking {
|
||||||
|
flag |= O_NONBLOCK;
|
||||||
|
} else {
|
||||||
|
flag &= ^O_NONBLOCK;
|
||||||
|
}
|
||||||
|
flag, err = fcntl(fd, F_SETFL, flag);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
|
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
|
||||||
// If a dup or exec fails, write the errno int64 to pipe.
|
// If a dup or exec fails, write the errno int to pipe.
|
||||||
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
|
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
|
||||||
// In the child, this function must not acquire any locks, because
|
// In the child, this function must not acquire any locks, because
|
||||||
// they might have been locked at the time of the fork. This means
|
// they might have been locked at the time of the fork. This means
|
||||||
// no rescheduling, no malloc calls, and no new stack segments.
|
// no rescheduling, no malloc calls, and no new stack segments.
|
||||||
// The calls to RawSyscall are okay because they are assembly
|
// The calls to RawSyscall are okay because they are assembly
|
||||||
// functions that do not grow the stack.
|
// functions that do not grow the stack.
|
||||||
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd []int64, pipe int64)
|
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd []int, pipe int)
|
||||||
(pid int64, err int64)
|
(pid int, err int)
|
||||||
{
|
{
|
||||||
// Declare all variables at top in case any
|
// Declare all variables at top in case any
|
||||||
// declarations require heap allocation (e.g., err1).
|
// declarations require heap allocation (e.g., err1).
|
||||||
var r1, r2, err1 int64;
|
var r1, r2, err1 uintptr;
|
||||||
var nextfd int64;
|
var nextfd int;
|
||||||
var i int;
|
var i int;
|
||||||
|
|
||||||
darwin := OS == "darwin";
|
darwin := OS == "darwin";
|
||||||
@ -114,7 +114,7 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
|
|||||||
// No more allocation or calls of non-assembly functions.
|
// No more allocation or calls of non-assembly functions.
|
||||||
r1, r2, err1 = RawSyscall(SYS_FORK, 0, 0, 0);
|
r1, r2, err1 = RawSyscall(SYS_FORK, 0, 0, 0);
|
||||||
if err1 != 0 {
|
if err1 != 0 {
|
||||||
return 0, err1
|
return 0, int(err1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// On Darwin:
|
// On Darwin:
|
||||||
@ -127,38 +127,38 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
|
|||||||
|
|
||||||
if r1 != 0 {
|
if r1 != 0 {
|
||||||
// parent; return PID
|
// parent; return PID
|
||||||
return r1, 0
|
return int(r1), 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fork succeeded, now in child.
|
// Fork succeeded, now in child.
|
||||||
|
|
||||||
// Chdir
|
// Chdir
|
||||||
if dir != nil {
|
if dir != nil {
|
||||||
r1, r2, err = RawSyscall(SYS_CHDIR, int64(uintptr(unsafe.Pointer(dir))), 0, 0);
|
r1, r2, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0);
|
||||||
if err != 0 {
|
if err1 != 0 {
|
||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass 1: look for fd[i] < i and move those up above len(fd)
|
// 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.
|
// so that pass 2 won't stomp on an fd it needs later.
|
||||||
nextfd = int64(len(fd));
|
nextfd = int(len(fd));
|
||||||
if pipe < nextfd {
|
if pipe < nextfd {
|
||||||
r1, r2, err = RawSyscall(SYS_DUP2, pipe, nextfd, 0);
|
r1, r2, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0);
|
||||||
if err != 0 {
|
if err1 != 0 {
|
||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
RawSyscall(SYS_FCNTL, nextfd, F_SETFD, FD_CLOEXEC);
|
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC);
|
||||||
pipe = nextfd;
|
pipe = nextfd;
|
||||||
nextfd++;
|
nextfd++;
|
||||||
}
|
}
|
||||||
for i = 0; i < len(fd); i++ {
|
for i = 0; i < len(fd); i++ {
|
||||||
if fd[i] >= 0 && fd[i] < int64(i) {
|
if fd[i] >= 0 && fd[i] < int(i) {
|
||||||
r1, r2, err = RawSyscall(SYS_DUP2, fd[i], nextfd, 0);
|
r1, r2, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0);
|
||||||
if err != 0 {
|
if err1 != 0 {
|
||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
RawSyscall(SYS_FCNTL, nextfd, F_SETFD, FD_CLOEXEC);
|
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC);
|
||||||
fd[i] = nextfd;
|
fd[i] = nextfd;
|
||||||
nextfd++;
|
nextfd++;
|
||||||
if nextfd == pipe { // don't stomp on pipe
|
if nextfd == pipe { // don't stomp on pipe
|
||||||
@ -170,22 +170,22 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
|
|||||||
// Pass 2: dup fd[i] down onto i.
|
// Pass 2: dup fd[i] down onto i.
|
||||||
for i = 0; i < len(fd); i++ {
|
for i = 0; i < len(fd); i++ {
|
||||||
if fd[i] == -1 {
|
if fd[i] == -1 {
|
||||||
RawSyscall(SYS_CLOSE, int64(i), 0, 0);
|
RawSyscall(SYS_CLOSE, uintptr(i), 0, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if fd[i] == int64(i) {
|
if fd[i] == int(i) {
|
||||||
// dup2(i, i) won't clear close-on-exec flag on Linux,
|
// dup2(i, i) won't clear close-on-exec flag on Linux,
|
||||||
// probably not elsewhere either.
|
// probably not elsewhere either.
|
||||||
r1, r2, err = RawSyscall(SYS_FCNTL, fd[i], F_SETFD, 0);
|
r1, r2, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0);
|
||||||
if err != 0 {
|
if err1 != 0 {
|
||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// The new fd is created NOT close-on-exec,
|
// The new fd is created NOT close-on-exec,
|
||||||
// which is exactly what we want.
|
// which is exactly what we want.
|
||||||
r1, r2, err = RawSyscall(SYS_DUP2, fd[i], int64(i), 0);
|
r1, r2, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(i), 0);
|
||||||
if err != 0 {
|
if err1 != 0 {
|
||||||
goto childerror;
|
goto childerror;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,18 +195,18 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
|
|||||||
// Programs that know they inherit fds >= 3 will need
|
// Programs that know they inherit fds >= 3 will need
|
||||||
// to set them close-on-exec.
|
// to set them close-on-exec.
|
||||||
for i = len(fd); i < 3; i++ {
|
for i = len(fd); i < 3; i++ {
|
||||||
RawSyscall(SYS_CLOSE, int64(i), 0, 0);
|
RawSyscall(SYS_CLOSE, uintptr(i), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time to exec.
|
// Time to exec.
|
||||||
r1, r2, err1 = RawSyscall(SYS_EXECVE,
|
r1, r2, err1 = RawSyscall(SYS_EXECVE,
|
||||||
int64(uintptr(unsafe.Pointer(argv0))),
|
uintptr(unsafe.Pointer(argv0)),
|
||||||
int64(uintptr(unsafe.Pointer(&argv[0]))),
|
uintptr(unsafe.Pointer(&argv[0])),
|
||||||
int64(uintptr(unsafe.Pointer(&envv[0]))));
|
uintptr(unsafe.Pointer(&envv[0])));
|
||||||
|
|
||||||
childerror:
|
childerror:
|
||||||
// send error code on pipe
|
// send error code on pipe
|
||||||
RawSyscall(SYS_WRITE, pipe, int64(uintptr(unsafe.Pointer(&err1))), 8);
|
RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)));
|
||||||
for {
|
for {
|
||||||
RawSyscall(SYS_EXIT, 253, 0, 0);
|
RawSyscall(SYS_EXIT, 253, 0, 0);
|
||||||
}
|
}
|
||||||
@ -218,12 +218,13 @@ childerror:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Combination of fork and exec, careful to be thread safe.
|
// Combination of fork and exec, careful to be thread safe.
|
||||||
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64)
|
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
|
||||||
(pid int64, err int64)
|
(pid int, err int)
|
||||||
{
|
{
|
||||||
var p [2]int64;
|
var p [2]int;
|
||||||
var r1 int64;
|
var r1 int;
|
||||||
var n, err1 int64;
|
var n int;
|
||||||
|
var err1 uintptr;
|
||||||
var wstatus WaitStatus;
|
var wstatus WaitStatus;
|
||||||
|
|
||||||
p[0] = -1;
|
p[0] = -1;
|
||||||
@ -244,13 +245,14 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64
|
|||||||
ForkLock.Lock();
|
ForkLock.Lock();
|
||||||
|
|
||||||
// Allocate child status pipe close on exec.
|
// Allocate child status pipe close on exec.
|
||||||
if r1, err = Pipe(&p); err != 0 {
|
if err = Pipe(&p); err != 0 {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if r1, err = Fcntl(p[0], F_SETFD, FD_CLOEXEC); err != 0 {
|
var val int;
|
||||||
|
if val, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != 0 {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if r1, err = Fcntl(p[1], F_SETFD, FD_CLOEXEC); err != 0 {
|
if val, err = fcntl(p[1], F_SETFD, FD_CLOEXEC); err != 0 {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,11 +271,11 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64
|
|||||||
|
|
||||||
// Read child error status from pipe.
|
// Read child error status from pipe.
|
||||||
Close(p[1]);
|
Close(p[1]);
|
||||||
n, r1, err = Syscall(SYS_READ, p[0], int64(uintptr(unsafe.Pointer(&err1))), 8);
|
n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), unsafe.Sizeof(err1));
|
||||||
Close(p[0]);
|
Close(p[0]);
|
||||||
if err != 0 || n != 0 {
|
if err != 0 || n != 0 {
|
||||||
if n == 8 {
|
if n == unsafe.Sizeof(err1) {
|
||||||
err = err1;
|
err = int(err1);
|
||||||
}
|
}
|
||||||
if err == 0 {
|
if err == 0 {
|
||||||
err = EPIPE;
|
err = EPIPE;
|
||||||
@ -293,11 +295,11 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ordinary exec.
|
// Ordinary exec.
|
||||||
func Exec(argv0 string, argv []string, envv []string) (err int64) {
|
func Exec(argv0 string, argv []string, envv []string) (err int) {
|
||||||
r1, r2, err1 := RawSyscall(SYS_EXECVE,
|
r1, r2, err1 := RawSyscall(SYS_EXECVE,
|
||||||
int64(uintptr(unsafe.Pointer(StringBytePtr(argv0)))),
|
uintptr(unsafe.Pointer(StringBytePtr(argv0))),
|
||||||
int64(uintptr(unsafe.Pointer(&StringArrayPtr(argv)[0]))),
|
uintptr(unsafe.Pointer(&StringArrayPtr(argv)[0])),
|
||||||
int64(uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0]))));
|
uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0])));
|
||||||
return err1;
|
return int(err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
94
src/lib/syscall/mkerrors
Executable file
94
src/lib/syscall/mkerrors
Executable file
@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
# Generate Go code listing error values (ENAMETOOLONG etc)
|
||||||
|
# and signal values (SIGALRM etc). They're unrelated except
|
||||||
|
# that we use the same method for finding them.
|
||||||
|
|
||||||
|
errors=$(
|
||||||
|
echo '#include <errno.h>' |
|
||||||
|
# The gcc command line prints all the #defines
|
||||||
|
# it encounters while processing the input
|
||||||
|
gcc -x c - -E -dM |
|
||||||
|
egrep -h '#define E[A-Z0-9_]+ ' $files |
|
||||||
|
sed 's/#define //; s/ .*//'
|
||||||
|
)
|
||||||
|
|
||||||
|
signals=$(
|
||||||
|
echo '#include <sys/signal.h>' |
|
||||||
|
gcc -x c - -E -dM |
|
||||||
|
egrep -h '#define SIG[^_]' |
|
||||||
|
egrep -v '#define (SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))' |
|
||||||
|
sed 's/#define //; s/ .*//'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Write godefs input.
|
||||||
|
(
|
||||||
|
echo '#include <errno.h>'
|
||||||
|
echo '#include <signal.h>'
|
||||||
|
echo 'enum {'
|
||||||
|
for i in $errors $signals
|
||||||
|
do
|
||||||
|
echo '$'"$i = $i,"
|
||||||
|
done
|
||||||
|
echo '};'
|
||||||
|
) >_errors.c
|
||||||
|
|
||||||
|
echo '// mkerrors' "$@"
|
||||||
|
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
|
||||||
|
echo
|
||||||
|
godefs -gsyscall "$@" _errors.c
|
||||||
|
|
||||||
|
# Run C program to print error strings.
|
||||||
|
(
|
||||||
|
echo "
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
|
|
||||||
|
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
|
||||||
|
|
||||||
|
int errors[] = {
|
||||||
|
"
|
||||||
|
for i in $errors
|
||||||
|
do
|
||||||
|
echo ' '$i,
|
||||||
|
done
|
||||||
|
|
||||||
|
echo '
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
int i, j, e;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
printf("\n\n// Error table\n");
|
||||||
|
printf("var errors = [...]string {\n");
|
||||||
|
for(i=0; i<nelem(errors); i++) {
|
||||||
|
e = errors[i];
|
||||||
|
for(j=0; j<i; j++)
|
||||||
|
if(errors[j] == e) // duplicate value
|
||||||
|
goto next;
|
||||||
|
strcpy(buf, strerror(e));
|
||||||
|
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
|
||||||
|
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
|
||||||
|
buf[0] += a - A;
|
||||||
|
printf("\t%d: \"%s\",\n", e, buf);
|
||||||
|
next:;
|
||||||
|
}
|
||||||
|
printf("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
'
|
||||||
|
) >_errors.c
|
||||||
|
|
||||||
|
gcc -o _errors _errors.c && ./_errors
|
||||||
|
rm -f _errors.c _errors
|
170
src/lib/syscall/mksyscall
Executable file
170
src/lib/syscall/mksyscall
Executable file
@ -0,0 +1,170 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# This program reads a file containing function prototypes
|
||||||
|
# (like syscall_darwin.go) and generates system call bodies.
|
||||||
|
# The prototypes 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 number, it must be named errno.
|
||||||
|
|
||||||
|
$cmdline = "mksyscall " . join(' ', @ARGV);
|
||||||
|
$errors = 0;
|
||||||
|
$_32bit = 0;
|
||||||
|
|
||||||
|
if($ARGV[0] eq "-b32") {
|
||||||
|
$_32bit = "big-endian";
|
||||||
|
shift;
|
||||||
|
} elsif($ARGV[0] eq "-l32") {
|
||||||
|
$_32bit = "little-endian";
|
||||||
|
shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($ARGV[0] =~ /^-/) {
|
||||||
|
print STDERR "usage: mksyscall [-b32 | -l32] [file ...]\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parseparamlist($) {
|
||||||
|
my ($list) = @_;
|
||||||
|
$list =~ s/^\s*//;
|
||||||
|
$list =~ s/\s*$//;
|
||||||
|
if($list eq "") {
|
||||||
|
return ();
|
||||||
|
}
|
||||||
|
return split(/\s*,\s*/, $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parseparam($) {
|
||||||
|
my ($p) = @_;
|
||||||
|
if($p !~ /^(\S*) (\S*)$/) {
|
||||||
|
print STDERR "$ARGV:$.: malformed parameter: $p\n";
|
||||||
|
$errors = 1;
|
||||||
|
return ("xx", "int");
|
||||||
|
}
|
||||||
|
return ($1, $2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$text = "";
|
||||||
|
while(<>) {
|
||||||
|
chomp;
|
||||||
|
s/\s+/ /g;
|
||||||
|
s/^\s+//;
|
||||||
|
s/\s+$//;
|
||||||
|
next if !/^\/\/sys /;
|
||||||
|
|
||||||
|
# Line must be of the form
|
||||||
|
# func Open(path string, mode int, perm int) (fd int, errno int)
|
||||||
|
# Split into name, in params, out params.
|
||||||
|
if(!/^\/\/sys (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(SYS_[A-Z0-9_]+))?$/) {
|
||||||
|
print STDERR "$ARGV:$.: malformed //sys declaration\n";
|
||||||
|
$errors = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
my ($func, $in, $out, $sysname) = ($1, $2, $3, $4);
|
||||||
|
|
||||||
|
# Split argument lists on comma.
|
||||||
|
my @in = parseparamlist($in);
|
||||||
|
my @out = parseparamlist($out);
|
||||||
|
|
||||||
|
# Go function header.
|
||||||
|
$text .= sprintf "func %s(%s) (%s) {\n", $func, join(', ', @in), join(', ', @out);
|
||||||
|
|
||||||
|
# Prepare arguments to Syscall.
|
||||||
|
my @args = ();
|
||||||
|
my $n = 0;
|
||||||
|
foreach my $p (@in) {
|
||||||
|
my ($name, $type) = parseparam($p);
|
||||||
|
if($type =~ /^\*/) {
|
||||||
|
push @args, "uintptr(unsafe.Pointer($name))";
|
||||||
|
} elsif($type eq "string") {
|
||||||
|
push @args, "uintptr(unsafe.Pointer(StringBytePtr($name)))";
|
||||||
|
} elsif($type =~ /^\[\](.*)/) {
|
||||||
|
# Convert slice into pointer, length.
|
||||||
|
# Have to be careful not to take address of &a[0] if len == 0:
|
||||||
|
# pass nil in that case.
|
||||||
|
$text .= "\tvar _p$n *$1;\n";
|
||||||
|
$text .= "\tif len($name) > 0 { _p$n = \&${name}[0]; }\n";
|
||||||
|
push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
|
||||||
|
$n++;
|
||||||
|
} elsif($type eq "int64" && $_32bit ne "") {
|
||||||
|
if($_32bit eq "big-endian") {
|
||||||
|
push @args, "uintptr($name >> 32)", "uintptr($name)";
|
||||||
|
} else {
|
||||||
|
push @args, "uintptr($name)", "uintptr($name >> 32)";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
push @args, "uintptr($name)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine which form to use; pad args with zeros.
|
||||||
|
my $asm = "Syscall";
|
||||||
|
if(@args <= 3) {
|
||||||
|
while(@args < 3) {
|
||||||
|
push @args, "0";
|
||||||
|
}
|
||||||
|
} elsif(@args <= 6) {
|
||||||
|
$asm = "Syscall6";
|
||||||
|
while(@args < 6) {
|
||||||
|
push @args, "0";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# System call number.
|
||||||
|
if($sysname eq "") {
|
||||||
|
$sysname = "SYS_$func";
|
||||||
|
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar
|
||||||
|
$sysname =~ y/a-z/A-Z/;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Actual call.
|
||||||
|
my $args = join(', ', @args);
|
||||||
|
$text .= "\tr0, r1, e1 := $asm($sysname, $args);\n";
|
||||||
|
|
||||||
|
# Assign return values.
|
||||||
|
for(my $i=0; $i<@out; $i++) {
|
||||||
|
my $p = $out[$i];
|
||||||
|
my ($name, $type) = parseparam($p);
|
||||||
|
my $reg = "";
|
||||||
|
if($name eq "errno") {
|
||||||
|
$reg = "e1";
|
||||||
|
} else {
|
||||||
|
$reg = sprintf("r%d", $i);
|
||||||
|
}
|
||||||
|
if($type eq "bool") {
|
||||||
|
$reg = "$reg != 0";
|
||||||
|
}
|
||||||
|
$text .= "\t$name = $type($reg);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$text .= "\treturn;\n";
|
||||||
|
$text .= "}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($errors) {
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
print <<EOF;
|
||||||
|
// $cmdline
|
||||||
|
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall";
|
||||||
|
"unsafe";
|
||||||
|
)
|
||||||
|
|
||||||
|
$text
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 0;
|
38
src/lib/syscall/mksysnum_darwin
Executable file
38
src/lib/syscall/mksysnum_darwin
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# Generate system call table for Darwin from master list
|
||||||
|
# (for example, xnu-1228/bsd/kern/syscalls.master).
|
||||||
|
|
||||||
|
my $command = "mksysnum_darwin " . join(' ', @ARGV);
|
||||||
|
|
||||||
|
print <<EOF;
|
||||||
|
// $command
|
||||||
|
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
const (
|
||||||
|
EOF
|
||||||
|
|
||||||
|
while(<>){
|
||||||
|
if(/^([0-9]+)\s+ALL\s+({ \S+\s+(\w+).*})/){
|
||||||
|
my $num = $1;
|
||||||
|
my $proto = $2;
|
||||||
|
my $name = "SYS_$3";
|
||||||
|
$name =~ y/a-z/A-Z/;
|
||||||
|
|
||||||
|
# There are multiple entries for enosys and nosys, so comment them out.
|
||||||
|
if($name =~ /^SYS_E?NOSYS$/){
|
||||||
|
$name = "// $name";
|
||||||
|
}
|
||||||
|
|
||||||
|
print " $name = $num; // $proto\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print <<EOF;
|
||||||
|
)
|
||||||
|
EOF
|
@ -11,22 +11,27 @@
|
|||||||
// the manuals for the appropriate operating system.
|
// the manuals for the appropriate operating system.
|
||||||
package syscall
|
package syscall
|
||||||
|
|
||||||
/*
|
import (
|
||||||
* Foundation of system call interface.
|
"syscall";
|
||||||
*/
|
"unsafe";
|
||||||
|
)
|
||||||
|
|
||||||
func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
|
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||||
func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
|
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||||
func RawSyscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
|
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||||
|
|
||||||
/*
|
// StringByteSlice returns a NUL-terminated slice of bytes
|
||||||
* Used to convert file names to byte arrays for passing to kernel,
|
// containing the text of s.
|
||||||
* but useful elsewhere too.
|
func StringByteSlice(s string) []byte {
|
||||||
*/
|
|
||||||
func StringBytePtr(s string) *byte {
|
|
||||||
a := make([]byte, len(s)+1);
|
a := make([]byte, len(s)+1);
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
a[i] = s[i];
|
a[i] = s[i];
|
||||||
}
|
}
|
||||||
return &a[0];
|
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];
|
||||||
}
|
}
|
||||||
|
674
src/lib/syscall/syscall_darwin.go
Normal file
674
src/lib/syscall/syscall_darwin.go
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Darwin system calls.
|
||||||
|
// This file is compiled as ordinary Go code,
|
||||||
|
// but it is also input to mksyscall,
|
||||||
|
// which parses the //sys lines and generates system call stubs.
|
||||||
|
// Note that sometimes we use a lowercase //sys name and
|
||||||
|
// wrap it in our own nicer implementation.
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall";
|
||||||
|
"unsafe";
|
||||||
|
)
|
||||||
|
|
||||||
|
const OS = "darwin"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pseudo-system calls
|
||||||
|
*/
|
||||||
|
// The const provides a compile-time constant so clients
|
||||||
|
// can adjust to whether there is a working Getwd and avoid
|
||||||
|
// even linking this function into the binary. See ../os/getwd.go.
|
||||||
|
const ImplementsGetwd = false
|
||||||
|
|
||||||
|
func Getwd() (string, int) {
|
||||||
|
return "", ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sys getgroups(ngid int, gid *_Gid_t) (n int, errno int)
|
||||||
|
//sys setgroups(ngid int, gid *_Gid_t) (errno int)
|
||||||
|
|
||||||
|
func Getgroups() (gids []int, errno int) {
|
||||||
|
n, err := getgroups(0, nil);
|
||||||
|
if err != 0 {
|
||||||
|
return nil, errno;
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return nil, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check group count. Max is 16 on BSD.
|
||||||
|
if n < 0 || n > 1000 {
|
||||||
|
return nil, EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a := make([]_Gid_t, n);
|
||||||
|
n, err = getgroups(n, &a[0]);
|
||||||
|
if err != 0 {
|
||||||
|
return nil, errno;
|
||||||
|
}
|
||||||
|
gids = make([]int, n);
|
||||||
|
for i, v := range a[0:n] {
|
||||||
|
gids[i] = int(v);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setgroups(gids []int) (errno int) {
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait status is 7 bits at bottom, either 0 (exited),
|
||||||
|
// 0x7F (stopped), or a signal number that caused an exit.
|
||||||
|
// The 0x80 bit is whether there was a core dump.
|
||||||
|
// An extra number (exit code, signal causing a stop)
|
||||||
|
// is in the high bits.
|
||||||
|
|
||||||
|
type WaitStatus uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
mask = 0x7F;
|
||||||
|
core = 0x80;
|
||||||
|
shift = 8;
|
||||||
|
|
||||||
|
exited = 0;
|
||||||
|
stopped = 0x7F;
|
||||||
|
)
|
||||||
|
|
||||||
|
func (w WaitStatus) Exited() bool {
|
||||||
|
return w&mask == exited;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) ExitStatus() int {
|
||||||
|
if w&mask != exited {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return int(w >> shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Signaled() bool {
|
||||||
|
return w&mask != stopped && w&mask != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Signal() int {
|
||||||
|
sig := int(w & mask);
|
||||||
|
if sig == stopped || sig == 0 {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) CoreDump() bool {
|
||||||
|
return w.Signaled() && w&core != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Stopped() bool {
|
||||||
|
return w&mask == stopped && w>>shift != SIGSTOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Continued() bool {
|
||||||
|
return w&mask == stopped && w>>shift == SIGSTOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) StopSignal() int {
|
||||||
|
if !w.Stopped() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return int(w >> shift) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, errno int)
|
||||||
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
|
||||||
|
var status _C_int;
|
||||||
|
wpid, errno = wait4(pid, &status, options, rusage);
|
||||||
|
if wstatus != nil {
|
||||||
|
*wstatus = WaitStatus(status);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys pipe() (r int, w int, errno int)
|
||||||
|
func Pipe(p []int) (errno int) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
p[0], p[1], errno = pipe();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(rsc): How does 386 return an int64 newoffset?
|
||||||
|
//sys lseek(fd int, offset int64, whence int) (newoffset uintptr, errno int)
|
||||||
|
func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
|
||||||
|
n, e := lseek(fd, offset, whence);
|
||||||
|
return int64(n), e;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys gettimeofday(tp *Timeval) (sec int64, usec int32, errno int)
|
||||||
|
func Gettimeofday(tv *Timeval) (errno int) {
|
||||||
|
// The tv passed to gettimeofday must be non-nil
|
||||||
|
// but is otherwise unused. The answers come back
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv);
|
||||||
|
tv.Sec = sec;
|
||||||
|
tv.Usec = usec;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sleep(ns int64) (errno int) {
|
||||||
|
tv := NsecToTimeval(ns);
|
||||||
|
return Select(0, nil, nil, nil, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int)
|
||||||
|
//sys bind(s int, addr uintptr, addrlen _Socklen) (errno int)
|
||||||
|
//sys connect(s int, addr uintptr, addrlen _Socklen) (errno int)
|
||||||
|
//sys socket(domain int, typ int, proto int) (fd int, errno int)
|
||||||
|
//sys setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int)
|
||||||
|
|
||||||
|
// For testing: clients can set this flag to force
|
||||||
|
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||||
|
var SocketDisableIPv6 bool
|
||||||
|
|
||||||
|
type Sockaddr interface {
|
||||||
|
sockaddr() (ptr uintptr, len _Socklen, errno int); // lowercase; only we can define Sockaddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrInet4 struct {
|
||||||
|
Port int;
|
||||||
|
Addr [4]byte;
|
||||||
|
raw RawSockaddrInet4;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrInet4) sockaddr() (uintptr, _Socklen, int) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return 0, 0, EINVAL;
|
||||||
|
}
|
||||||
|
sa.raw.Len = SizeofSockaddrInet4;
|
||||||
|
sa.raw.Family = AF_INET;
|
||||||
|
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 uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrInet6 struct {
|
||||||
|
Port int;
|
||||||
|
Addr [16]byte;
|
||||||
|
raw RawSockaddrInet6;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrInet6) sockaddr() (uintptr, _Socklen, int) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return 0, 0, EINVAL;
|
||||||
|
}
|
||||||
|
sa.raw.Len = SizeofSockaddrInet6;
|
||||||
|
sa.raw.Family = AF_INET6;
|
||||||
|
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 uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrUnix struct {
|
||||||
|
Name string;
|
||||||
|
raw RawSockaddrUnix;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
|
||||||
|
name := sa.Name;
|
||||||
|
n := len(name);
|
||||||
|
if n >= len(sa.raw.Path) || n == 0 {
|
||||||
|
return 0, 0, EINVAL;
|
||||||
|
}
|
||||||
|
sa.raw.Len = byte(3 + n); // 2 for Family, Len; 1 for NUL
|
||||||
|
sa.raw.Family = AF_UNIX;
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
sa.raw.Path[i] = int8(name[i]);
|
||||||
|
}
|
||||||
|
return uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
|
||||||
|
switch rsa.Addr.Family {
|
||||||
|
case AF_UNIX:
|
||||||
|
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa));
|
||||||
|
if pp.Len < 3 || pp.Len > SizeofSockaddrUnix {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
sa := new(SockaddrUnix);
|
||||||
|
n := int(pp.Len) - 3; // subtract leading Family, Len, terminating NUL
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if pp.Path[i] == 0 {
|
||||||
|
// found early NUL; assume Len is overestimating
|
||||||
|
n = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]));
|
||||||
|
sa.Name = string(bytes[0:n]);
|
||||||
|
return sa, 0;
|
||||||
|
|
||||||
|
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, 0;
|
||||||
|
|
||||||
|
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, 0;
|
||||||
|
}
|
||||||
|
return nil, EAFNOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
|
||||||
|
var rsa RawSockaddrAny;
|
||||||
|
var len _Socklen = SizeofSockaddrAny;
|
||||||
|
nfd, errno = accept(fd, &rsa, &len);
|
||||||
|
if errno != 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sa, errno = anyToSockaddr(&rsa);
|
||||||
|
if errno != 0 {
|
||||||
|
Close(nfd);
|
||||||
|
nfd = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bind(fd int, sa Sockaddr) (errno int) {
|
||||||
|
ptr, n, err := sa.sockaddr();
|
||||||
|
if err != 0 {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return bind(fd, ptr, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Connect(fd int, sa Sockaddr) (errno int) {
|
||||||
|
ptr, n, err := sa.sockaddr();
|
||||||
|
if err != 0 {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return connect(fd, ptr, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Socket(domain, typ, proto int) (fd, errno int) {
|
||||||
|
if domain == AF_INET6 && SocketDisableIPv6 {
|
||||||
|
return -1, EAFNOSUPPORT
|
||||||
|
}
|
||||||
|
fd, errno = socket(domain, typ, proto);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptInt(fd, level, opt int, value int) (errno int) {
|
||||||
|
var n = int32(value);
|
||||||
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
|
||||||
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), unsafe.Sizeof(*tv));
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||||
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), unsafe.Sizeof(*l));
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, timeout *Timespec) (n int, errno int)
|
||||||
|
func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, errno int) {
|
||||||
|
var change, event uintptr;
|
||||||
|
if len(changes) > 0 {
|
||||||
|
change = uintptr(unsafe.Pointer(&changes[0]));
|
||||||
|
}
|
||||||
|
if len(events) > 0 {
|
||||||
|
event = uintptr(unsafe.Pointer(&events[0]));
|
||||||
|
}
|
||||||
|
return kevent(kq, change, len(changes), event, len(events), timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: wrap
|
||||||
|
// Acct(name nil-string) (errno int)
|
||||||
|
// Futimes(fd int, timeval *Timeval) (errno int) // Pointer to 2 timevals!
|
||||||
|
// Gethostuuid(uuid *byte, timeout *Timespec) (errno int)
|
||||||
|
// Getpeername(fd int, addr *Sockaddr, addrlen *int) (errno int)
|
||||||
|
// Getsockname(fd int, addr *Sockaddr, addrlen *int) (errno int)
|
||||||
|
// Getsockopt(s int, level int, name int, val *byte, vallen *int) (errno int)
|
||||||
|
// Madvise(addr *byte, len int, behav int) (errno int)
|
||||||
|
// Mprotect(addr *byte, len int, prot int) (errno int)
|
||||||
|
// Msync(addr *byte, len int, flags int) (errno int)
|
||||||
|
// Munmap(addr *byte, len int) (errno int)
|
||||||
|
// Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, errno int)
|
||||||
|
// Recvfrom(s int, buf *byte, nbuf int, flags int, from *Sockaddr, fromlen *int) (n int, errno int)
|
||||||
|
// Recvmsg(s int, msg *Msghdr, flags int) (n int, errno int)
|
||||||
|
// Sendmsg(s int, msg *Msghdr, flags int) (n int, errno int)
|
||||||
|
// Sendto(s int, buf *byte, nbuf int, flags int, to *Sockaddr, addrlen int) (errno int)
|
||||||
|
// Utimes(path string, timeval *Timeval) (errno int) // Pointer to 2 timevals!
|
||||||
|
//sys fcntl(fd int, cmd int, arg int) (val int, errno int)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exposed directly
|
||||||
|
*/
|
||||||
|
//sys Access(path string, flags int) (errno int)
|
||||||
|
//sys Adjtime(delta *Timeval, olddelta *Timeval) (errno int)
|
||||||
|
//sys Chdir(path string) (errno int)
|
||||||
|
//sys Chflags(path string, flags int) (errno int)
|
||||||
|
//sys Chmod(path string, mode int) (errno int)
|
||||||
|
//sys Chown(path string, uid int, gid int) (errno int)
|
||||||
|
//sys Chroot(path string) (errno int)
|
||||||
|
//sys Close(fd int) (errno int)
|
||||||
|
//sys Dup(fd int) (nfd int, errno int)
|
||||||
|
//sys Dup2(from int, to int) (errno int)
|
||||||
|
//sys Exchangedata(path1 string, path2 string, options int) (errno int)
|
||||||
|
//sys Exit(code int)
|
||||||
|
//sys Fchdir(fd int) (errno int)
|
||||||
|
//sys Fchflags(path string, flags int) (errno int)
|
||||||
|
//sys Fchmod(fd int, mode int) (errno int)
|
||||||
|
//sys Fchown(fd int, uid int, gid int) (errno int)
|
||||||
|
//sys Flock(fd int, how int) (errno int)
|
||||||
|
//sys Fpathconf(fd int, name int) (val int, errno int)
|
||||||
|
//sys Fstat(fd int, stat *Stat_t) (errno int) = SYS_FSTAT64
|
||||||
|
//sys Fstatfs(fd int, stat *Statfs_t) (errno int) = SYS_FSTATFS64
|
||||||
|
//sys Fsync(fd int) (errno int)
|
||||||
|
//sys Ftruncate(fd int, length int64) (errno int)
|
||||||
|
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, errno int) = SYS_GETDIRENTRIES64
|
||||||
|
//sys Getdtablesize() (size int)
|
||||||
|
//sys Getegid() (egid int)
|
||||||
|
//sys Geteuid() (uid int)
|
||||||
|
//sys Getfsstat(buf []Statfs_t, flags int) (n int, errno int) = SYS_GETFSSTAT64
|
||||||
|
//sys Getgid() (gid int)
|
||||||
|
//sys Getpgid(pid int) (pgid int, errno int)
|
||||||
|
//sys Getpgrp() (pgrp int)
|
||||||
|
//sys Getpid() (pid int)
|
||||||
|
//sys Getppid() (ppid int)
|
||||||
|
//sys Getpriority(which int, who int) (prio int, errno int)
|
||||||
|
//sys Getrlimit(which int, lim *Rlimit) (errno int)
|
||||||
|
//sys Getrusage(who int, rusage *Rusage) (errno int)
|
||||||
|
//sys Getsid(pid int) (sid int, errno int)
|
||||||
|
//sys Getuid() (uid int)
|
||||||
|
//sys Issetugid() (tainted bool)
|
||||||
|
//sys Kill(pid int, signum int, posix int) (errno int)
|
||||||
|
//sys Kqueue() (fd int, errno int)
|
||||||
|
//sys Lchown(path string, uid int, gid int) (errno int)
|
||||||
|
//sys Link(path string, link string) (errno int)
|
||||||
|
//sys Listen(s int, backlog int) (errno int)
|
||||||
|
//sys Lstat(path string, stat *Stat_t) (errno int) = SYS_LSTAT64
|
||||||
|
//sys Mkdir(path string, mode int) (errno int)
|
||||||
|
//sys Mkfifo(path string, mode int) (errno int)
|
||||||
|
//sys Mknod(path string, mode int, dev int) (errno int)
|
||||||
|
//sys Open(path string, mode int, perm int) (fd int, errno int)
|
||||||
|
//sys Pathconf(path string, name int) (val int, errno int)
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, errno int)
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, errno int)
|
||||||
|
//sys Read(fd int, p []byte) (n int, errno int)
|
||||||
|
//sys Readlink(path string, buf []byte) (n int, errno int)
|
||||||
|
//sys Rename(from string, to string) (errno int)
|
||||||
|
//sys Revoke(path string) (errno int)
|
||||||
|
//sys Rmdir(path string) (errno int)
|
||||||
|
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (errno int)
|
||||||
|
//sys Setegid(egid int) (errno int)
|
||||||
|
//sys Seteuid(euid int) (errno int)
|
||||||
|
//sys Setgid(gid int) (errno int)
|
||||||
|
//sys Setlogin(name string) (errno int)
|
||||||
|
//sys Setpgid(pid int, pgid int) (errno int)
|
||||||
|
//sys Setpriority(which int, who int, prio int) (errno int)
|
||||||
|
//sys Setprivexec(flag int) (errno int)
|
||||||
|
//sys Setregid(rgid int, egid int) (errno int)
|
||||||
|
//sys Setreuid(ruid int, euid int) (errno int)
|
||||||
|
//sys Setrlimit(which int, lim *Rlimit) (errno int)
|
||||||
|
//sys Setsid() (pid int, errno int)
|
||||||
|
//sys Settimeofday(tp *Timeval) (errno int)
|
||||||
|
//sys Setuid(uid int) (errno int)
|
||||||
|
//sys Stat(path string, stat *Stat_t) (errno int) = SYS_STAT64
|
||||||
|
//sys Statfs(path string, stat *Statfs_t) (errno int) = SYS_STATFS64
|
||||||
|
//sys Symlink(path string, link string) (errno int)
|
||||||
|
//sys Sync() (errno int)
|
||||||
|
//sys Truncate(path string, length int64) (errno int)
|
||||||
|
//sys Umask(newmask int) (errno int)
|
||||||
|
//sys Undelete(path string) (errno int)
|
||||||
|
//sys Unlink(path string) (errno int)
|
||||||
|
//sys Unmount(path string, flags int) (errno int)
|
||||||
|
//sys Write(fd int, p []byte) (n int, errno int)
|
||||||
|
//sys read(fd int, buf *byte, nbuf int) (n int, errno int)
|
||||||
|
//sys write(fd int, buf *byte, nbuf int) (n int, errno int)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unimplemented
|
||||||
|
*/
|
||||||
|
// Profil
|
||||||
|
// Sigaction
|
||||||
|
// Sigprocmask
|
||||||
|
// Getlogin
|
||||||
|
// Sigpending
|
||||||
|
// Sigaltstack
|
||||||
|
// Ioctl
|
||||||
|
// Reboot
|
||||||
|
// Execve
|
||||||
|
// Vfork
|
||||||
|
// Sbrk
|
||||||
|
// Sstk
|
||||||
|
// Ovadvise
|
||||||
|
// Mincore
|
||||||
|
// Setitimer
|
||||||
|
// Swapon
|
||||||
|
// Select
|
||||||
|
// Sigsuspend
|
||||||
|
// Readv
|
||||||
|
// Writev
|
||||||
|
// Nfssvc
|
||||||
|
// Getfh
|
||||||
|
// Quotactl
|
||||||
|
// Mount
|
||||||
|
// Csops
|
||||||
|
// Waitid
|
||||||
|
// Add_profil
|
||||||
|
// Kdebug_trace
|
||||||
|
// Sigreturn
|
||||||
|
// Mmap
|
||||||
|
// __Sysctl
|
||||||
|
// Mlock
|
||||||
|
// Munlock
|
||||||
|
// Atsocket
|
||||||
|
// Kqueue_from_portset_np
|
||||||
|
// Kqueue_portset
|
||||||
|
// Getattrlist
|
||||||
|
// Setattrlist
|
||||||
|
// Getdirentriesattr
|
||||||
|
// Searchfs
|
||||||
|
// Delete
|
||||||
|
// Copyfile
|
||||||
|
// Poll
|
||||||
|
// Watchevent
|
||||||
|
// Waitevent
|
||||||
|
// Modwatch
|
||||||
|
// Getxattr
|
||||||
|
// Fgetxattr
|
||||||
|
// Setxattr
|
||||||
|
// Fsetxattr
|
||||||
|
// Removexattr
|
||||||
|
// Fremovexattr
|
||||||
|
// Listxattr
|
||||||
|
// Flistxattr
|
||||||
|
// Fsctl
|
||||||
|
// Initgroups
|
||||||
|
// Posix_spawn
|
||||||
|
// Nfsclnt
|
||||||
|
// Fhopen
|
||||||
|
// Minherit
|
||||||
|
// Semsys
|
||||||
|
// Msgsys
|
||||||
|
// Shmsys
|
||||||
|
// Semctl
|
||||||
|
// Semget
|
||||||
|
// Semop
|
||||||
|
// Msgctl
|
||||||
|
// Msgget
|
||||||
|
// Msgsnd
|
||||||
|
// Msgrcv
|
||||||
|
// Shmat
|
||||||
|
// Shmctl
|
||||||
|
// Shmdt
|
||||||
|
// Shmget
|
||||||
|
// Shm_open
|
||||||
|
// Shm_unlink
|
||||||
|
// Sem_open
|
||||||
|
// Sem_close
|
||||||
|
// Sem_unlink
|
||||||
|
// Sem_wait
|
||||||
|
// Sem_trywait
|
||||||
|
// Sem_post
|
||||||
|
// Sem_getvalue
|
||||||
|
// Sem_init
|
||||||
|
// Sem_destroy
|
||||||
|
// Open_extended
|
||||||
|
// Umask_extended
|
||||||
|
// Stat_extended
|
||||||
|
// Lstat_extended
|
||||||
|
// Fstat_extended
|
||||||
|
// Chmod_extended
|
||||||
|
// Fchmod_extended
|
||||||
|
// Access_extended
|
||||||
|
// Settid
|
||||||
|
// Gettid
|
||||||
|
// Setsgroups
|
||||||
|
// Getsgroups
|
||||||
|
// Setwgroups
|
||||||
|
// Getwgroups
|
||||||
|
// Mkfifo_extended
|
||||||
|
// Mkdir_extended
|
||||||
|
// Identitysvc
|
||||||
|
// Shared_region_check_np
|
||||||
|
// Shared_region_map_np
|
||||||
|
// __pthread_mutex_destroy
|
||||||
|
// __pthread_mutex_init
|
||||||
|
// __pthread_mutex_lock
|
||||||
|
// __pthread_mutex_trylock
|
||||||
|
// __pthread_mutex_unlock
|
||||||
|
// __pthread_cond_init
|
||||||
|
// __pthread_cond_destroy
|
||||||
|
// __pthread_cond_broadcast
|
||||||
|
// __pthread_cond_signal
|
||||||
|
// Setsid_with_pid
|
||||||
|
// __pthread_cond_timedwait
|
||||||
|
// Aio_fsync
|
||||||
|
// Aio_return
|
||||||
|
// Aio_suspend
|
||||||
|
// Aio_cancel
|
||||||
|
// Aio_error
|
||||||
|
// Aio_read
|
||||||
|
// Aio_write
|
||||||
|
// Lio_listio
|
||||||
|
// __pthread_cond_wait
|
||||||
|
// Iopolicysys
|
||||||
|
// Mlockall
|
||||||
|
// Munlockall
|
||||||
|
// __pthread_kill
|
||||||
|
// __pthread_sigmask
|
||||||
|
// __sigwait
|
||||||
|
// __disable_threadsignal
|
||||||
|
// __pthread_markcancel
|
||||||
|
// __pthread_canceled
|
||||||
|
// __semwait_signal
|
||||||
|
// Proc_info
|
||||||
|
// Sendfile
|
||||||
|
// Stat64_extended
|
||||||
|
// Lstat64_extended
|
||||||
|
// Fstat64_extended
|
||||||
|
// __pthread_chdir
|
||||||
|
// __pthread_fchdir
|
||||||
|
// Audit
|
||||||
|
// Auditon
|
||||||
|
// Getauid
|
||||||
|
// Setauid
|
||||||
|
// Getaudit
|
||||||
|
// Setaudit
|
||||||
|
// Getaudit_addr
|
||||||
|
// Setaudit_addr
|
||||||
|
// Auditctl
|
||||||
|
// Bsdthread_create
|
||||||
|
// Bsdthread_terminate
|
||||||
|
// Stack_snapshot
|
||||||
|
// Bsdthread_register
|
||||||
|
// Workq_open
|
||||||
|
// Workq_ops
|
||||||
|
// __mac_execve
|
||||||
|
// __mac_syscall
|
||||||
|
// __mac_get_file
|
||||||
|
// __mac_set_file
|
||||||
|
// __mac_get_link
|
||||||
|
// __mac_set_link
|
||||||
|
// __mac_get_proc
|
||||||
|
// __mac_set_proc
|
||||||
|
// __mac_get_fd
|
||||||
|
// __mac_set_fd
|
||||||
|
// __mac_get_pid
|
||||||
|
// __mac_get_lcid
|
||||||
|
// __mac_get_lctx
|
||||||
|
// __mac_set_lctx
|
||||||
|
// Setlcid
|
||||||
|
// Read_nocancel
|
||||||
|
// Write_nocancel
|
||||||
|
// Open_nocancel
|
||||||
|
// Close_nocancel
|
||||||
|
// Wait4_nocancel
|
||||||
|
// Recvmsg_nocancel
|
||||||
|
// Sendmsg_nocancel
|
||||||
|
// Recvfrom_nocancel
|
||||||
|
// Accept_nocancel
|
||||||
|
// Msync_nocancel
|
||||||
|
// Fcntl_nocancel
|
||||||
|
// Select_nocancel
|
||||||
|
// Fsync_nocancel
|
||||||
|
// Connect_nocancel
|
||||||
|
// Sigsuspend_nocancel
|
||||||
|
// Readv_nocancel
|
||||||
|
// Writev_nocancel
|
||||||
|
// Sendto_nocancel
|
||||||
|
// Pread_nocancel
|
||||||
|
// Pwrite_nocancel
|
||||||
|
// Waitid_nocancel
|
||||||
|
// Poll_nocancel
|
||||||
|
// Msgsnd_nocancel
|
||||||
|
// Msgrcv_nocancel
|
||||||
|
// Sem_wait_nocancel
|
||||||
|
// Aio_suspend_nocancel
|
||||||
|
// __sigwait_nocancel
|
||||||
|
// __semwait_signal_nocancel
|
||||||
|
// __mac_mount
|
||||||
|
// __mac_get_mount
|
||||||
|
// __mac_getfsstat
|
||||||
|
|
28
src/lib/syscall/syscall_darwin_amd64.go
Normal file
28
src/lib/syscall/syscall_darwin_amd64.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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 "syscall"
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 {
|
||||||
|
return int64(ts.Sec)*1e9 + int64(ts.Nsec);
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9;
|
||||||
|
ts.Nsec = 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.Usec = int32(nsec%1e9 / 1e3);
|
||||||
|
tv.Sec = int64(nsec/1e9);
|
||||||
|
return;
|
||||||
|
}
|
636
src/lib/syscall/syscall_linux.go
Normal file
636
src/lib/syscall/syscall_linux.go
Normal file
@ -0,0 +1,636 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Linux system calls.
|
||||||
|
// This file is compiled as ordinary Go code,
|
||||||
|
// but it is also input to mksyscall,
|
||||||
|
// which parses the //sys lines and generates system call stubs.
|
||||||
|
// Note that sometimes we use a lowercase //sys name and
|
||||||
|
// wrap it in our own nicer implementation.
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall";
|
||||||
|
"unsafe";
|
||||||
|
)
|
||||||
|
|
||||||
|
const OS = "linux"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sys pipe(p *[2]_C_int) (errno int)
|
||||||
|
func Pipe(p []int) (errno int) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
var pp [2]_C_int;
|
||||||
|
errno = pipe(&pp);
|
||||||
|
p[0] = int(pp[0]);
|
||||||
|
p[1] = int(pp[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys utimes(path string, times *[2]Timeval) (errno int)
|
||||||
|
func Utimes(path string, tv []Timeval) (errno int) {
|
||||||
|
if len(tv) != 2 {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys futimesat(dirfd int, path string, times *[2]Timeval) (errno int)
|
||||||
|
func Futimesat(dirfd int, path string, tv []Timeval) (errno int) {
|
||||||
|
if len(tv) != 2 {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImplementsGetwd = true;
|
||||||
|
|
||||||
|
//sys Getcwd(buf []byte) (n int, errno int)
|
||||||
|
func Getwd() (wd string, errno int) {
|
||||||
|
var buf [PathMax]byte;
|
||||||
|
n, err := Getcwd(&buf);
|
||||||
|
if err != 0 {
|
||||||
|
return "", err;
|
||||||
|
}
|
||||||
|
// Getcwd returns the number of bytes written to buf, including the NUL.
|
||||||
|
if n < 1|| n > len(buf) || buf[n-1] != 0 {
|
||||||
|
return "", EINVAL;
|
||||||
|
}
|
||||||
|
return string(buf[0:n-1]), 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys getgroups(n int, list *_Gid_t) (nn int, errno int)
|
||||||
|
//sys setgroups(n int, list *_Gid_t) (errno int)
|
||||||
|
func Getgroups() (gids []int, errno int) {
|
||||||
|
n, err := getgroups(0, nil);
|
||||||
|
if err != 0 {
|
||||||
|
return nil, errno;
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return nil, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check group count. Max is 1<<16 on Linux.
|
||||||
|
if n < 0 || n > 1<<20 {
|
||||||
|
return nil, EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a := make([]_Gid_t, n);
|
||||||
|
n, err = getgroups(n, &a[0]);
|
||||||
|
if err != 0 {
|
||||||
|
return nil, errno;
|
||||||
|
}
|
||||||
|
gids = make([]int, n);
|
||||||
|
for i, v := range a[0:n] {
|
||||||
|
gids[i] = int(v);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setgroups(gids []int) (errno int) {
|
||||||
|
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
|
||||||
|
|
||||||
|
// Wait status is 7 bits at bottom, either 0 (exited),
|
||||||
|
// 0x7F (stopped), or a signal number that caused an exit.
|
||||||
|
// The 0x80 bit is whether there was a core dump.
|
||||||
|
// An extra number (exit code, signal causing a stop)
|
||||||
|
// is in the high bits. At least that's the idea.
|
||||||
|
// There are various irregularities. For example, the
|
||||||
|
// "continued" status is 0xFFFF, distinguishing itself
|
||||||
|
// from stopped via the core dump bit.
|
||||||
|
|
||||||
|
const (
|
||||||
|
mask = 0x7F;
|
||||||
|
core = 0x80;
|
||||||
|
exited = 0x00;
|
||||||
|
stopped = 0x7F;
|
||||||
|
shift = 8;
|
||||||
|
)
|
||||||
|
|
||||||
|
func (w WaitStatus) Exited() bool {
|
||||||
|
return w&mask == exited;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Signaled() bool {
|
||||||
|
return w&mask != stopped && w&mask != exited;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Stopped() bool {
|
||||||
|
return w&0xFF == stopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Continued() bool {
|
||||||
|
return w == 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) CoreDump() bool {
|
||||||
|
return w.Signaled() && w&core != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) ExitStatus() int {
|
||||||
|
if !w.Exited() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return int(w >> shift) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Signal() int {
|
||||||
|
if !w.Signaled() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return int(w & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) StopSignal() int {
|
||||||
|
if !w.Stopped() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return int(w >> shift) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, errno int)
|
||||||
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
|
||||||
|
var status _C_int;
|
||||||
|
wpid, errno = wait4(pid, &status, options, rusage);
|
||||||
|
if wstatus != nil {
|
||||||
|
*wstatus = WaitStatus(status);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sleep(nsec int64) (errno int) {
|
||||||
|
tv := NsecToTimeval(nsec);
|
||||||
|
n, err := Select(0, nil, nil, nil, &tv);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int)
|
||||||
|
//sys bind(s int, addr uintptr, addrlen _Socklen) (errno int)
|
||||||
|
//sys connect(s int, addr uintptr, addrlen _Socklen) (errno int)
|
||||||
|
//sys socket(domain int, typ int, proto int) (fd int, errno int)
|
||||||
|
//sys setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int)
|
||||||
|
//sys Listen(s int, n int) (errno int)
|
||||||
|
|
||||||
|
// For testing: clients can set this flag to force
|
||||||
|
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||||
|
var SocketDisableIPv6 bool
|
||||||
|
|
||||||
|
type Sockaddr interface {
|
||||||
|
sockaddr() (ptr uintptr, len _Socklen, errno int); // lowercase; only we can define Sockaddrs
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrInet4 struct {
|
||||||
|
Port int;
|
||||||
|
Addr [4]byte;
|
||||||
|
raw RawSockaddrInet4;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrInet4) sockaddr() (uintptr, _Socklen, int) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return 0, 0, EINVAL;
|
||||||
|
}
|
||||||
|
sa.raw.Family = AF_INET;
|
||||||
|
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 uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrInet6 struct {
|
||||||
|
Port int;
|
||||||
|
Addr [16]byte;
|
||||||
|
raw RawSockaddrInet6;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrInet6) sockaddr() (uintptr, _Socklen, int) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return 0, 0, EINVAL;
|
||||||
|
}
|
||||||
|
sa.raw.Family = AF_INET6;
|
||||||
|
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 uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrUnix struct {
|
||||||
|
Name string;
|
||||||
|
raw RawSockaddrUnix;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
|
||||||
|
name := sa.Name;
|
||||||
|
n := len(name);
|
||||||
|
if n >= len(sa.raw.Path) || n == 0 {
|
||||||
|
return 0, 0, EINVAL;
|
||||||
|
}
|
||||||
|
sa.raw.Family = AF_UNIX;
|
||||||
|
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, name, NUL.
|
||||||
|
return uintptr(unsafe.Pointer(&sa.raw)), 1 + _Socklen(n) + 1, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
|
||||||
|
switch rsa.Addr.Family {
|
||||||
|
case AF_UNIX:
|
||||||
|
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa));
|
||||||
|
sa := new(SockaddrUnix);
|
||||||
|
if pp.Path[0] == 0 {
|
||||||
|
// "Abstract" Unix domain socket.
|
||||||
|
// Rewrite leading NUL as @ for textual display.
|
||||||
|
// (This is the standard convention.)
|
||||||
|
// Not friendly to overwrite in place,
|
||||||
|
// but the callers below don't care.
|
||||||
|
pp.Path[0] = '@';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume path ends at NUL.
|
||||||
|
// This is not technically the Linux semantics for
|
||||||
|
// abstract Unix domain sockets--they are supposed
|
||||||
|
// to be uninterpreted fixed-size binary blobs--but
|
||||||
|
// everyone uses this convention.
|
||||||
|
n := 0;
|
||||||
|
for n < len(pp.Path) && pp.Path[n] != 0 {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]));
|
||||||
|
sa.Name = string(bytes[0:n]);
|
||||||
|
return sa, 0;
|
||||||
|
|
||||||
|
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, 0;
|
||||||
|
|
||||||
|
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, 0;
|
||||||
|
}
|
||||||
|
return nil, EAFNOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
|
||||||
|
var rsa RawSockaddrAny;
|
||||||
|
var len _Socklen = SizeofSockaddrAny;
|
||||||
|
nfd, errno = accept(fd, &rsa, &len);
|
||||||
|
if errno != 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sa, errno = anyToSockaddr(&rsa);
|
||||||
|
if errno != 0 {
|
||||||
|
Close(nfd);
|
||||||
|
nfd = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bind(fd int, sa Sockaddr) (errno int) {
|
||||||
|
ptr, n, err := sa.sockaddr();
|
||||||
|
if err != 0 {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return bind(fd, ptr, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Connect(fd int, sa Sockaddr) (errno int) {
|
||||||
|
ptr, n, err := sa.sockaddr();
|
||||||
|
if err != 0 {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return connect(fd, ptr, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Socket(domain, typ, proto int) (fd, errno int) {
|
||||||
|
if domain == AF_INET6 && SocketDisableIPv6 {
|
||||||
|
return -1, EAFNOSUPPORT
|
||||||
|
}
|
||||||
|
fd, errno = socket(domain, typ, proto);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptInt(fd, level, opt int, value int) (errno int) {
|
||||||
|
var n = int32(value);
|
||||||
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
|
||||||
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(tv)), unsafe.Sizeof(*tv));
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||||
|
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(l)), unsafe.Sizeof(*l));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sendto
|
||||||
|
// Recvfrom
|
||||||
|
// Sendmsg
|
||||||
|
// Recvmsg
|
||||||
|
// Getsockname
|
||||||
|
// Getpeername
|
||||||
|
// Socketpair
|
||||||
|
// Getsockopt
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Direct access
|
||||||
|
*/
|
||||||
|
//sys Access(path string, mode int) (errno int)
|
||||||
|
//sys Acct(path string) (errno int)
|
||||||
|
//sys Adjtimex(buf *Timex) (state int, errno int)
|
||||||
|
//sys Chdir(path string) (errno int)
|
||||||
|
//sys Chmod(path string, mode int) (errno int)
|
||||||
|
//sys Chown(path string, uid int, gid int) (errno int)
|
||||||
|
//sys Chroot(path string) (errno int)
|
||||||
|
//sys Close(fd int) (errno int)
|
||||||
|
//sys Creat(path string, mode int) (fd int, errno int)
|
||||||
|
//sys Dup(oldfd int) (fd int, errno int)
|
||||||
|
//sys Dup2(oldfd int, newfd int) (fd int, errno int)
|
||||||
|
//sys EpollCreate(size int) (fd int, errno int)
|
||||||
|
//sys EpollCtl(epfd int, op int, fd int, event *EpollEvent) (errno int)
|
||||||
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, errno int)
|
||||||
|
//sys Exit(code int) = SYS_EXIT_GROUP
|
||||||
|
//sys Faccessat(dirfd int, path string, mode int, flags int) (errno int)
|
||||||
|
//sys Fallocate(fd int, mode int, off int64, len int64) (errno int)
|
||||||
|
//sys Fchdir(fd int) (errno int)
|
||||||
|
//sys Fchmod(fd int, mode int) (errno int)
|
||||||
|
//sys Fchmodat(dirfd int, path string, mode int, flags int) (errno int)
|
||||||
|
//sys Fchown(fd int, uid int, gid int) (errno int)
|
||||||
|
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (errno int)
|
||||||
|
//sys fcntl(fd int, cmd int, arg int) (val int, errno int)
|
||||||
|
//sys Fdatasync(fd int) (errno int)
|
||||||
|
//sys Fstat(fd int, stat *Stat_t) (errno int)
|
||||||
|
//sys Fstatfs(fd int, buf *Statfs_t) (errno int)
|
||||||
|
//sys Fsync(fd int) (errno int)
|
||||||
|
//sys Ftruncate(fd int, length int64) (errno int)
|
||||||
|
//sys Getdents(fd int, buf []byte) (n int, errno int) = SYS_GETDENTS64
|
||||||
|
//sys Getegid() (egid int)
|
||||||
|
//sys Geteuid() (euid int)
|
||||||
|
//sys Getgid() (gid int)
|
||||||
|
//sys Getpgid(pid int) (pgid int, errno int)
|
||||||
|
//sys Getpgrp() (pid int)
|
||||||
|
//sys Getpid() (pid int)
|
||||||
|
//sys Getppid() (ppid int)
|
||||||
|
//sys Getrlimit(resource int, rlim *Rlimit) (errno int)
|
||||||
|
//sys Getrusage(who int, rusage *Rusage) (errno int)
|
||||||
|
//sys Gettid() (tid int)
|
||||||
|
//sys Gettimeofday(tv *Timeval) (errno int)
|
||||||
|
//sys Getuid() (uid int)
|
||||||
|
//sys Ioperm(from int, num int, on int) (errno int)
|
||||||
|
//sys Iopl(level int) (errno int)
|
||||||
|
//sys Kill(pid int, sig int) (errno int)
|
||||||
|
//sys Klogctl(typ int, buf []byte) (n int, errno int) = SYS_SYSLOG
|
||||||
|
//sys Lchown(path string, uid int, gid int) (errno int)
|
||||||
|
//sys Link(oldpath string, newpath string) (errno int)
|
||||||
|
//sys Lstat(path string, stat *Stat_t) (errno int)
|
||||||
|
//sys Mkdir(path string, mode int) (errno int)
|
||||||
|
//sys Mkdirat(dirfd int, path string, mode int) (errno int)
|
||||||
|
//sys Mknod(path string, mode int, dev int) (errno int)
|
||||||
|
//sys Mknodat(dirfd int, path string, mode int, dev int) (errno int)
|
||||||
|
//sys Nanosleep(time *Timespec, leftover *Timespec) (errno int)
|
||||||
|
//sys Open(path string, mode int, perm int) (fd int, errno int)
|
||||||
|
//sys Openat(dirfd int, path string, flags int, mode int) (fd int, errno int)
|
||||||
|
//sys Pause() (errno int)
|
||||||
|
//sys PivotRoot(newroot string, putold string) (errno int) = SYS_PIVOT_ROOT
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, errno int) = SYS_PREAD64
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, errno int) = SYS_PWRITE64
|
||||||
|
//sys Read(fd int, p []byte) (n int, errno int)
|
||||||
|
//sys Readlink(path string, buf []byte) (n int, errno int)
|
||||||
|
//sys Rename(oldpath string, newpath string) (errno int)
|
||||||
|
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (errno int)
|
||||||
|
//sys Rmdir(path string) (errno int)
|
||||||
|
//sys Seek(fd int, offset int64, whence int) (off int64, errno int) = SYS_LSEEK
|
||||||
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, errno int)
|
||||||
|
//sys Setdomainname(p []byte) (errno int)
|
||||||
|
//sys Setfsgid(gid int) (errno int)
|
||||||
|
//sys Setfsuid(uid int) (errno int)
|
||||||
|
//sys Setgid(gid int) (errno int)
|
||||||
|
//sys Sethostname(p []byte) (errno int)
|
||||||
|
//sys Setpgid(pid int, pgid int) (errno int)
|
||||||
|
//sys Setregid(rgid int, egid int) (errno int)
|
||||||
|
//sys Setresgid(rgid int, egid int, sgid int) (errno int)
|
||||||
|
//sys Setresuid(ruid int, euid int, suid int) (errno int)
|
||||||
|
//sys Setreuid(ruid int, euid int) (errno int)
|
||||||
|
//sys Setrlimit(resource int, rlim *Rlimit) (errno int)
|
||||||
|
//sys Setsid() (pid int)
|
||||||
|
//sys Settimeofday(tv *Timeval) (errno int)
|
||||||
|
//sys Setuid(uid int) (errno int)
|
||||||
|
//sys Shutdown(fd int, how int) (errno int)
|
||||||
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, errno int)
|
||||||
|
//sys Stat(path string, stat *Stat_t) (errno int)
|
||||||
|
//sys Statfs(path string, buf *Statfs_t) (errno int)
|
||||||
|
//sys Symlink(oldpath string, newpath string) (errno int)
|
||||||
|
//sys Sync()
|
||||||
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (errno int)
|
||||||
|
//sys Sysinfo(info *Sysinfo_t) (errno int)
|
||||||
|
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, errno int)
|
||||||
|
//sys Tgkill(tgid int, tid int, sig int) (errno int)
|
||||||
|
//sys Time(t *Time_t) (tt Time_t, errno int)
|
||||||
|
//sys Times(tms *Tms) (ticks uintptr, errno int)
|
||||||
|
//sys Truncate(path string, length int64) (errno int)
|
||||||
|
//sys Umask(mask int) (oldmask int)
|
||||||
|
//sys Uname(buf *Utsname) (errno int)
|
||||||
|
//sys Unlink(path string) (errno int)
|
||||||
|
//sys Unlinkat(dirfd int, path string) (errno int)
|
||||||
|
//sys Unshare(flags int) (errno int)
|
||||||
|
//sys Ustat(dev int, ubuf *Ustat_t) (errno int)
|
||||||
|
//sys Utime(path string, buf *Utimbuf) (errno int)
|
||||||
|
//sys Write(fd int, p []byte) (n int, errno int)
|
||||||
|
//sys exitThread(code int) (errno int) = SYS_EXIT
|
||||||
|
//sys read(fd int, p *byte, np int) (n int, errno int)
|
||||||
|
//sys write(fd int, p *byte, np int) (n int, errno int)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unimplemented
|
||||||
|
*/
|
||||||
|
// AddKey
|
||||||
|
// AfsSyscall
|
||||||
|
// Alarm
|
||||||
|
// ArchPrctl
|
||||||
|
// Brk
|
||||||
|
// Capget
|
||||||
|
// Capset
|
||||||
|
// ClockGetres
|
||||||
|
// ClockGettime
|
||||||
|
// ClockNanosleep
|
||||||
|
// ClockSettime
|
||||||
|
// Clone
|
||||||
|
// CreateModule
|
||||||
|
// DeleteModule
|
||||||
|
// EpollCtlOld
|
||||||
|
// EpollPwait
|
||||||
|
// EpollWaitOld
|
||||||
|
// Eventfd
|
||||||
|
// Execve
|
||||||
|
// Fadvise64
|
||||||
|
// Fgetxattr
|
||||||
|
// Flistxattr
|
||||||
|
// Flock
|
||||||
|
// Fork
|
||||||
|
// Fremovexattr
|
||||||
|
// Fsetxattr
|
||||||
|
// Futex
|
||||||
|
// GetKernelSyms
|
||||||
|
// GetMempolicy
|
||||||
|
// GetRobustList
|
||||||
|
// GetThreadArea
|
||||||
|
// Getitimer
|
||||||
|
// Getpmsg
|
||||||
|
// Getpriority
|
||||||
|
// Getxattr
|
||||||
|
// InotifyAddWatch
|
||||||
|
// InotifyInit
|
||||||
|
// InotifyRmWatch
|
||||||
|
// IoCancel
|
||||||
|
// IoDestroy
|
||||||
|
// IoGetevents
|
||||||
|
// IoSetup
|
||||||
|
// IoSubmit
|
||||||
|
// Ioctl
|
||||||
|
// IoprioGet
|
||||||
|
// IoprioSet
|
||||||
|
// KexecLoad
|
||||||
|
// Keyctl
|
||||||
|
// Lgetxattr
|
||||||
|
// Listxattr
|
||||||
|
// Llistxattr
|
||||||
|
// LookupDcookie
|
||||||
|
// Lremovexattr
|
||||||
|
// Lsetxattr
|
||||||
|
// Madvise
|
||||||
|
// Mbind
|
||||||
|
// MigratePages
|
||||||
|
// Mincore
|
||||||
|
// Mlock
|
||||||
|
// Mmap
|
||||||
|
// ModifyLdt
|
||||||
|
// Mount
|
||||||
|
// MovePages
|
||||||
|
// Mprotect
|
||||||
|
// MqGetsetattr
|
||||||
|
// MqNotify
|
||||||
|
// MqOpen
|
||||||
|
// MqTimedreceive
|
||||||
|
// MqTimedsend
|
||||||
|
// MqUnlink
|
||||||
|
// Mremap
|
||||||
|
// Msgctl
|
||||||
|
// Msgget
|
||||||
|
// Msgrcv
|
||||||
|
// Msgsnd
|
||||||
|
// Msync
|
||||||
|
// Munlock
|
||||||
|
// Munlockall
|
||||||
|
// Munmap
|
||||||
|
// Newfstatat
|
||||||
|
// Nfsservctl
|
||||||
|
// Personality
|
||||||
|
// Poll
|
||||||
|
// Ppoll
|
||||||
|
// Prctl
|
||||||
|
// Pselect6
|
||||||
|
// Ptrace
|
||||||
|
// Putpmsg
|
||||||
|
// QueryModule
|
||||||
|
// Quotactl
|
||||||
|
// Readahead
|
||||||
|
// Readv
|
||||||
|
// Reboot
|
||||||
|
// RemapFilePages
|
||||||
|
// Removexattr
|
||||||
|
// RequestKey
|
||||||
|
// RestartSyscall
|
||||||
|
// RtSigaction
|
||||||
|
// RtSigpending
|
||||||
|
// RtSigprocmask
|
||||||
|
// RtSigqueueinfo
|
||||||
|
// RtSigreturn
|
||||||
|
// RtSigsuspend
|
||||||
|
// RtSigtimedwait
|
||||||
|
// SchedGetPriorityMax
|
||||||
|
// SchedGetPriorityMin
|
||||||
|
// SchedGetaffinity
|
||||||
|
// SchedGetparam
|
||||||
|
// SchedGetscheduler
|
||||||
|
// SchedRrGetInterval
|
||||||
|
// SchedSetaffinity
|
||||||
|
// SchedSetparam
|
||||||
|
// SchedYield
|
||||||
|
// Security
|
||||||
|
// Semctl
|
||||||
|
// Semget
|
||||||
|
// Semop
|
||||||
|
// Semtimedop
|
||||||
|
// Sendfile
|
||||||
|
// SetMempolicy
|
||||||
|
// SetRobustList
|
||||||
|
// SetThreadArea
|
||||||
|
// SetTidAddress
|
||||||
|
// Setpriority
|
||||||
|
// Setxattr
|
||||||
|
// Shmat
|
||||||
|
// Shmctl
|
||||||
|
// Shmdt
|
||||||
|
// Shmget
|
||||||
|
// Sigaltstack
|
||||||
|
// Signalfd
|
||||||
|
// Swapoff
|
||||||
|
// Swapon
|
||||||
|
// Sysfs
|
||||||
|
// TimerCreate
|
||||||
|
// TimerDelete
|
||||||
|
// TimerGetoverrun
|
||||||
|
// TimerGettime
|
||||||
|
// TimerSettime
|
||||||
|
// Timerfd
|
||||||
|
// Tkill (obsolete)
|
||||||
|
// Tuxcall
|
||||||
|
// Umount2
|
||||||
|
// Uselib
|
||||||
|
// Utimensat
|
||||||
|
// Vfork
|
||||||
|
// Vhangup
|
||||||
|
// Vmsplice
|
||||||
|
// Vserver
|
||||||
|
// Waitid
|
||||||
|
// Writev
|
||||||
|
// _Sysctl
|
29
src/lib/syscall/syscall_linux_amd64.go
Normal file
29
src/lib/syscall/syscall_linux_amd64.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// 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 "syscall"
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 {
|
||||||
|
return int64(ts.Sec)*1e9 + int64(ts.Nsec);
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9;
|
||||||
|
ts.Nsec = 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 = nsec/1e9;
|
||||||
|
tv.Usec = nsec%1e9 / 1e3;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
226
src/lib/syscall/types_darwin.c
Normal file
226
src/lib/syscall/types_darwin.c
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to godefs. See PORT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __DARWIN_UNIX03 0
|
||||||
|
#define KERNEL
|
||||||
|
#define _DARWIN_USE_64_BIT_INODE
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/message.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/event.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$sizeofPtr = sizeof(void*),
|
||||||
|
$sizeofShort = sizeof(short),
|
||||||
|
$sizeofInt = sizeof(int),
|
||||||
|
$sizeofLong = sizeof(long),
|
||||||
|
$sizeofLongLong = sizeof(long long),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Time
|
||||||
|
|
||||||
|
typedef struct timespec $Timespec;
|
||||||
|
typedef struct timeval $Timeval;
|
||||||
|
|
||||||
|
// Processes
|
||||||
|
|
||||||
|
typedef struct rusage $Rusage;
|
||||||
|
typedef struct rlimit $Rlimit;
|
||||||
|
|
||||||
|
typedef int $_C_int;
|
||||||
|
typedef gid_t $_Gid_t;
|
||||||
|
|
||||||
|
// Files
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$O_RDONLY = O_RDONLY,
|
||||||
|
$O_WRONLY = O_WRONLY,
|
||||||
|
$O_RDWR = O_RDWR,
|
||||||
|
$O_APPEND = O_APPEND,
|
||||||
|
$O_ASYNC = O_ASYNC,
|
||||||
|
$O_CREAT = O_CREAT,
|
||||||
|
$O_NOCTTY = O_NOCTTY,
|
||||||
|
$O_NONBLOCK = O_NONBLOCK,
|
||||||
|
$O_SYNC = O_SYNC,
|
||||||
|
$O_TRUNC = O_TRUNC,
|
||||||
|
$O_CLOEXEC = 0, // not supported
|
||||||
|
|
||||||
|
$F_GETFD = F_GETFD,
|
||||||
|
$F_SETFD = F_SETFD,
|
||||||
|
|
||||||
|
$F_GETFL = F_GETFL,
|
||||||
|
$F_SETFL = F_SETFL,
|
||||||
|
|
||||||
|
$FD_CLOEXEC = FD_CLOEXEC,
|
||||||
|
|
||||||
|
$NAME_MAX = NAME_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{ // Directory mode bits
|
||||||
|
$S_IFMT = S_IFMT,
|
||||||
|
$S_IFIFO = S_IFIFO,
|
||||||
|
$S_IFCHR = S_IFCHR,
|
||||||
|
$S_IFDIR = S_IFDIR,
|
||||||
|
$S_IFBLK = S_IFBLK,
|
||||||
|
$S_IFREG = S_IFREG,
|
||||||
|
$S_IFLNK = S_IFLNK,
|
||||||
|
$S_IFSOCK = S_IFSOCK,
|
||||||
|
$S_IFWHT = S_IFWHT,
|
||||||
|
$S_ISUID = S_ISUID,
|
||||||
|
$S_ISGID = S_ISGID,
|
||||||
|
$S_ISVTX = S_ISVTX,
|
||||||
|
$S_IRUSR = S_IRUSR,
|
||||||
|
$S_IWUSR = S_IWUSR,
|
||||||
|
$S_IXUSR = S_IXUSR,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct stat64 $Stat_t;
|
||||||
|
typedef struct statfs64 $Statfs_t;
|
||||||
|
|
||||||
|
typedef struct dirent $Dirent;
|
||||||
|
|
||||||
|
// Wait status.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$WNOHANG = WNOHANG,
|
||||||
|
$WUNTRACED = WUNTRACED,
|
||||||
|
$WEXITED = WEXITED,
|
||||||
|
$WSTOPPED = WSTOPPED,
|
||||||
|
$WCONTINUED = WCONTINUED,
|
||||||
|
$WNOWAIT = WNOWAIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sockets
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$AF_UNIX = AF_UNIX,
|
||||||
|
$AF_INET = AF_INET,
|
||||||
|
$AF_DATAKIT = AF_DATAKIT,
|
||||||
|
$AF_INET6 = AF_INET6,
|
||||||
|
|
||||||
|
$SOCK_STREAM = SOCK_STREAM,
|
||||||
|
$SOCK_DGRAM = SOCK_DGRAM,
|
||||||
|
$SOCK_RAW = SOCK_RAW,
|
||||||
|
$SOCK_SEQPACKET = SOCK_SEQPACKET,
|
||||||
|
|
||||||
|
$SOL_SOCKET = SOL_SOCKET,
|
||||||
|
|
||||||
|
$SO_REUSEADDR = SO_REUSEADDR,
|
||||||
|
$SO_KEEPALIVE = SO_KEEPALIVE,
|
||||||
|
$SO_DONTROUTE = SO_DONTROUTE,
|
||||||
|
$SO_BROADCAST = SO_BROADCAST,
|
||||||
|
$SO_USELOOPBACK = SO_USELOOPBACK,
|
||||||
|
$SO_LINGER = SO_LINGER,
|
||||||
|
$SO_REUSEPORT = SO_REUSEPORT,
|
||||||
|
$SO_SNDBUF = SO_SNDBUF,
|
||||||
|
$SO_RCVBUF = SO_RCVBUF,
|
||||||
|
$SO_SNDTIMEO = SO_SNDTIMEO,
|
||||||
|
$SO_RCVTIMEO = SO_RCVTIMEO,
|
||||||
|
$SO_NOSIGPIPE = SO_NOSIGPIPE,
|
||||||
|
|
||||||
|
$IPPROTO_TCP = IPPROTO_TCP,
|
||||||
|
$IPPROTO_UDP = IPPROTO_UDP,
|
||||||
|
|
||||||
|
$TCP_NODELAY = TCP_NODELAY,
|
||||||
|
|
||||||
|
$SOMAXCONN = SOMAXCONN
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sockaddr_in $RawSockaddrInet4;
|
||||||
|
typedef struct sockaddr_in6 $RawSockaddrInet6;
|
||||||
|
typedef struct sockaddr_un $RawSockaddrUnix;
|
||||||
|
typedef struct sockaddr $RawSockaddr;
|
||||||
|
|
||||||
|
union sockaddr_all {
|
||||||
|
struct sockaddr s1; // this one gets used for fields
|
||||||
|
struct sockaddr_in s2; // these pad it out
|
||||||
|
struct sockaddr_in6 s3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr_any {
|
||||||
|
struct sockaddr addr;
|
||||||
|
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$SizeofSockaddrInet4 = sizeof(struct sockaddr_in),
|
||||||
|
$SizeofSockaddrInet6 = sizeof(struct sockaddr_in6),
|
||||||
|
$SizeofSockaddrAny = sizeof(struct sockaddr_any),
|
||||||
|
$SizeofSockaddrUnix = sizeof(struct sockaddr_un),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sockaddr_any $RawSockaddrAny;
|
||||||
|
typedef socklen_t $_Socklen;
|
||||||
|
typedef struct linger $Linger;
|
||||||
|
|
||||||
|
// Events (kqueue, kevent)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// filters
|
||||||
|
$EVFILT_READ = EVFILT_READ,
|
||||||
|
$EVFILT_WRITE = EVFILT_WRITE,
|
||||||
|
$EVFILT_AIO = EVFILT_AIO,
|
||||||
|
$EVFILT_VNODE = EVFILT_VNODE,
|
||||||
|
$EVFILT_PROC = EVFILT_PROC,
|
||||||
|
$EVFILT_SIGNAL = EVFILT_SIGNAL,
|
||||||
|
$EVFILT_TIMER = EVFILT_TIMER,
|
||||||
|
$EVFILT_MACHPORT = EVFILT_MACHPORT,
|
||||||
|
$EVFILT_FS = EVFILT_FS,
|
||||||
|
|
||||||
|
$EVFILT_SYSCOUNT = EVFILT_SYSCOUNT,
|
||||||
|
|
||||||
|
// actions
|
||||||
|
$EV_ADD = EV_ADD,
|
||||||
|
$EV_DELETE = EV_DELETE,
|
||||||
|
$EV_DISABLE = EV_DISABLE,
|
||||||
|
$EV_RECEIPT = EV_RECEIPT,
|
||||||
|
|
||||||
|
// flags
|
||||||
|
$EV_ONESHOT = EV_ONESHOT,
|
||||||
|
$EV_CLEAR = EV_CLEAR,
|
||||||
|
$EV_SYSFLAGS = EV_SYSFLAGS,
|
||||||
|
$EV_FLAG0 = EV_FLAG0,
|
||||||
|
$EV_FLAG1 = EV_FLAG1,
|
||||||
|
|
||||||
|
// returned values
|
||||||
|
$EV_EOF = EV_EOF,
|
||||||
|
$EV_ERROR = EV_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct kevent $Kevent_t;
|
||||||
|
|
||||||
|
// Select
|
||||||
|
|
||||||
|
typedef fd_set $FdSet;
|
5
src/lib/syscall/types_darwin_amd64.c
Normal file
5
src/lib/syscall/types_darwin_amd64.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Nothing to see here.
|
217
src/lib/syscall/types_linux.c
Normal file
217
src/lib/syscall/types_linux.c
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to godefs. See PORT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __DARWIN_UNIX03 0
|
||||||
|
#define KERNEL
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/times.h>
|
||||||
|
#include <sys/timex.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ustat.h>
|
||||||
|
#include <utime.h>
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$sizeofPtr = sizeof(void*),
|
||||||
|
$sizeofShort = sizeof(short),
|
||||||
|
$sizeofInt = sizeof(int),
|
||||||
|
$sizeofLong = sizeof(long),
|
||||||
|
$sizeofLongLong = sizeof(long long),
|
||||||
|
$PathMax = PATH_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Time
|
||||||
|
|
||||||
|
typedef struct timespec $Timespec;
|
||||||
|
typedef struct timeval $Timeval;
|
||||||
|
typedef struct timex $Timex;
|
||||||
|
typedef time_t $Time_t;
|
||||||
|
typedef struct tms $Tms;
|
||||||
|
typedef struct utimbuf $Utimbuf;
|
||||||
|
|
||||||
|
// Processes
|
||||||
|
|
||||||
|
typedef struct rusage $Rusage;
|
||||||
|
typedef struct rlimit $Rlimit;
|
||||||
|
|
||||||
|
typedef int $_C_int;
|
||||||
|
typedef gid_t $_Gid_t;
|
||||||
|
|
||||||
|
// Files
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$O_RDONLY = O_RDONLY,
|
||||||
|
$O_WRONLY = O_WRONLY,
|
||||||
|
$O_RDWR = O_RDWR,
|
||||||
|
$O_APPEND = O_APPEND,
|
||||||
|
$O_ASYNC = O_ASYNC,
|
||||||
|
$O_CREAT = O_CREAT,
|
||||||
|
$O_NOCTTY = O_NOCTTY,
|
||||||
|
$O_NONBLOCK = O_NONBLOCK,
|
||||||
|
$O_SYNC = O_SYNC,
|
||||||
|
$O_TRUNC = O_TRUNC,
|
||||||
|
$O_CLOEXEC = 0, // not supported
|
||||||
|
|
||||||
|
$F_GETFD = F_GETFD,
|
||||||
|
$F_SETFD = F_SETFD,
|
||||||
|
|
||||||
|
$F_GETFL = F_GETFL,
|
||||||
|
$F_SETFL = F_SETFL,
|
||||||
|
|
||||||
|
$FD_CLOEXEC = FD_CLOEXEC,
|
||||||
|
|
||||||
|
$NAME_MAX = NAME_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{ // Directory mode bits
|
||||||
|
$S_IFMT = S_IFMT,
|
||||||
|
$S_IFIFO = S_IFIFO,
|
||||||
|
$S_IFCHR = S_IFCHR,
|
||||||
|
$S_IFDIR = S_IFDIR,
|
||||||
|
$S_IFBLK = S_IFBLK,
|
||||||
|
$S_IFREG = S_IFREG,
|
||||||
|
$S_IFLNK = S_IFLNK,
|
||||||
|
$S_IFSOCK = S_IFSOCK,
|
||||||
|
$S_ISUID = S_ISUID,
|
||||||
|
$S_ISGID = S_ISGID,
|
||||||
|
$S_ISVTX = S_ISVTX,
|
||||||
|
$S_IRUSR = S_IRUSR,
|
||||||
|
$S_IWUSR = S_IWUSR,
|
||||||
|
$S_IXUSR = S_IXUSR,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct stat $Stat_t;
|
||||||
|
typedef struct statfs $Statfs_t;
|
||||||
|
|
||||||
|
typedef struct dirent $Dirent;
|
||||||
|
|
||||||
|
// Wait status.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$WNOHANG = WNOHANG,
|
||||||
|
$WUNTRACED = WUNTRACED,
|
||||||
|
$WEXITED = WEXITED,
|
||||||
|
$WSTOPPED = WSTOPPED,
|
||||||
|
$WCONTINUED = WCONTINUED,
|
||||||
|
$WNOWAIT = WNOWAIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sockets
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
$AF_UNIX = AF_UNIX,
|
||||||
|
$AF_INET = AF_INET,
|
||||||
|
$AF_INET6 = AF_INET6,
|
||||||
|
|
||||||
|
$SOCK_STREAM = SOCK_STREAM,
|
||||||
|
$SOCK_DGRAM = SOCK_DGRAM,
|
||||||
|
$SOCK_RAW = SOCK_RAW,
|
||||||
|
$SOCK_SEQPACKET = SOCK_SEQPACKET,
|
||||||
|
|
||||||
|
$SOL_SOCKET = SOL_SOCKET,
|
||||||
|
|
||||||
|
$SO_REUSEADDR = SO_REUSEADDR,
|
||||||
|
$SO_KEEPALIVE = SO_KEEPALIVE,
|
||||||
|
$SO_DONTROUTE = SO_DONTROUTE,
|
||||||
|
$SO_BROADCAST = SO_BROADCAST,
|
||||||
|
$SO_LINGER = SO_LINGER,
|
||||||
|
$SO_SNDBUF = SO_SNDBUF,
|
||||||
|
$SO_RCVBUF = SO_RCVBUF,
|
||||||
|
$SO_SNDTIMEO = SO_SNDTIMEO,
|
||||||
|
$SO_RCVTIMEO = SO_RCVTIMEO,
|
||||||
|
|
||||||
|
$IPPROTO_TCP = IPPROTO_TCP,
|
||||||
|
$IPPROTO_UDP = IPPROTO_UDP,
|
||||||
|
|
||||||
|
$TCP_NODELAY = TCP_NODELAY,
|
||||||
|
|
||||||
|
$SOMAXCONN = SOMAXCONN
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sockaddr_in $RawSockaddrInet4;
|
||||||
|
typedef struct sockaddr_in6 $RawSockaddrInet6;
|
||||||
|
typedef struct sockaddr_un $RawSockaddrUnix;
|
||||||
|
typedef struct sockaddr $RawSockaddr;
|
||||||
|
|
||||||
|
union sockaddr_all {
|
||||||
|
struct sockaddr s1; // this one gets used for fields
|
||||||
|
struct sockaddr_in s2; // these pad it out
|
||||||
|
struct sockaddr_in6 s3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr_any {
|
||||||
|
struct sockaddr addr;
|
||||||
|
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$SizeofSockaddrInet4 = sizeof(struct sockaddr_in),
|
||||||
|
$SizeofSockaddrInet6 = sizeof(struct sockaddr_in6),
|
||||||
|
$SizeofSockaddrAny = sizeof(struct sockaddr_any),
|
||||||
|
$SizeofSockaddrUnix = sizeof(struct sockaddr_un),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sockaddr_any $RawSockaddrAny;
|
||||||
|
typedef socklen_t $_Socklen;
|
||||||
|
typedef struct linger $Linger;
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$EPOLLIN = EPOLLIN,
|
||||||
|
$EPOLLRDHUP = EPOLLRDHUP,
|
||||||
|
$EPOLLOUT = EPOLLOUT,
|
||||||
|
$EPOLLONESHOT = EPOLLONESHOT,
|
||||||
|
$EPOLL_CTL_MOD = EPOLL_CTL_MOD,
|
||||||
|
$EPOLL_CTL_ADD = EPOLL_CTL_ADD,
|
||||||
|
$EPOLL_CTL_DEL = EPOLL_CTL_DEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef fd_set $FdSet;
|
||||||
|
typedef struct sysinfo $Sysinfo_t;
|
||||||
|
typedef struct utsname $Utsname;
|
||||||
|
typedef struct ustat $Ustat_t;
|
||||||
|
|
||||||
|
// The real epoll_event is a union, and godefs doesn't handle it well.
|
||||||
|
struct my_epoll_event {
|
||||||
|
uint32_t events;
|
||||||
|
int32_t fd;
|
||||||
|
int32_t pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct my_epoll_event $EpollEvent;
|
5
src/lib/syscall/types_linux_amd64.c
Normal file
5
src/lib/syscall/types_linux_amd64.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Nothing to see here
|
Loading…
Reference in New Issue
Block a user