Commit 602a446b authored by Russ Cox's avatar Russ Cox

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
parent 9e0fec9c
#!/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
// 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
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;
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;
}
return r1, err1;
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);
}
#!/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
#!/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;
#!/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.
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];
}
This diff is collapsed.
// 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;
}
This diff is collapsed.
// 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;
}
// 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;
// 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.
// 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;
// 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment