1
0
mirror of https://github.com/golang/go synced 2024-11-18 10:54:40 -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:
Russ Cox 2009-06-01 22:14:57 -07:00
parent 9e0fec9c9c
commit 602a446b74
15 changed files with 2352 additions and 73 deletions

120
src/lib/syscall/PORT Executable file
View 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
View 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]
}

View File

@ -61,10 +61,6 @@ import (
var ForkLock sync.RWMutex
func CloseOnExec(fd int64) {
Fcntl(fd, F_SETFD, FD_CLOEXEC);
}
// Convert array of string to array
// of NUL-terminated byte pointer.
func StringArrayPtr(ss []string) []*byte {
@ -76,36 +72,40 @@ func StringArrayPtr(ss []string) []*byte {
return bb;
}
func Wait4(pid int64, wstatus *WaitStatus, options int64, rusage *Rusage)
(wpid, err int64)
{
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 CloseOnExec(fd int) {
fcntl(fd, F_SETFD, FD_CLOEXEC);
}
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.
// 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.)
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd []int64, pipe int64)
(pid int64, err int64)
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd []int, pipe int)
(pid int, err int)
{
// Declare all variables at top in case any
// declarations require heap allocation (e.g., err1).
var r1, r2, err1 int64;
var nextfd int64;
var r1, r2, err1 uintptr;
var nextfd int;
var i int;
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.
r1, r2, err1 = RawSyscall(SYS_FORK, 0, 0, 0);
if err1 != 0 {
return 0, err1
return 0, int(err1)
}
// On Darwin:
@ -127,38 +127,38 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, dir *byte, fd [
if r1 != 0 {
// parent; return PID
return r1, 0
return int(r1), 0
}
// Fork succeeded, now in child.
// Chdir
if dir != nil {
r1, r2, err = RawSyscall(SYS_CHDIR, int64(uintptr(unsafe.Pointer(dir))), 0, 0);
if err != 0 {
r1, r2, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0);
if err1 != 0 {
goto childerror;
}
}
// Pass 1: look for fd[i] < i and move those up above len(fd)
// so that pass 2 won't stomp on an fd it needs later.
nextfd = int64(len(fd));
nextfd = int(len(fd));
if pipe < nextfd {
r1, r2, err = RawSyscall(SYS_DUP2, pipe, nextfd, 0);
if err != 0 {
r1, r2, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0);
if err1 != 0 {
goto childerror;
}
RawSyscall(SYS_FCNTL, nextfd, F_SETFD, FD_CLOEXEC);
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC);
pipe = nextfd;
nextfd++;
}
for i = 0; i < len(fd); i++ {
if fd[i] >= 0 && fd[i] < int64(i) {
r1, r2, err = RawSyscall(SYS_DUP2, fd[i], nextfd, 0);
if err != 0 {
if fd[i] >= 0 && fd[i] < int(i) {
r1, r2, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0);
if err1 != 0 {
goto childerror;
}
RawSyscall(SYS_FCNTL, nextfd, F_SETFD, FD_CLOEXEC);
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC);
fd[i] = nextfd;
nextfd++;
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.
for i = 0; i < len(fd); i++ {
if fd[i] == -1 {
RawSyscall(SYS_CLOSE, int64(i), 0, 0);
RawSyscall(SYS_CLOSE, uintptr(i), 0, 0);
continue;
}
if fd[i] == int64(i) {
if fd[i] == int(i) {
// dup2(i, i) won't clear close-on-exec flag on Linux,
// probably not elsewhere either.
r1, r2, err = RawSyscall(SYS_FCNTL, fd[i], F_SETFD, 0);
if err != 0 {
r1, r2, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0);
if err1 != 0 {
goto childerror;
}
continue;
}
// The new fd is created NOT close-on-exec,
// which is exactly what we want.
r1, r2, err = RawSyscall(SYS_DUP2, fd[i], int64(i), 0);
if err != 0 {
r1, r2, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(i), 0);
if err1 != 0 {
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
// to set them close-on-exec.
for i = len(fd); i < 3; i++ {
RawSyscall(SYS_CLOSE, int64(i), 0, 0);
RawSyscall(SYS_CLOSE, uintptr(i), 0, 0);
}
// Time to exec.
r1, r2, err1 = RawSyscall(SYS_EXECVE,
int64(uintptr(unsafe.Pointer(argv0))),
int64(uintptr(unsafe.Pointer(&argv[0]))),
int64(uintptr(unsafe.Pointer(&envv[0]))));
uintptr(unsafe.Pointer(argv0)),
uintptr(unsafe.Pointer(&argv[0])),
uintptr(unsafe.Pointer(&envv[0])));
childerror:
// 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 {
RawSyscall(SYS_EXIT, 253, 0, 0);
}
@ -218,12 +218,13 @@ childerror:
}
// Combination of fork and exec, careful to be thread safe.
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64)
(pid int64, err int64)
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int)
(pid int, err int)
{
var p [2]int64;
var r1 int64;
var n, err1 int64;
var p [2]int;
var r1 int;
var n int;
var err1 uintptr;
var wstatus WaitStatus;
p[0] = -1;
@ -244,13 +245,14 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64
ForkLock.Lock();
// Allocate child status pipe close on exec.
if r1, err = Pipe(&p); err != 0 {
if err = Pipe(&p); err != 0 {
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;
}
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;
}
@ -269,11 +271,11 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64
// Read child error status from pipe.
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]);
if err != 0 || n != 0 {
if n == 8 {
err = err1;
if n == unsafe.Sizeof(err1) {
err = int(err1);
}
if err == 0 {
err = EPIPE;
@ -293,11 +295,11 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int64
}
// 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,
int64(uintptr(unsafe.Pointer(StringBytePtr(argv0)))),
int64(uintptr(unsafe.Pointer(&StringArrayPtr(argv)[0]))),
int64(uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0]))));
return err1;
uintptr(unsafe.Pointer(StringBytePtr(argv0))),
uintptr(unsafe.Pointer(&StringArrayPtr(argv)[0])),
uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0])));
return int(err1);
}

94
src/lib/syscall/mkerrors Executable file
View 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
View 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
View 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

View File

@ -11,22 +11,27 @@
// the manuals for the appropriate operating system.
package syscall
/*
* Foundation of system call interface.
*/
import (
"syscall";
"unsafe";
)
func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
func RawSyscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
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)
/*
* Used to convert file names to byte arrays for passing to kernel,
* but useful elsewhere too.
*/
func StringBytePtr(s string) *byte {
// StringByteSlice returns a NUL-terminated slice of bytes
// containing the text of s.
func StringByteSlice(s string) []byte {
a := make([]byte, len(s)+1);
for i := 0; i < len(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];
}

View 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

View 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;
}

View 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

View 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;
}

View 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;

View 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.

View 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;

View 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