mirror of
https://github.com/golang/go.git
synced 2025-05-22 07:59:19 +00:00
1) Change default gofmt default settings for
parsing and printing to new syntax. Use -oldparser to parse the old syntax, use -oldprinter to print the old syntax. 2) Change default gofmt formatting settings to use tabs for indentation only and to use spaces for alignment. This will make the code alignment insensitive to an editor's tabwidth. Use -spaces=false to use tabs for alignment. 3) Manually changed src/exp/parser/parser_test.go so that it doesn't try to parse the parser's source files using the old syntax (they have new syntax now). 4) gofmt -w src misc test/bench 4th set of files. R=rsc CC=golang-dev https://golang.org/cl/180049
This commit is contained in:
parent
a3d1045fb7
commit
d65a5cce89
@ -9,8 +9,8 @@ package once
|
||||
import "sync"
|
||||
|
||||
type job struct {
|
||||
done bool;
|
||||
sync.Mutex; // should probably be sync.Notification or some such
|
||||
done bool
|
||||
sync.Mutex // should probably be sync.Notification or some such
|
||||
}
|
||||
|
||||
var jobs = make(map[func()]*job)
|
||||
@ -37,23 +37,23 @@ var joblock sync.Mutex
|
||||
// because the func() expression in the first creates a new
|
||||
// func each time f runs, and each of those funcs is run once.
|
||||
func Do(f func()) {
|
||||
joblock.Lock();
|
||||
j, present := jobs[f];
|
||||
joblock.Lock()
|
||||
j, present := jobs[f]
|
||||
if !present {
|
||||
// run it
|
||||
j = new(job);
|
||||
j.Lock();
|
||||
jobs[f] = j;
|
||||
joblock.Unlock();
|
||||
f();
|
||||
j.done = true;
|
||||
j.Unlock();
|
||||
j = new(job)
|
||||
j.Lock()
|
||||
jobs[f] = j
|
||||
joblock.Unlock()
|
||||
f()
|
||||
j.done = true
|
||||
j.Unlock()
|
||||
} else {
|
||||
// wait for it
|
||||
joblock.Unlock();
|
||||
joblock.Unlock()
|
||||
if j.done != true {
|
||||
j.Lock();
|
||||
j.Unlock();
|
||||
j.Lock()
|
||||
j.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,25 +5,25 @@
|
||||
package once_test
|
||||
|
||||
import (
|
||||
"once";
|
||||
"testing";
|
||||
"once"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var ncall int
|
||||
|
||||
func call() { ncall++ }
|
||||
func call() { ncall++ }
|
||||
|
||||
func TestDo(t *testing.T) {
|
||||
ncall = 0;
|
||||
once.Do(call);
|
||||
ncall = 0
|
||||
once.Do(call)
|
||||
if ncall != 1 {
|
||||
t.Fatalf("once.Do(call) didn't call(): ncall=%d", ncall)
|
||||
}
|
||||
once.Do(call);
|
||||
once.Do(call)
|
||||
if ncall != 1 {
|
||||
t.Fatalf("second once.Do(call) did call(): ncall=%d", ncall)
|
||||
}
|
||||
once.Do(call);
|
||||
once.Do(call)
|
||||
if ncall != 1 {
|
||||
t.Fatalf("third once.Do(call) did call(): ncall=%d", ncall)
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"unsafe";
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
blockSize = 4096; // TODO(r): use statfs
|
||||
blockSize = 4096 // TODO(r): use statfs
|
||||
)
|
||||
|
||||
// Readdirnames reads the contents of the directory associated with file and
|
||||
@ -21,59 +21,59 @@ const (
|
||||
func (file *File) Readdirnames(count int) (names []string, err Error) {
|
||||
// If this file has no dirinfo, create one.
|
||||
if file.dirinfo == nil {
|
||||
file.dirinfo = new(dirInfo);
|
||||
file.dirinfo = new(dirInfo)
|
||||
// The buffer must be at least a block long.
|
||||
// TODO(r): use fstatfs to find fs block size.
|
||||
file.dirinfo.buf = make([]byte, blockSize);
|
||||
file.dirinfo.buf = make([]byte, blockSize)
|
||||
}
|
||||
d := file.dirinfo;
|
||||
size := count;
|
||||
d := file.dirinfo
|
||||
size := count
|
||||
if size < 0 {
|
||||
size = 100
|
||||
}
|
||||
names = make([]string, 0, size); // Empty with room to grow.
|
||||
names = make([]string, 0, size) // Empty with room to grow.
|
||||
for count != 0 {
|
||||
// Refill the buffer if necessary
|
||||
if d.bufp >= d.nbuf {
|
||||
var errno int;
|
||||
d.bufp = 0;
|
||||
var errno int
|
||||
d.bufp = 0
|
||||
// Final argument is (basep *uintptr) and the syscall doesn't take nil.
|
||||
d.nbuf, errno = syscall.Getdirentries(file.fd, d.buf, new(uintptr));
|
||||
d.nbuf, errno = syscall.Getdirentries(file.fd, d.buf, new(uintptr))
|
||||
if errno != 0 {
|
||||
d.nbuf = 0;
|
||||
return names, NewSyscallError("getdirentries", errno);
|
||||
d.nbuf = 0
|
||||
return names, NewSyscallError("getdirentries", errno)
|
||||
}
|
||||
if d.nbuf <= 0 {
|
||||
break // EOF
|
||||
break // EOF
|
||||
}
|
||||
}
|
||||
// Drain the buffer
|
||||
for count != 0 && d.bufp < d.nbuf {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]));
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]))
|
||||
if dirent.Reclen == 0 {
|
||||
d.bufp = d.nbuf;
|
||||
break;
|
||||
d.bufp = d.nbuf
|
||||
break
|
||||
}
|
||||
d.bufp += int(dirent.Reclen);
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
d.bufp += int(dirent.Reclen)
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
continue
|
||||
}
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]));
|
||||
var name = string(bytes[0:dirent.Namlen]);
|
||||
if name == "." || name == ".." { // Useless names
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
var name = string(bytes[0:dirent.Namlen])
|
||||
if name == "." || name == ".." { // Useless names
|
||||
continue
|
||||
}
|
||||
count--;
|
||||
count--
|
||||
if len(names) == cap(names) {
|
||||
nnames := make([]string, len(names), 2*len(names));
|
||||
nnames := make([]string, len(names), 2*len(names))
|
||||
for i := 0; i < len(names); i++ {
|
||||
nnames[i] = names[i]
|
||||
}
|
||||
names = nnames;
|
||||
names = nnames
|
||||
}
|
||||
names = names[0 : len(names)+1];
|
||||
names[len(names)-1] = name;
|
||||
names = names[0 : len(names)+1]
|
||||
names[len(names)-1] = name
|
||||
}
|
||||
}
|
||||
return names, nil;
|
||||
return names, nil
|
||||
}
|
||||
|
@ -5,70 +5,70 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"unsafe";
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
blockSize = 4096; // TODO(r): use statfs
|
||||
blockSize = 4096 // TODO(r): use statfs
|
||||
)
|
||||
|
||||
func (file *File) Readdirnames(count int) (names []string, err Error) {
|
||||
// If this file has no dirinfo, create one.
|
||||
if file.dirinfo == nil {
|
||||
file.dirinfo = new(dirInfo);
|
||||
file.dirinfo = new(dirInfo)
|
||||
// The buffer must be at least a block long.
|
||||
// TODO(r): use fstatfs to find fs block size.
|
||||
file.dirinfo.buf = make([]byte, blockSize);
|
||||
file.dirinfo.buf = make([]byte, blockSize)
|
||||
}
|
||||
d := file.dirinfo;
|
||||
size := count;
|
||||
d := file.dirinfo
|
||||
size := count
|
||||
if size < 0 {
|
||||
size = 100
|
||||
}
|
||||
names = make([]string, 0, size); // Empty with room to grow.
|
||||
names = make([]string, 0, size) // Empty with room to grow.
|
||||
for count != 0 {
|
||||
// Refill the buffer if necessary
|
||||
if d.bufp >= d.nbuf {
|
||||
var errno int;
|
||||
d.bufp = 0;
|
||||
var errno int
|
||||
d.bufp = 0
|
||||
// Final argument is (basep *uintptr) and the syscall doesn't take nil.
|
||||
d.nbuf, errno = syscall.Getdirentries(file.fd, d.buf, new(uintptr));
|
||||
d.nbuf, errno = syscall.Getdirentries(file.fd, d.buf, new(uintptr))
|
||||
if errno != 0 {
|
||||
d.nbuf = 0;
|
||||
return names, NewSyscallError("getdirentries", errno);
|
||||
d.nbuf = 0
|
||||
return names, NewSyscallError("getdirentries", errno)
|
||||
}
|
||||
if d.nbuf <= 0 {
|
||||
break // EOF
|
||||
break // EOF
|
||||
}
|
||||
}
|
||||
// Drain the buffer
|
||||
for count != 0 && d.bufp < d.nbuf {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]));
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]))
|
||||
if dirent.Reclen == 0 {
|
||||
d.bufp = d.nbuf;
|
||||
break;
|
||||
d.bufp = d.nbuf
|
||||
break
|
||||
}
|
||||
d.bufp += int(dirent.Reclen);
|
||||
if dirent.Fileno == 0 { // File absent in directory.
|
||||
d.bufp += int(dirent.Reclen)
|
||||
if dirent.Fileno == 0 { // File absent in directory.
|
||||
continue
|
||||
}
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]));
|
||||
var name = string(bytes[0:dirent.Namlen]);
|
||||
if name == "." || name == ".." { // Useless names
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
var name = string(bytes[0:dirent.Namlen])
|
||||
if name == "." || name == ".." { // Useless names
|
||||
continue
|
||||
}
|
||||
count--;
|
||||
count--
|
||||
if len(names) == cap(names) {
|
||||
nnames := make([]string, len(names), 2*len(names));
|
||||
nnames := make([]string, len(names), 2*len(names))
|
||||
for i := 0; i < len(names); i++ {
|
||||
nnames[i] = names[i]
|
||||
}
|
||||
names = nnames;
|
||||
names = nnames
|
||||
}
|
||||
names = names[0 : len(names)+1];
|
||||
names[len(names)-1] = name;
|
||||
names = names[0 : len(names)+1]
|
||||
names[len(names)-1] = name
|
||||
}
|
||||
}
|
||||
return names, nil;
|
||||
return names, nil
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"unsafe";
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
blockSize = 4096; // TODO(r): use statfs
|
||||
blockSize = 4096 // TODO(r): use statfs
|
||||
)
|
||||
|
||||
func clen(n []byte) int {
|
||||
@ -19,59 +19,59 @@ func clen(n []byte) int {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(n);
|
||||
return len(n)
|
||||
}
|
||||
|
||||
func (file *File) Readdirnames(count int) (names []string, err Error) {
|
||||
// If this file has no dirinfo, create one.
|
||||
if file.dirinfo == nil {
|
||||
file.dirinfo = new(dirInfo);
|
||||
file.dirinfo = new(dirInfo)
|
||||
// The buffer must be at least a block long.
|
||||
// TODO(r): use fstatfs to find fs block size.
|
||||
file.dirinfo.buf = make([]byte, blockSize);
|
||||
file.dirinfo.buf = make([]byte, blockSize)
|
||||
}
|
||||
d := file.dirinfo;
|
||||
size := count;
|
||||
d := file.dirinfo
|
||||
size := count
|
||||
if size < 0 {
|
||||
size = 100
|
||||
}
|
||||
names = make([]string, 0, size); // Empty with room to grow.
|
||||
names = make([]string, 0, size) // Empty with room to grow.
|
||||
for count != 0 {
|
||||
// Refill the buffer if necessary
|
||||
if d.bufp >= d.nbuf {
|
||||
var errno int;
|
||||
d.nbuf, errno = syscall.Getdents(file.fd, d.buf);
|
||||
var errno int
|
||||
d.nbuf, errno = syscall.Getdents(file.fd, d.buf)
|
||||
if errno != 0 {
|
||||
return names, NewSyscallError("getdents", errno)
|
||||
}
|
||||
if d.nbuf <= 0 {
|
||||
break // EOF
|
||||
break // EOF
|
||||
}
|
||||
d.bufp = 0;
|
||||
d.bufp = 0
|
||||
}
|
||||
// Drain the buffer
|
||||
for count != 0 && d.bufp < d.nbuf {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]));
|
||||
d.bufp += int(dirent.Reclen);
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]))
|
||||
d.bufp += int(dirent.Reclen)
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
continue
|
||||
}
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]));
|
||||
var name = string(bytes[0:clen(bytes)]);
|
||||
if name == "." || name == ".." { // Useless names
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
var name = string(bytes[0:clen(bytes)])
|
||||
if name == "." || name == ".." { // Useless names
|
||||
continue
|
||||
}
|
||||
count--;
|
||||
count--
|
||||
if len(names) == cap(names) {
|
||||
nnames := make([]string, len(names), 2*len(names));
|
||||
nnames := make([]string, len(names), 2*len(names))
|
||||
for i := 0; i < len(names); i++ {
|
||||
nnames[i] = names[i]
|
||||
}
|
||||
names = nnames;
|
||||
names = nnames
|
||||
}
|
||||
names = names[0 : len(names)+1];
|
||||
names[len(names)-1] = name;
|
||||
names = names[0 : len(names)+1]
|
||||
names[len(names)-1] = name
|
||||
}
|
||||
}
|
||||
return names, nil;
|
||||
return names, nil
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"unsafe";
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
blockSize = 4096; // TODO(r): use statfs
|
||||
blockSize = 4096 // TODO(r): use statfs
|
||||
)
|
||||
|
||||
func clen(n []byte) int {
|
||||
@ -19,59 +19,59 @@ func clen(n []byte) int {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(n);
|
||||
return len(n)
|
||||
}
|
||||
|
||||
func (file *File) Readdirnames(count int) (names []string, err Error) {
|
||||
// If this file has no dirinfo, create one.
|
||||
if file.dirinfo == nil {
|
||||
file.dirinfo = new(dirInfo);
|
||||
file.dirinfo = new(dirInfo)
|
||||
// The buffer must be at least a block long.
|
||||
// TODO(r): use fstatfs to find fs block size.
|
||||
file.dirinfo.buf = make([]byte, blockSize);
|
||||
file.dirinfo.buf = make([]byte, blockSize)
|
||||
}
|
||||
d := file.dirinfo;
|
||||
size := count;
|
||||
d := file.dirinfo
|
||||
size := count
|
||||
if size < 0 {
|
||||
size = 100
|
||||
}
|
||||
names = make([]string, 0, size); // Empty with room to grow.
|
||||
names = make([]string, 0, size) // Empty with room to grow.
|
||||
for count != 0 {
|
||||
// Refill the buffer if necessary
|
||||
if d.bufp >= d.nbuf {
|
||||
var errno int;
|
||||
d.nbuf, errno = syscall.Getdents(file.fd, d.buf);
|
||||
var errno int
|
||||
d.nbuf, errno = syscall.Getdents(file.fd, d.buf)
|
||||
if errno != 0 {
|
||||
return names, NewSyscallError("getdents", errno)
|
||||
}
|
||||
if d.nbuf <= 0 {
|
||||
break // EOF
|
||||
break // EOF
|
||||
}
|
||||
d.bufp = 0;
|
||||
d.bufp = 0
|
||||
}
|
||||
// Drain the buffer
|
||||
for count != 0 && d.bufp < d.nbuf {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]));
|
||||
d.bufp += int(dirent.Reclen);
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]))
|
||||
d.bufp += int(dirent.Reclen)
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
continue
|
||||
}
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]));
|
||||
var name = string(bytes[0:clen(bytes)]);
|
||||
if name == "." || name == ".." { // Useless names
|
||||
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
var name = string(bytes[0:clen(bytes)])
|
||||
if name == "." || name == ".." { // Useless names
|
||||
continue
|
||||
}
|
||||
count--;
|
||||
count--
|
||||
if len(names) == cap(names) {
|
||||
nnames := make([]string, len(names), 2*len(names));
|
||||
nnames := make([]string, len(names), 2*len(names))
|
||||
for i := 0; i < len(names); i++ {
|
||||
nnames[i] = names[i]
|
||||
}
|
||||
names = nnames;
|
||||
names = nnames
|
||||
}
|
||||
names = names[0 : len(names)+1];
|
||||
names[len(names)-1] = name;
|
||||
names = names[0 : len(names)+1]
|
||||
names[len(names)-1] = name
|
||||
}
|
||||
}
|
||||
return names, nil;
|
||||
return names, nil
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"once";
|
||||
"once"
|
||||
)
|
||||
|
||||
// ENOENV is the Error indicating that an environment variable does not exist.
|
||||
@ -17,12 +17,12 @@ var env map[string]string
|
||||
|
||||
|
||||
func copyenv() {
|
||||
env = make(map[string]string);
|
||||
env = make(map[string]string)
|
||||
for _, s := range Envs {
|
||||
for j := 0; j < len(s); j++ {
|
||||
if s[j] == '=' {
|
||||
env[s[0:j]] = s[j+1:];
|
||||
break;
|
||||
env[s[0:j]] = s[j+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,56 +31,56 @@ func copyenv() {
|
||||
// Getenverror retrieves the value of the environment variable named by the key.
|
||||
// It returns the value and an error, if any.
|
||||
func Getenverror(key string) (value string, err Error) {
|
||||
once.Do(copyenv);
|
||||
once.Do(copyenv)
|
||||
|
||||
if len(key) == 0 {
|
||||
return "", EINVAL
|
||||
}
|
||||
v, ok := env[key];
|
||||
v, ok := env[key]
|
||||
if !ok {
|
||||
return "", ENOENV
|
||||
}
|
||||
return v, nil;
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Getenv retrieves the value of the environment variable named by the key.
|
||||
// It returns the value, which will be empty if the variable is not present.
|
||||
func Getenv(key string) string {
|
||||
v, _ := Getenverror(key);
|
||||
return v;
|
||||
v, _ := Getenverror(key)
|
||||
return v
|
||||
}
|
||||
|
||||
// Setenv sets the value of the environment variable named by the key.
|
||||
// It returns an Error, if any.
|
||||
func Setenv(key, value string) Error {
|
||||
once.Do(copyenv);
|
||||
once.Do(copyenv)
|
||||
|
||||
if len(key) == 0 {
|
||||
return EINVAL
|
||||
}
|
||||
env[key] = value;
|
||||
return nil;
|
||||
env[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clearenv deletes all environment variables.
|
||||
func Clearenv() {
|
||||
once.Do(copyenv); // prevent copyenv in Getenv/Setenv
|
||||
env = make(map[string]string);
|
||||
once.Do(copyenv) // prevent copyenv in Getenv/Setenv
|
||||
env = make(map[string]string)
|
||||
}
|
||||
|
||||
// Environ returns an array of strings representing the environment,
|
||||
// in the form "key=value".
|
||||
func Environ() []string {
|
||||
once.Do(copyenv);
|
||||
a := make([]string, len(env));
|
||||
i := 0;
|
||||
once.Do(copyenv)
|
||||
a := make([]string, len(env))
|
||||
i := 0
|
||||
for k, v := range env {
|
||||
// check i < len(a) for safety,
|
||||
// in case env is changing underfoot.
|
||||
if i < len(a) {
|
||||
a[i] = k + "=" + v;
|
||||
i++;
|
||||
a[i] = k + "=" + v
|
||||
i++
|
||||
}
|
||||
}
|
||||
return a[0:i];
|
||||
return a[0:i]
|
||||
}
|
||||
|
@ -8,85 +8,85 @@ import syscall "syscall"
|
||||
|
||||
// An Error can represent any printable error condition.
|
||||
type Error interface {
|
||||
String() string;
|
||||
String() string
|
||||
}
|
||||
|
||||
// A helper type that can be embedded or wrapped to simplify satisfying
|
||||
// Error.
|
||||
type ErrorString string
|
||||
|
||||
func (e ErrorString) String() string { return string(e) }
|
||||
func (e ErrorString) String() string { return string(e) }
|
||||
|
||||
// Note: If the name of the function NewError changes,
|
||||
// pkg/go/doc/doc.go should be adjusted since it hardwires
|
||||
// this name in a heuristic.
|
||||
|
||||
// NewError converts s to an ErrorString, which satisfies the Error interface.
|
||||
func NewError(s string) Error { return ErrorString(s) }
|
||||
func NewError(s string) Error { return ErrorString(s) }
|
||||
|
||||
// Errno is the Unix error number. Names such as EINVAL are simple
|
||||
// wrappers to convert the error number into an Error.
|
||||
type Errno int64
|
||||
|
||||
func (e Errno) String() string { return syscall.Errstr(int(e)) }
|
||||
func (e Errno) String() string { return syscall.Errstr(int(e)) }
|
||||
|
||||
// Commonly known Unix errors.
|
||||
var (
|
||||
EPERM Error = Errno(syscall.EPERM);
|
||||
ENOENT Error = Errno(syscall.ENOENT);
|
||||
ESRCH Error = Errno(syscall.ESRCH);
|
||||
EINTR Error = Errno(syscall.EINTR);
|
||||
EIO Error = Errno(syscall.EIO);
|
||||
ENXIO Error = Errno(syscall.ENXIO);
|
||||
E2BIG Error = Errno(syscall.E2BIG);
|
||||
ENOEXEC Error = Errno(syscall.ENOEXEC);
|
||||
EBADF Error = Errno(syscall.EBADF);
|
||||
ECHILD Error = Errno(syscall.ECHILD);
|
||||
EDEADLK Error = Errno(syscall.EDEADLK);
|
||||
ENOMEM Error = Errno(syscall.ENOMEM);
|
||||
EACCES Error = Errno(syscall.EACCES);
|
||||
EFAULT Error = Errno(syscall.EFAULT);
|
||||
EBUSY Error = Errno(syscall.EBUSY);
|
||||
EEXIST Error = Errno(syscall.EEXIST);
|
||||
EXDEV Error = Errno(syscall.EXDEV);
|
||||
ENODEV Error = Errno(syscall.ENODEV);
|
||||
ENOTDIR Error = Errno(syscall.ENOTDIR);
|
||||
EISDIR Error = Errno(syscall.EISDIR);
|
||||
EINVAL Error = Errno(syscall.EINVAL);
|
||||
ENFILE Error = Errno(syscall.ENFILE);
|
||||
EMFILE Error = Errno(syscall.EMFILE);
|
||||
ENOTTY Error = Errno(syscall.ENOTTY);
|
||||
EFBIG Error = Errno(syscall.EFBIG);
|
||||
ENOSPC Error = Errno(syscall.ENOSPC);
|
||||
ESPIPE Error = Errno(syscall.ESPIPE);
|
||||
EROFS Error = Errno(syscall.EROFS);
|
||||
EMLINK Error = Errno(syscall.EMLINK);
|
||||
EPIPE Error = Errno(syscall.EPIPE);
|
||||
EAGAIN Error = Errno(syscall.EAGAIN);
|
||||
EDOM Error = Errno(syscall.EDOM);
|
||||
ERANGE Error = Errno(syscall.ERANGE);
|
||||
EADDRINUSE Error = Errno(syscall.EADDRINUSE);
|
||||
ECONNREFUSED Error = Errno(syscall.ECONNREFUSED);
|
||||
ENAMETOOLONG Error = Errno(syscall.ENAMETOOLONG);
|
||||
EAFNOSUPPORT Error = Errno(syscall.EAFNOSUPPORT);
|
||||
EPERM Error = Errno(syscall.EPERM)
|
||||
ENOENT Error = Errno(syscall.ENOENT)
|
||||
ESRCH Error = Errno(syscall.ESRCH)
|
||||
EINTR Error = Errno(syscall.EINTR)
|
||||
EIO Error = Errno(syscall.EIO)
|
||||
ENXIO Error = Errno(syscall.ENXIO)
|
||||
E2BIG Error = Errno(syscall.E2BIG)
|
||||
ENOEXEC Error = Errno(syscall.ENOEXEC)
|
||||
EBADF Error = Errno(syscall.EBADF)
|
||||
ECHILD Error = Errno(syscall.ECHILD)
|
||||
EDEADLK Error = Errno(syscall.EDEADLK)
|
||||
ENOMEM Error = Errno(syscall.ENOMEM)
|
||||
EACCES Error = Errno(syscall.EACCES)
|
||||
EFAULT Error = Errno(syscall.EFAULT)
|
||||
EBUSY Error = Errno(syscall.EBUSY)
|
||||
EEXIST Error = Errno(syscall.EEXIST)
|
||||
EXDEV Error = Errno(syscall.EXDEV)
|
||||
ENODEV Error = Errno(syscall.ENODEV)
|
||||
ENOTDIR Error = Errno(syscall.ENOTDIR)
|
||||
EISDIR Error = Errno(syscall.EISDIR)
|
||||
EINVAL Error = Errno(syscall.EINVAL)
|
||||
ENFILE Error = Errno(syscall.ENFILE)
|
||||
EMFILE Error = Errno(syscall.EMFILE)
|
||||
ENOTTY Error = Errno(syscall.ENOTTY)
|
||||
EFBIG Error = Errno(syscall.EFBIG)
|
||||
ENOSPC Error = Errno(syscall.ENOSPC)
|
||||
ESPIPE Error = Errno(syscall.ESPIPE)
|
||||
EROFS Error = Errno(syscall.EROFS)
|
||||
EMLINK Error = Errno(syscall.EMLINK)
|
||||
EPIPE Error = Errno(syscall.EPIPE)
|
||||
EAGAIN Error = Errno(syscall.EAGAIN)
|
||||
EDOM Error = Errno(syscall.EDOM)
|
||||
ERANGE Error = Errno(syscall.ERANGE)
|
||||
EADDRINUSE Error = Errno(syscall.EADDRINUSE)
|
||||
ECONNREFUSED Error = Errno(syscall.ECONNREFUSED)
|
||||
ENAMETOOLONG Error = Errno(syscall.ENAMETOOLONG)
|
||||
EAFNOSUPPORT Error = Errno(syscall.EAFNOSUPPORT)
|
||||
)
|
||||
|
||||
// PathError records an error and the operation and file path that caused it.
|
||||
type PathError struct {
|
||||
Op string;
|
||||
Path string;
|
||||
Error Error;
|
||||
Op string
|
||||
Path string
|
||||
Error Error
|
||||
}
|
||||
|
||||
func (e *PathError) String() string { return e.Op + " " + e.Path + ": " + e.Error.String() }
|
||||
func (e *PathError) String() string { return e.Op + " " + e.Path + ": " + e.Error.String() }
|
||||
|
||||
// SyscallError records an error from a specific system call.
|
||||
type SyscallError struct {
|
||||
Syscall string;
|
||||
Errno Errno;
|
||||
Syscall string
|
||||
Errno Errno
|
||||
}
|
||||
|
||||
func (e *SyscallError) String() string { return e.Syscall + ": " + e.Errno.String() }
|
||||
func (e *SyscallError) String() string { return e.Syscall + ": " + e.Errno.String() }
|
||||
|
||||
// Note: If the name of the function NewSyscallError changes,
|
||||
// pkg/go/doc/doc.go should be adjusted since it hardwires
|
||||
@ -99,5 +99,5 @@ func NewSyscallError(syscall string, errno int) Error {
|
||||
if errno == 0 {
|
||||
return nil
|
||||
}
|
||||
return &SyscallError{syscall, Errno(errno)};
|
||||
return &SyscallError{syscall, Errno(errno)}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ForkExec forks the current process and invokes Exec with the file, arguments,
|
||||
@ -17,7 +17,7 @@ import (
|
||||
// If dir is not empty, the child chdirs into the directory before execing the program.
|
||||
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*File) (pid int, err Error) {
|
||||
// Create array of integer (system) fds.
|
||||
intfd := make([]int, len(fd));
|
||||
intfd := make([]int, len(fd))
|
||||
for i, f := range fd {
|
||||
if f == nil {
|
||||
intfd[i] = -1
|
||||
@ -26,11 +26,11 @@ func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*File
|
||||
}
|
||||
}
|
||||
|
||||
p, e := syscall.ForkExec(argv0, argv, envv, dir, intfd);
|
||||
p, e := syscall.ForkExec(argv0, argv, envv, dir, intfd)
|
||||
if e != 0 {
|
||||
return 0, &PathError{"fork/exec", argv0, Errno(e)}
|
||||
}
|
||||
return p, nil;
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Exec replaces the current process with an execution of the program
|
||||
@ -41,11 +41,11 @@ func Exec(argv0 string, argv []string, envv []string) Error {
|
||||
if envv == nil {
|
||||
envv = Environ()
|
||||
}
|
||||
e := syscall.Exec(argv0, argv, envv);
|
||||
e := syscall.Exec(argv0, argv, envv)
|
||||
if e != 0 {
|
||||
return &PathError{"exec", argv0, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(rsc): Should os implement its own syscall.WaitStatus
|
||||
@ -57,17 +57,17 @@ func Exec(argv0 string, argv []string, envv []string) Error {
|
||||
|
||||
// Waitmsg stores the information about an exited process as reported by Wait.
|
||||
type Waitmsg struct {
|
||||
Pid int; // The process's id.
|
||||
syscall.WaitStatus; // System-dependent status info.
|
||||
Rusage *syscall.Rusage; // System-dependent resource usage info.
|
||||
Pid int // The process's id.
|
||||
syscall.WaitStatus // System-dependent status info.
|
||||
Rusage *syscall.Rusage // System-dependent resource usage info.
|
||||
}
|
||||
|
||||
// Options for Wait.
|
||||
const (
|
||||
WNOHANG = syscall.WNOHANG; // Don't wait if no process has exited.
|
||||
WSTOPPED = syscall.WSTOPPED; // If set, status of stopped subprocesses is also reported.
|
||||
WUNTRACED = WSTOPPED;
|
||||
WRUSAGE = 1 << 20; // Record resource usage.
|
||||
WNOHANG = syscall.WNOHANG // Don't wait if no process has exited.
|
||||
WSTOPPED = syscall.WSTOPPED // If set, status of stopped subprocesses is also reported.
|
||||
WUNTRACED = WSTOPPED
|
||||
WRUSAGE = 1 << 20 // Record resource usage.
|
||||
)
|
||||
|
||||
// WRUSAGE must not be too high a bit, to avoid clashing with Linux's
|
||||
@ -78,21 +78,21 @@ const (
|
||||
// Waitmsg describing its status and an Error, if any. The options
|
||||
// (WNOHANG etc.) affect the behavior of the Wait call.
|
||||
func Wait(pid int, options int) (w *Waitmsg, err Error) {
|
||||
var status syscall.WaitStatus;
|
||||
var rusage *syscall.Rusage;
|
||||
var status syscall.WaitStatus
|
||||
var rusage *syscall.Rusage
|
||||
if options&WRUSAGE != 0 {
|
||||
rusage = new(syscall.Rusage);
|
||||
options ^= WRUSAGE;
|
||||
rusage = new(syscall.Rusage)
|
||||
options ^= WRUSAGE
|
||||
}
|
||||
pid1, e := syscall.Wait4(pid, &status, options, rusage);
|
||||
pid1, e := syscall.Wait4(pid, &status, options, rusage)
|
||||
if e != 0 {
|
||||
return nil, NewSyscallError("wait", e)
|
||||
}
|
||||
w = new(Waitmsg);
|
||||
w.Pid = pid1;
|
||||
w.WaitStatus = status;
|
||||
w.Rusage = rusage;
|
||||
return w, nil;
|
||||
w = new(Waitmsg)
|
||||
w.Pid = pid1
|
||||
w.WaitStatus = status
|
||||
w.Rusage = rusage
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// Convert i to decimal string.
|
||||
@ -101,37 +101,37 @@ func itod(i int) string {
|
||||
return "0"
|
||||
}
|
||||
|
||||
u := uint64(i);
|
||||
u := uint64(i)
|
||||
if i < 0 {
|
||||
u = -u
|
||||
}
|
||||
|
||||
// Assemble decimal in reverse order.
|
||||
var b [32]byte;
|
||||
bp := len(b);
|
||||
var b [32]byte
|
||||
bp := len(b)
|
||||
for ; u > 0; u /= 10 {
|
||||
bp--;
|
||||
b[bp] = byte(u%10) + '0';
|
||||
bp--
|
||||
b[bp] = byte(u%10) + '0'
|
||||
}
|
||||
|
||||
if i < 0 {
|
||||
bp--;
|
||||
b[bp] = '-';
|
||||
bp--
|
||||
b[bp] = '-'
|
||||
}
|
||||
|
||||
return string(b[bp:]);
|
||||
return string(b[bp:])
|
||||
}
|
||||
|
||||
func (w Waitmsg) String() string {
|
||||
// TODO(austin) Use signal names when possible?
|
||||
res := "";
|
||||
res := ""
|
||||
switch {
|
||||
case w.Exited():
|
||||
res = "exit status " + itod(w.ExitStatus())
|
||||
case w.Signaled():
|
||||
res = "signal " + itod(w.Signal())
|
||||
case w.Stopped():
|
||||
res = "stop signal " + itod(w.StopSignal());
|
||||
res = "stop signal " + itod(w.StopSignal())
|
||||
if w.StopSignal() == syscall.SIGTRAP && w.TrapCause() != 0 {
|
||||
res += " (trap " + itod(w.TrapCause()) + ")"
|
||||
}
|
||||
@ -141,11 +141,11 @@ func (w Waitmsg) String() string {
|
||||
if w.CoreDump() {
|
||||
res += " (core dumped)"
|
||||
}
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
|
||||
// Getpid returns the process id of the caller.
|
||||
func Getpid() int { return syscall.Getpid() }
|
||||
func Getpid() int { return syscall.Getpid() }
|
||||
|
||||
// Getppid returns the process id of the caller's parent.
|
||||
func Getppid() int { return syscall.Getppid() }
|
||||
func Getppid() int { return syscall.Getppid() }
|
||||
|
@ -7,80 +7,80 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Auxiliary information if the File describes a directory
|
||||
type dirInfo struct {
|
||||
buf []byte; // buffer for directory I/O
|
||||
nbuf int; // length of buf; return value from Getdirentries
|
||||
bufp int; // location of next record in buf.
|
||||
buf []byte // buffer for directory I/O
|
||||
nbuf int // length of buf; return value from Getdirentries
|
||||
bufp int // location of next record in buf.
|
||||
}
|
||||
|
||||
// File represents an open file descriptor.
|
||||
type File struct {
|
||||
fd int;
|
||||
name string;
|
||||
dirinfo *dirInfo; // nil unless directory being read
|
||||
nepipe int; // number of consecutive EPIPE in Write
|
||||
fd int
|
||||
name string
|
||||
dirinfo *dirInfo // nil unless directory being read
|
||||
nepipe int // number of consecutive EPIPE in Write
|
||||
}
|
||||
|
||||
// Fd returns the integer Unix file descriptor referencing the open file.
|
||||
func (file *File) Fd() int { return file.fd }
|
||||
func (file *File) Fd() int { return file.fd }
|
||||
|
||||
// Name returns the name of the file as presented to Open.
|
||||
func (file *File) Name() string { return file.name }
|
||||
func (file *File) Name() string { return file.name }
|
||||
|
||||
// NewFile returns a new File with the given file descriptor and name.
|
||||
func NewFile(fd int, name string) *File {
|
||||
if fd < 0 {
|
||||
return nil
|
||||
}
|
||||
return &File{fd, name, nil, 0};
|
||||
return &File{fd, name, nil, 0}
|
||||
}
|
||||
|
||||
// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
|
||||
// standard output, and standard error file descriptors.
|
||||
var (
|
||||
Stdin = NewFile(0, "/dev/stdin");
|
||||
Stdout = NewFile(1, "/dev/stdout");
|
||||
Stderr = NewFile(2, "/dev/stderr");
|
||||
Stdin = NewFile(0, "/dev/stdin")
|
||||
Stdout = NewFile(1, "/dev/stdout")
|
||||
Stderr = NewFile(2, "/dev/stderr")
|
||||
)
|
||||
|
||||
// Flags to Open wrapping those of the underlying system. Not all flags
|
||||
// may be implemented on a given system.
|
||||
const (
|
||||
O_RDONLY = syscall.O_RDONLY; // open the file read-only.
|
||||
O_WRONLY = syscall.O_WRONLY; // open the file write-only.
|
||||
O_RDWR = syscall.O_RDWR; // open the file read-write.
|
||||
O_APPEND = syscall.O_APPEND; // open the file append-only.
|
||||
O_ASYNC = syscall.O_ASYNC; // generate a signal when I/O is available.
|
||||
O_CREAT = syscall.O_CREAT; // create a new file if none exists.
|
||||
O_EXCL = syscall.O_EXCL; // used with O_CREAT, file must not exist
|
||||
O_NOCTTY = syscall.O_NOCTTY; // do not make file the controlling tty.
|
||||
O_NONBLOCK = syscall.O_NONBLOCK; // open in non-blocking mode.
|
||||
O_NDELAY = O_NONBLOCK; // synonym for O_NONBLOCK
|
||||
O_SYNC = syscall.O_SYNC; // open for synchronous I/O.
|
||||
O_TRUNC = syscall.O_TRUNC; // if possible, truncate file when opened.
|
||||
O_CREATE = O_CREAT; // create a new file if none exists.
|
||||
O_RDONLY = syscall.O_RDONLY // open the file read-only.
|
||||
O_WRONLY = syscall.O_WRONLY // open the file write-only.
|
||||
O_RDWR = syscall.O_RDWR // open the file read-write.
|
||||
O_APPEND = syscall.O_APPEND // open the file append-only.
|
||||
O_ASYNC = syscall.O_ASYNC // generate a signal when I/O is available.
|
||||
O_CREAT = syscall.O_CREAT // create a new file if none exists.
|
||||
O_EXCL = syscall.O_EXCL // used with O_CREAT, file must not exist
|
||||
O_NOCTTY = syscall.O_NOCTTY // do not make file the controlling tty.
|
||||
O_NONBLOCK = syscall.O_NONBLOCK // open in non-blocking mode.
|
||||
O_NDELAY = O_NONBLOCK // synonym for O_NONBLOCK
|
||||
O_SYNC = syscall.O_SYNC // open for synchronous I/O.
|
||||
O_TRUNC = syscall.O_TRUNC // if possible, truncate file when opened.
|
||||
O_CREATE = O_CREAT // create a new file if none exists.
|
||||
)
|
||||
|
||||
// Open opens the named file with specified flag (O_RDONLY etc.) and perm, (0666 etc.)
|
||||
// if applicable. If successful, methods on the returned File can be used for I/O.
|
||||
// It returns the File and an Error, if any.
|
||||
func Open(name string, flag int, perm int) (file *File, err Error) {
|
||||
r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, perm);
|
||||
r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, perm)
|
||||
if e != 0 {
|
||||
return nil, &PathError{"open", name, Errno(e)}
|
||||
}
|
||||
|
||||
// There's a race here with fork/exec, which we are
|
||||
// content to live with. See ../syscall/exec.go
|
||||
if syscall.O_CLOEXEC == 0 { // O_CLOEXEC not supported
|
||||
if syscall.O_CLOEXEC == 0 { // O_CLOEXEC not supported
|
||||
syscall.CloseOnExec(r)
|
||||
}
|
||||
|
||||
return NewFile(r, name), nil;
|
||||
return NewFile(r, name), nil
|
||||
}
|
||||
|
||||
// Close closes the File, rendering it unusable for I/O.
|
||||
@ -89,17 +89,17 @@ func (file *File) Close() Error {
|
||||
if file == nil {
|
||||
return EINVAL
|
||||
}
|
||||
var err Error;
|
||||
var err Error
|
||||
if e := syscall.Close(file.fd); e != 0 {
|
||||
err = &PathError{"close", file.name, Errno(e)}
|
||||
}
|
||||
file.fd = -1; // so it can't be closed again
|
||||
return err;
|
||||
file.fd = -1 // so it can't be closed again
|
||||
return err
|
||||
}
|
||||
|
||||
type eofError int
|
||||
|
||||
func (eofError) String() string { return "EOF" }
|
||||
func (eofError) String() string { return "EOF" }
|
||||
|
||||
// EOF is the Error returned by Read when no more input is available.
|
||||
// Functions should return EOF only to signal a graceful end of input.
|
||||
@ -115,7 +115,7 @@ func (file *File) Read(b []byte) (n int, err Error) {
|
||||
if file == nil {
|
||||
return 0, EINVAL
|
||||
}
|
||||
n, e := syscall.Read(file.fd, b);
|
||||
n, e := syscall.Read(file.fd, b)
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
@ -125,7 +125,7 @@ func (file *File) Read(b []byte) (n int, err Error) {
|
||||
if e != 0 {
|
||||
err = &PathError{"read", file.name, Errno(e)}
|
||||
}
|
||||
return n, err;
|
||||
return n, err
|
||||
}
|
||||
|
||||
// ReadAt reads len(b) bytes from the File starting at byte offset off.
|
||||
@ -137,19 +137,19 @@ func (file *File) ReadAt(b []byte, off int64) (n int, err Error) {
|
||||
return 0, EINVAL
|
||||
}
|
||||
for len(b) > 0 {
|
||||
m, e := syscall.Pread(file.fd, b, off);
|
||||
m, e := syscall.Pread(file.fd, b, off)
|
||||
if m == 0 && e == 0 {
|
||||
return n, EOF
|
||||
}
|
||||
if e != 0 {
|
||||
err = &PathError{"read", file.name, Errno(e)};
|
||||
break;
|
||||
err = &PathError{"read", file.name, Errno(e)}
|
||||
break
|
||||
}
|
||||
n += m;
|
||||
b = b[m:];
|
||||
off += int64(m);
|
||||
n += m
|
||||
b = b[m:]
|
||||
off += int64(m)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Write writes len(b) bytes to the File.
|
||||
@ -159,12 +159,12 @@ func (file *File) Write(b []byte) (n int, err Error) {
|
||||
if file == nil {
|
||||
return 0, EINVAL
|
||||
}
|
||||
n, e := syscall.Write(file.fd, b);
|
||||
n, e := syscall.Write(file.fd, b)
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
if e == syscall.EPIPE {
|
||||
file.nepipe++;
|
||||
file.nepipe++
|
||||
if file.nepipe >= 10 {
|
||||
Exit(syscall.EPIPE)
|
||||
}
|
||||
@ -174,7 +174,7 @@ func (file *File) Write(b []byte) (n int, err Error) {
|
||||
if e != 0 {
|
||||
err = &PathError{"write", file.name, Errno(e)}
|
||||
}
|
||||
return n, err;
|
||||
return n, err
|
||||
}
|
||||
|
||||
// WriteAt writes len(b) bytes to the File starting at byte offset off.
|
||||
@ -185,16 +185,16 @@ func (file *File) WriteAt(b []byte, off int64) (n int, err Error) {
|
||||
return 0, EINVAL
|
||||
}
|
||||
for len(b) > 0 {
|
||||
m, e := syscall.Pwrite(file.fd, b, off);
|
||||
m, e := syscall.Pwrite(file.fd, b, off)
|
||||
if e != 0 {
|
||||
err = &PathError{"write", file.name, Errno(e)};
|
||||
break;
|
||||
err = &PathError{"write", file.name, Errno(e)}
|
||||
break
|
||||
}
|
||||
n += m;
|
||||
b = b[m:];
|
||||
off += int64(m);
|
||||
n += m
|
||||
b = b[m:]
|
||||
off += int64(m)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Seek sets the offset for the next Read or Write on file to offset, interpreted
|
||||
@ -202,14 +202,14 @@ func (file *File) WriteAt(b []byte, off int64) (n int, err Error) {
|
||||
// relative to the current offset, and 2 means relative to the end.
|
||||
// It returns the new offset and an Error, if any.
|
||||
func (file *File) Seek(offset int64, whence int) (ret int64, err Error) {
|
||||
r, e := syscall.Seek(file.fd, offset, whence);
|
||||
r, e := syscall.Seek(file.fd, offset, whence)
|
||||
if e == 0 && file.dirinfo != nil && r != 0 {
|
||||
e = syscall.EISDIR
|
||||
}
|
||||
if e != 0 {
|
||||
return 0, &PathError{"seek", file.name, Errno(e)}
|
||||
}
|
||||
return r, nil;
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// WriteString is like Write, but writes the contents of string s rather than
|
||||
@ -218,38 +218,38 @@ func (file *File) WriteString(s string) (ret int, err Error) {
|
||||
if file == nil {
|
||||
return 0, EINVAL
|
||||
}
|
||||
b := syscall.StringByteSlice(s);
|
||||
b = b[0 : len(b)-1];
|
||||
return file.Write(b);
|
||||
b := syscall.StringByteSlice(s)
|
||||
b = b[0 : len(b)-1]
|
||||
return file.Write(b)
|
||||
}
|
||||
|
||||
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
|
||||
// It returns the files and an Error, if any.
|
||||
func Pipe() (r *File, w *File, err Error) {
|
||||
var p [2]int;
|
||||
var p [2]int
|
||||
|
||||
// See ../syscall/exec.go for description of lock.
|
||||
syscall.ForkLock.RLock();
|
||||
e := syscall.Pipe(&p);
|
||||
syscall.ForkLock.RLock()
|
||||
e := syscall.Pipe(&p)
|
||||
if e != 0 {
|
||||
syscall.ForkLock.RUnlock();
|
||||
return nil, nil, NewSyscallError("pipe", e);
|
||||
syscall.ForkLock.RUnlock()
|
||||
return nil, nil, NewSyscallError("pipe", e)
|
||||
}
|
||||
syscall.CloseOnExec(p[0]);
|
||||
syscall.CloseOnExec(p[1]);
|
||||
syscall.ForkLock.RUnlock();
|
||||
syscall.CloseOnExec(p[0])
|
||||
syscall.CloseOnExec(p[1])
|
||||
syscall.ForkLock.RUnlock()
|
||||
|
||||
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil;
|
||||
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
|
||||
}
|
||||
|
||||
// Mkdir creates a new directory with the specified name and permission bits.
|
||||
// It returns an error, if any.
|
||||
func Mkdir(name string, perm int) Error {
|
||||
e := syscall.Mkdir(name, perm);
|
||||
e := syscall.Mkdir(name, perm)
|
||||
if e != 0 {
|
||||
return &PathError{"mkdir", name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stat returns a Dir structure describing the named file and an error, if any.
|
||||
@ -258,42 +258,42 @@ func Mkdir(name string, perm int) Error {
|
||||
// If name names an invalid symbolic link, the returned Dir describes
|
||||
// the link itself and has dir.FollowedSymlink set to false.
|
||||
func Stat(name string) (dir *Dir, err Error) {
|
||||
var lstat, stat syscall.Stat_t;
|
||||
e := syscall.Lstat(name, &lstat);
|
||||
var lstat, stat syscall.Stat_t
|
||||
e := syscall.Lstat(name, &lstat)
|
||||
if e != 0 {
|
||||
return nil, &PathError{"stat", name, Errno(e)}
|
||||
}
|
||||
statp := &lstat;
|
||||
statp := &lstat
|
||||
if lstat.Mode&syscall.S_IFMT == syscall.S_IFLNK {
|
||||
e := syscall.Stat(name, &stat);
|
||||
e := syscall.Stat(name, &stat)
|
||||
if e == 0 {
|
||||
statp = &stat
|
||||
}
|
||||
}
|
||||
return dirFromStat(name, new(Dir), &lstat, statp), nil;
|
||||
return dirFromStat(name, new(Dir), &lstat, statp), nil
|
||||
}
|
||||
|
||||
// Stat returns the Dir structure describing file.
|
||||
// It returns the Dir and an error, if any.
|
||||
func (file *File) Stat() (dir *Dir, err Error) {
|
||||
var stat syscall.Stat_t;
|
||||
e := syscall.Fstat(file.fd, &stat);
|
||||
var stat syscall.Stat_t
|
||||
e := syscall.Fstat(file.fd, &stat)
|
||||
if e != 0 {
|
||||
return nil, &PathError{"stat", file.name, Errno(e)}
|
||||
}
|
||||
return dirFromStat(file.name, new(Dir), &stat, &stat), nil;
|
||||
return dirFromStat(file.name, new(Dir), &stat, &stat), nil
|
||||
}
|
||||
|
||||
// Lstat returns the Dir structure describing the named file and an error, if any.
|
||||
// If the file is a symbolic link, the returned Dir describes the
|
||||
// symbolic link. Lstat makes no attempt to follow the link.
|
||||
func Lstat(name string) (dir *Dir, err Error) {
|
||||
var stat syscall.Stat_t;
|
||||
e := syscall.Lstat(name, &stat);
|
||||
var stat syscall.Stat_t
|
||||
e := syscall.Lstat(name, &stat)
|
||||
if e != 0 {
|
||||
return nil, &PathError{"lstat", name, Errno(e)}
|
||||
}
|
||||
return dirFromStat(name, new(Dir), &stat, &stat), nil;
|
||||
return dirFromStat(name, new(Dir), &stat, &stat), nil
|
||||
}
|
||||
|
||||
// Readdir reads the contents of the directory associated with file and
|
||||
@ -302,25 +302,25 @@ func Lstat(name string) (dir *Dir, err Error) {
|
||||
// A negative count means to read until EOF.
|
||||
// Readdir returns the array and an Error, if any.
|
||||
func (file *File) Readdir(count int) (dirs []Dir, err Error) {
|
||||
dirname := file.name;
|
||||
dirname := file.name
|
||||
if dirname == "" {
|
||||
dirname = "."
|
||||
}
|
||||
dirname += "/";
|
||||
names, err1 := file.Readdirnames(count);
|
||||
dirname += "/"
|
||||
names, err1 := file.Readdirnames(count)
|
||||
if err1 != nil {
|
||||
return nil, err1
|
||||
}
|
||||
dirs = make([]Dir, len(names));
|
||||
dirs = make([]Dir, len(names))
|
||||
for i, filename := range names {
|
||||
dirp, err := Lstat(dirname + filename);
|
||||
dirp, err := Lstat(dirname + filename)
|
||||
if dirp == nil || err != nil {
|
||||
dirs[i].Name = filename // rest is already zeroed out
|
||||
dirs[i].Name = filename // rest is already zeroed out
|
||||
} else {
|
||||
dirs[i] = *dirp
|
||||
}
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Chdir changes the current working directory to the named directory.
|
||||
@ -328,7 +328,7 @@ func Chdir(dir string) Error {
|
||||
if e := syscall.Chdir(dir); e != 0 {
|
||||
return &PathError{"chdir", dir, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chdir changes the current working directory to the file,
|
||||
@ -337,7 +337,7 @@ func (f *File) Chdir() Error {
|
||||
if e := syscall.Fchdir(f.fd); e != 0 {
|
||||
return &PathError{"chdir", f.name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes the named file or directory.
|
||||
@ -346,11 +346,11 @@ func Remove(name string) Error {
|
||||
// whether name is a file or directory.
|
||||
// Try both: it is cheaper on average than
|
||||
// doing a Stat plus the right one.
|
||||
e := syscall.Unlink(name);
|
||||
e := syscall.Unlink(name)
|
||||
if e == 0 {
|
||||
return nil
|
||||
}
|
||||
e1 := syscall.Rmdir(name);
|
||||
e1 := syscall.Rmdir(name)
|
||||
if e1 == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -367,16 +367,16 @@ func Remove(name string) Error {
|
||||
if e1 != syscall.ENOTDIR {
|
||||
e = e1
|
||||
}
|
||||
return &PathError{"remove", name, Errno(e)};
|
||||
return &PathError{"remove", name, Errno(e)}
|
||||
}
|
||||
|
||||
// LinkError records an error during a link or symlink or rename
|
||||
// system call and the paths that caused it.
|
||||
type LinkError struct {
|
||||
Op string;
|
||||
Old string;
|
||||
New string;
|
||||
Error Error;
|
||||
Op string
|
||||
Old string
|
||||
New string
|
||||
Error Error
|
||||
}
|
||||
|
||||
func (e *LinkError) String() string {
|
||||
@ -385,28 +385,28 @@ func (e *LinkError) String() string {
|
||||
|
||||
// Link creates a hard link.
|
||||
func Link(oldname, newname string) Error {
|
||||
e := syscall.Link(oldname, newname);
|
||||
e := syscall.Link(oldname, newname)
|
||||
if e != 0 {
|
||||
return &LinkError{"link", oldname, newname, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Symlink creates a symbolic link.
|
||||
func Symlink(oldname, newname string) Error {
|
||||
e := syscall.Symlink(oldname, newname);
|
||||
e := syscall.Symlink(oldname, newname)
|
||||
if e != 0 {
|
||||
return &LinkError{"symlink", oldname, newname, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Readlink reads the contents of a symbolic link: the destination of
|
||||
// the link. It returns the contents and an Error, if any.
|
||||
func Readlink(name string) (string, Error) {
|
||||
for len := 128; ; len *= 2 {
|
||||
b := make([]byte, len);
|
||||
n, e := syscall.Readlink(name, b);
|
||||
b := make([]byte, len)
|
||||
n, e := syscall.Readlink(name, b)
|
||||
if e != 0 {
|
||||
return "", &PathError{"readlink", name, Errno(e)}
|
||||
}
|
||||
@ -415,16 +415,16 @@ func Readlink(name string) (string, Error) {
|
||||
}
|
||||
}
|
||||
// Silence 6g.
|
||||
return "", nil;
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Rename renames a file.
|
||||
func Rename(oldname, newname string) Error {
|
||||
e := syscall.Rename(oldname, newname);
|
||||
e := syscall.Rename(oldname, newname)
|
||||
if e != 0 {
|
||||
return &LinkError{"rename", oldname, newname, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chmod changes the mode of the named file to mode.
|
||||
@ -433,7 +433,7 @@ func Chmod(name string, mode int) Error {
|
||||
if e := syscall.Chmod(name, mode); e != 0 {
|
||||
return &PathError{"chmod", name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chmod changes the mode of the file to mode.
|
||||
@ -441,7 +441,7 @@ func (f *File) Chmod(mode int) Error {
|
||||
if e := syscall.Fchmod(f.fd, mode); e != 0 {
|
||||
return &PathError{"chmod", f.name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chown changes the numeric uid and gid of the named file.
|
||||
@ -450,7 +450,7 @@ func Chown(name string, uid, gid int) Error {
|
||||
if e := syscall.Chown(name, uid, gid); e != 0 {
|
||||
return &PathError{"chown", name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lchown changes the numeric uid and gid of the named file.
|
||||
@ -459,7 +459,7 @@ func Lchown(name string, uid, gid int) Error {
|
||||
if e := syscall.Lchown(name, uid, gid); e != 0 {
|
||||
return &PathError{"lchown", name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chown changes the numeric uid and gid of the named file.
|
||||
@ -467,7 +467,7 @@ func (f *File) Chown(uid, gid int) Error {
|
||||
if e := syscall.Fchown(f.fd, uid, gid); e != 0 {
|
||||
return &PathError{"chown", f.name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Truncate changes the size of the named file.
|
||||
@ -476,7 +476,7 @@ func Truncate(name string, size int64) Error {
|
||||
if e := syscall.Truncate(name, size); e != 0 {
|
||||
return &PathError{"truncate", name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// Truncate changes the size of the file.
|
||||
@ -485,5 +485,5 @@ func (f *File) Truncate(size int64) Error {
|
||||
if e := syscall.Ftruncate(f.fd, size); e != 0 {
|
||||
return &PathError{"truncate", f.name, Errno(e)}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
package os
|
||||
|
||||
import (
|
||||
"syscall";
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Getwd returns a rooted path name corresponding to the
|
||||
@ -15,21 +15,21 @@ import (
|
||||
func Getwd() (string, Error) {
|
||||
// If the operating system provides a Getwd call, use it.
|
||||
if syscall.ImplementsGetwd {
|
||||
s, e := syscall.Getwd();
|
||||
return s, NewSyscallError("getwd", e);
|
||||
s, e := syscall.Getwd()
|
||||
return s, NewSyscallError("getwd", e)
|
||||
}
|
||||
|
||||
// Otherwise, we're trying to find our way back to ".".
|
||||
dot, err := Stat(".");
|
||||
dot, err := Stat(".")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Clumsy but widespread kludge:
|
||||
// if $PWD is set and matches ".", use it.
|
||||
pwd := Getenv("PWD");
|
||||
pwd := Getenv("PWD")
|
||||
if len(pwd) > 0 && pwd[0] == '/' {
|
||||
d, err := Stat(pwd);
|
||||
d, err := Stat(pwd)
|
||||
if err == nil && d.Dev == dot.Dev && d.Ino == dot.Ino {
|
||||
return pwd, nil
|
||||
}
|
||||
@ -37,7 +37,7 @@ func Getwd() (string, Error) {
|
||||
|
||||
// Root is a special case because it has no parent
|
||||
// and ends in a slash.
|
||||
root, err := Stat("/");
|
||||
root, err := Stat("/")
|
||||
if err != nil {
|
||||
// Can't stat root - no hope.
|
||||
return "", err
|
||||
@ -49,44 +49,44 @@ func Getwd() (string, Error) {
|
||||
// General algorithm: find name in parent
|
||||
// and then find name of parent. Each iteration
|
||||
// adds /name to the beginning of pwd.
|
||||
pwd = "";
|
||||
pwd = ""
|
||||
for parent := ".."; ; parent = "../" + parent {
|
||||
if len(parent) >= 1024 { // Sanity check
|
||||
if len(parent) >= 1024 { // Sanity check
|
||||
return "", ENAMETOOLONG
|
||||
}
|
||||
fd, err := Open(parent, O_RDONLY, 0);
|
||||
fd, err := Open(parent, O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for {
|
||||
names, err := fd.Readdirnames(100);
|
||||
names, err := fd.Readdirnames(100)
|
||||
if err != nil {
|
||||
fd.Close();
|
||||
return "", err;
|
||||
fd.Close()
|
||||
return "", err
|
||||
}
|
||||
for _, name := range names {
|
||||
d, _ := Lstat(parent + "/" + name);
|
||||
d, _ := Lstat(parent + "/" + name)
|
||||
if d.Dev == dot.Dev && d.Ino == dot.Ino {
|
||||
pwd = "/" + name + pwd;
|
||||
goto Found;
|
||||
pwd = "/" + name + pwd
|
||||
goto Found
|
||||
}
|
||||
}
|
||||
}
|
||||
fd.Close();
|
||||
return "", ENOENT;
|
||||
fd.Close()
|
||||
return "", ENOENT
|
||||
|
||||
Found:
|
||||
pd, err := fd.Stat();
|
||||
pd, err := fd.Stat()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fd.Close();
|
||||
fd.Close()
|
||||
if pd.Dev == root.Dev && pd.Ino == root.Ino {
|
||||
break
|
||||
}
|
||||
// Set up for next round.
|
||||
dot = pd;
|
||||
dot = pd
|
||||
}
|
||||
return pwd, nil;
|
||||
return pwd, nil
|
||||
}
|
||||
|
@ -5,13 +5,13 @@
|
||||
package os_test
|
||||
|
||||
import (
|
||||
"bytes";
|
||||
"fmt";
|
||||
"io";
|
||||
"io/ioutil";
|
||||
. "os";
|
||||
"strings";
|
||||
"testing";
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
. "os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var dot = []string{
|
||||
@ -34,16 +34,16 @@ var etc = []string{
|
||||
}
|
||||
|
||||
func size(name string, t *testing.T) uint64 {
|
||||
file, err := Open(name, O_RDONLY, 0);
|
||||
defer file.Close();
|
||||
file, err := Open(name, O_RDONLY, 0)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
t.Fatal("open failed:", err)
|
||||
}
|
||||
var buf [100]byte;
|
||||
len := 0;
|
||||
var buf [100]byte
|
||||
len := 0
|
||||
for {
|
||||
n, e := file.Read(&buf);
|
||||
len += n;
|
||||
n, e := file.Read(&buf)
|
||||
len += n
|
||||
if e == EOF {
|
||||
break
|
||||
}
|
||||
@ -51,68 +51,68 @@ func size(name string, t *testing.T) uint64 {
|
||||
t.Fatal("read failed:", err)
|
||||
}
|
||||
}
|
||||
return uint64(len);
|
||||
return uint64(len)
|
||||
}
|
||||
|
||||
func TestStat(t *testing.T) {
|
||||
dir, err := Stat("/etc/passwd");
|
||||
dir, err := Stat("/etc/passwd")
|
||||
if err != nil {
|
||||
t.Fatal("stat failed:", err)
|
||||
}
|
||||
if dir.Name != "passwd" {
|
||||
t.Error("name should be passwd; is", dir.Name)
|
||||
}
|
||||
filesize := size("/etc/passwd", t);
|
||||
filesize := size("/etc/passwd", t)
|
||||
if dir.Size != filesize {
|
||||
t.Error("size should be", filesize, "; is", dir.Size)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFstat(t *testing.T) {
|
||||
file, err1 := Open("/etc/passwd", O_RDONLY, 0);
|
||||
defer file.Close();
|
||||
file, err1 := Open("/etc/passwd", O_RDONLY, 0)
|
||||
defer file.Close()
|
||||
if err1 != nil {
|
||||
t.Fatal("open failed:", err1)
|
||||
}
|
||||
dir, err2 := file.Stat();
|
||||
dir, err2 := file.Stat()
|
||||
if err2 != nil {
|
||||
t.Fatal("fstat failed:", err2)
|
||||
}
|
||||
if dir.Name != "passwd" {
|
||||
t.Error("name should be passwd; is", dir.Name)
|
||||
}
|
||||
filesize := size("/etc/passwd", t);
|
||||
filesize := size("/etc/passwd", t)
|
||||
if dir.Size != filesize {
|
||||
t.Error("size should be", filesize, "; is", dir.Size)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLstat(t *testing.T) {
|
||||
dir, err := Lstat("/etc/passwd");
|
||||
dir, err := Lstat("/etc/passwd")
|
||||
if err != nil {
|
||||
t.Fatal("lstat failed:", err)
|
||||
}
|
||||
if dir.Name != "passwd" {
|
||||
t.Error("name should be passwd; is", dir.Name)
|
||||
}
|
||||
filesize := size("/etc/passwd", t);
|
||||
filesize := size("/etc/passwd", t)
|
||||
if dir.Size != filesize {
|
||||
t.Error("size should be", filesize, "; is", dir.Size)
|
||||
}
|
||||
}
|
||||
|
||||
func testReaddirnames(dir string, contents []string, t *testing.T) {
|
||||
file, err := Open(dir, O_RDONLY, 0);
|
||||
defer file.Close();
|
||||
file, err := Open(dir, O_RDONLY, 0)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", dir, err)
|
||||
}
|
||||
s, err2 := file.Readdirnames(-1);
|
||||
s, err2 := file.Readdirnames(-1)
|
||||
if err2 != nil {
|
||||
t.Fatalf("readdirnames %q failed: %v", err2)
|
||||
}
|
||||
for _, m := range contents {
|
||||
found := false;
|
||||
found := false
|
||||
for _, n := range s {
|
||||
if n == "." || n == ".." {
|
||||
t.Errorf("got %s in directory", n)
|
||||
@ -121,7 +121,7 @@ func testReaddirnames(dir string, contents []string, t *testing.T) {
|
||||
if found {
|
||||
t.Error("present twice:", m)
|
||||
}
|
||||
found = true;
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
@ -131,23 +131,23 @@ func testReaddirnames(dir string, contents []string, t *testing.T) {
|
||||
}
|
||||
|
||||
func testReaddir(dir string, contents []string, t *testing.T) {
|
||||
file, err := Open(dir, O_RDONLY, 0);
|
||||
defer file.Close();
|
||||
file, err := Open(dir, O_RDONLY, 0)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", dir, err)
|
||||
}
|
||||
s, err2 := file.Readdir(-1);
|
||||
s, err2 := file.Readdir(-1)
|
||||
if err2 != nil {
|
||||
t.Fatalf("readdir %q failed: %v", dir, err2)
|
||||
}
|
||||
for _, m := range contents {
|
||||
found := false;
|
||||
found := false
|
||||
for _, n := range s {
|
||||
if m == n.Name {
|
||||
if found {
|
||||
t.Error("present twice:", m)
|
||||
}
|
||||
found = true;
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
@ -157,51 +157,51 @@ func testReaddir(dir string, contents []string, t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReaddirnames(t *testing.T) {
|
||||
testReaddirnames(".", dot, t);
|
||||
testReaddirnames("/etc", etc, t);
|
||||
testReaddirnames(".", dot, t)
|
||||
testReaddirnames("/etc", etc, t)
|
||||
}
|
||||
|
||||
func TestReaddir(t *testing.T) {
|
||||
testReaddir(".", dot, t);
|
||||
testReaddir("/etc", etc, t);
|
||||
testReaddir(".", dot, t)
|
||||
testReaddir("/etc", etc, t)
|
||||
}
|
||||
|
||||
// Read the directory one entry at a time.
|
||||
func smallReaddirnames(file *File, length int, t *testing.T) []string {
|
||||
names := make([]string, length);
|
||||
count := 0;
|
||||
names := make([]string, length)
|
||||
count := 0
|
||||
for {
|
||||
d, err := file.Readdirnames(1);
|
||||
d, err := file.Readdirnames(1)
|
||||
if err != nil {
|
||||
t.Fatalf("readdir %q failed: %v", file.Name(), err)
|
||||
}
|
||||
if len(d) == 0 {
|
||||
break
|
||||
}
|
||||
names[count] = d[0];
|
||||
count++;
|
||||
names[count] = d[0]
|
||||
count++
|
||||
}
|
||||
return names[0:count];
|
||||
return names[0:count]
|
||||
}
|
||||
|
||||
// Check that reading a directory one entry at a time gives the same result
|
||||
// as reading it all at once.
|
||||
func TestReaddirnamesOneAtATime(t *testing.T) {
|
||||
dir := "/usr/bin"; // big directory that doesn't change often.
|
||||
file, err := Open(dir, O_RDONLY, 0);
|
||||
defer file.Close();
|
||||
dir := "/usr/bin" // big directory that doesn't change often.
|
||||
file, err := Open(dir, O_RDONLY, 0)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", dir, err)
|
||||
}
|
||||
all, err1 := file.Readdirnames(-1);
|
||||
all, err1 := file.Readdirnames(-1)
|
||||
if err1 != nil {
|
||||
t.Fatalf("readdirnames %q failed: %v", dir, err1)
|
||||
}
|
||||
file1, err2 := Open(dir, O_RDONLY, 0);
|
||||
file1, err2 := Open(dir, O_RDONLY, 0)
|
||||
if err2 != nil {
|
||||
t.Fatalf("open %q failed: %v", dir, err2)
|
||||
}
|
||||
small := smallReaddirnames(file1, len(all)+100, t); // +100 in case we screw up
|
||||
small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
|
||||
for i, n := range all {
|
||||
if small[i] != n {
|
||||
t.Errorf("small read %q %q mismatch: %v", small[i], n)
|
||||
@ -210,26 +210,26 @@ func TestReaddirnamesOneAtATime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHardLink(t *testing.T) {
|
||||
from, to := "hardlinktestfrom", "hardlinktestto";
|
||||
Remove(from); // Just in case.
|
||||
file, err := Open(to, O_CREAT|O_WRONLY, 0666);
|
||||
from, to := "hardlinktestfrom", "hardlinktestto"
|
||||
Remove(from) // Just in case.
|
||||
file, err := Open(to, O_CREAT|O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", to, err)
|
||||
}
|
||||
defer Remove(to);
|
||||
defer Remove(to)
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", to, err)
|
||||
}
|
||||
err = Link(to, from);
|
||||
err = Link(to, from)
|
||||
if err != nil {
|
||||
t.Fatalf("link %q, %q failed: %v", to, from, err)
|
||||
}
|
||||
defer Remove(from);
|
||||
tostat, err := Stat(to);
|
||||
defer Remove(from)
|
||||
tostat, err := Stat(to)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", to, err)
|
||||
}
|
||||
fromstat, err := Stat(from);
|
||||
fromstat, err := Stat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err)
|
||||
}
|
||||
@ -239,74 +239,74 @@ func TestHardLink(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSymLink(t *testing.T) {
|
||||
from, to := "symlinktestfrom", "symlinktestto";
|
||||
Remove(from); // Just in case.
|
||||
file, err := Open(to, O_CREAT|O_WRONLY, 0666);
|
||||
from, to := "symlinktestfrom", "symlinktestto"
|
||||
Remove(from) // Just in case.
|
||||
file, err := Open(to, O_CREAT|O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", to, err)
|
||||
}
|
||||
defer Remove(to);
|
||||
defer Remove(to)
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", to, err)
|
||||
}
|
||||
err = Symlink(to, from);
|
||||
err = Symlink(to, from)
|
||||
if err != nil {
|
||||
t.Fatalf("symlink %q, %q failed: %v", to, from, err)
|
||||
}
|
||||
defer Remove(from);
|
||||
tostat, err := Stat(to);
|
||||
defer Remove(from)
|
||||
tostat, err := Stat(to)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", to, err)
|
||||
}
|
||||
if tostat.FollowedSymlink {
|
||||
t.Fatalf("stat %q claims to have followed a symlink", to)
|
||||
}
|
||||
fromstat, err := Stat(from);
|
||||
fromstat, err := Stat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err)
|
||||
}
|
||||
if tostat.Dev != fromstat.Dev || tostat.Ino != fromstat.Ino {
|
||||
t.Errorf("symlink %q, %q did not create symlink", to, from)
|
||||
}
|
||||
fromstat, err = Lstat(from);
|
||||
fromstat, err = Lstat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("lstat %q failed: %v", from, err)
|
||||
}
|
||||
if !fromstat.IsSymlink() {
|
||||
t.Fatalf("symlink %q, %q did not create symlink", to, from)
|
||||
}
|
||||
fromstat, err = Stat(from);
|
||||
fromstat, err = Stat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err)
|
||||
}
|
||||
if !fromstat.FollowedSymlink {
|
||||
t.Fatalf("stat %q did not follow symlink")
|
||||
}
|
||||
s, err := Readlink(from);
|
||||
s, err := Readlink(from)
|
||||
if err != nil {
|
||||
t.Fatalf("readlink %q failed: %v", from, err)
|
||||
}
|
||||
if s != to {
|
||||
t.Fatalf("after symlink %q != %q", s, to)
|
||||
}
|
||||
file, err = Open(from, O_RDONLY, 0);
|
||||
file, err = Open(from, O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", from, err)
|
||||
}
|
||||
file.Close();
|
||||
file.Close()
|
||||
}
|
||||
|
||||
func TestLongSymlink(t *testing.T) {
|
||||
s := "0123456789abcdef";
|
||||
s := "0123456789abcdef"
|
||||
// Long, but not too long: a common limit is 255.
|
||||
s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s;
|
||||
from := "longsymlinktestfrom";
|
||||
err := Symlink(s, from);
|
||||
s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
|
||||
from := "longsymlinktestfrom"
|
||||
err := Symlink(s, from)
|
||||
if err != nil {
|
||||
t.Fatalf("symlink %q, %q failed: %v", s, from, err)
|
||||
}
|
||||
defer Remove(from);
|
||||
r, err := Readlink(from);
|
||||
defer Remove(from)
|
||||
r, err := Readlink(from)
|
||||
if err != nil {
|
||||
t.Fatalf("readlink %q failed: %v", from, err)
|
||||
}
|
||||
@ -316,49 +316,49 @@ func TestLongSymlink(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRename(t *testing.T) {
|
||||
from, to := "renamefrom", "renameto";
|
||||
Remove(to); // Just in case.
|
||||
file, err := Open(from, O_CREAT|O_WRONLY, 0666);
|
||||
from, to := "renamefrom", "renameto"
|
||||
Remove(to) // Just in case.
|
||||
file, err := Open(from, O_CREAT|O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", to, err)
|
||||
}
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", to, err)
|
||||
}
|
||||
err = Rename(from, to);
|
||||
err = Rename(from, to)
|
||||
if err != nil {
|
||||
t.Fatalf("rename %q, %q failed: %v", to, from, err)
|
||||
}
|
||||
defer Remove(to);
|
||||
_, err = Stat(to);
|
||||
defer Remove(to)
|
||||
_, err = Stat(to)
|
||||
if err != nil {
|
||||
t.Errorf("stat %q failed: %v", to, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestForkExec(t *testing.T) {
|
||||
r, w, err := Pipe();
|
||||
r, w, err := Pipe()
|
||||
if err != nil {
|
||||
t.Fatalf("Pipe: %v", err)
|
||||
}
|
||||
pid, err := ForkExec("/bin/pwd", []string{"pwd"}, nil, "/", []*File{nil, w, Stderr});
|
||||
pid, err := ForkExec("/bin/pwd", []string{"pwd"}, nil, "/", []*File{nil, w, Stderr})
|
||||
if err != nil {
|
||||
t.Fatalf("ForkExec: %v", err)
|
||||
}
|
||||
w.Close();
|
||||
w.Close()
|
||||
|
||||
var b bytes.Buffer;
|
||||
io.Copy(&b, r);
|
||||
output := b.String();
|
||||
expect := "/\n";
|
||||
var b bytes.Buffer
|
||||
io.Copy(&b, r)
|
||||
output := b.String()
|
||||
expect := "/\n"
|
||||
if output != expect {
|
||||
t.Errorf("exec /bin/pwd returned %q wanted %q", output, expect)
|
||||
}
|
||||
Wait(pid, 0);
|
||||
Wait(pid, 0)
|
||||
}
|
||||
|
||||
func checkMode(t *testing.T, path string, mode uint32) {
|
||||
dir, err := Stat(path);
|
||||
dir, err := Stat(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
|
||||
}
|
||||
@ -368,9 +368,9 @@ func checkMode(t *testing.T, path string, mode uint32) {
|
||||
}
|
||||
|
||||
func TestChmod(t *testing.T) {
|
||||
MkdirAll("_obj", 0777);
|
||||
const Path = "_obj/_TestChmod_";
|
||||
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666);
|
||||
MkdirAll("_obj", 0777)
|
||||
const Path = "_obj/_TestChmod_"
|
||||
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %s: %s", Path, err)
|
||||
}
|
||||
@ -378,19 +378,19 @@ func TestChmod(t *testing.T) {
|
||||
if err = Chmod(Path, 0456); err != nil {
|
||||
t.Fatalf("chmod %s 0456: %s", Path, err)
|
||||
}
|
||||
checkMode(t, Path, 0456);
|
||||
checkMode(t, Path, 0456)
|
||||
|
||||
if err = fd.Chmod(0123); err != nil {
|
||||
t.Fatalf("fchmod %s 0123: %s", Path, err)
|
||||
}
|
||||
checkMode(t, Path, 0123);
|
||||
checkMode(t, Path, 0123)
|
||||
|
||||
fd.Close();
|
||||
Remove(Path);
|
||||
fd.Close()
|
||||
Remove(Path)
|
||||
}
|
||||
|
||||
func checkUidGid(t *testing.T, path string, uid, gid int) {
|
||||
dir, err := Stat(path);
|
||||
dir, err := Stat(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat %q (looking for uid/gid %d/%d): %s", path, uid, gid, err)
|
||||
}
|
||||
@ -408,49 +408,49 @@ func TestChown(t *testing.T) {
|
||||
// on the file. If _obj is on NFS, the Getgroups groups are
|
||||
// basically useless.
|
||||
|
||||
const Path = "/tmp/_TestChown_";
|
||||
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666);
|
||||
const Path = "/tmp/_TestChown_"
|
||||
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %s: %s", Path, err)
|
||||
}
|
||||
dir, err := fd.Stat();
|
||||
dir, err := fd.Stat()
|
||||
if err != nil {
|
||||
t.Fatalf("fstat %s: %s", Path, err)
|
||||
}
|
||||
defer fd.Close();
|
||||
defer Remove(Path);
|
||||
defer fd.Close()
|
||||
defer Remove(Path)
|
||||
|
||||
// Can't change uid unless root, but can try
|
||||
// changing the group id. First try our current group.
|
||||
gid := Getgid();
|
||||
t.Log("gid:", gid);
|
||||
gid := Getgid()
|
||||
t.Log("gid:", gid)
|
||||
if err = Chown(Path, -1, gid); err != nil {
|
||||
t.Fatalf("chown %s -1 %d: %s", Path, gid, err)
|
||||
}
|
||||
checkUidGid(t, Path, int(dir.Uid), gid);
|
||||
checkUidGid(t, Path, int(dir.Uid), gid)
|
||||
|
||||
// Then try all the auxiliary groups.
|
||||
groups, err := Getgroups();
|
||||
groups, err := Getgroups()
|
||||
if err != nil {
|
||||
t.Fatalf("getgroups: %s", err)
|
||||
}
|
||||
t.Log("groups: ", groups);
|
||||
t.Log("groups: ", groups)
|
||||
for _, g := range groups {
|
||||
if err = Chown(Path, -1, g); err != nil {
|
||||
t.Fatalf("chown %s -1 %d: %s", Path, g, err)
|
||||
}
|
||||
checkUidGid(t, Path, int(dir.Uid), g);
|
||||
checkUidGid(t, Path, int(dir.Uid), g)
|
||||
|
||||
// change back to gid to test fd.Chown
|
||||
if err = fd.Chown(-1, gid); err != nil {
|
||||
t.Fatalf("fchown %s -1 %d: %s", Path, gid, err)
|
||||
}
|
||||
checkUidGid(t, Path, int(dir.Uid), gid);
|
||||
checkUidGid(t, Path, int(dir.Uid), gid)
|
||||
}
|
||||
}
|
||||
|
||||
func checkSize(t *testing.T, path string, size uint64) {
|
||||
dir, err := Stat(path);
|
||||
dir, err := Stat(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat %q (looking for size %d): %s", path, size, err)
|
||||
}
|
||||
@ -460,73 +460,73 @@ func checkSize(t *testing.T, path string, size uint64) {
|
||||
}
|
||||
|
||||
func TestTruncate(t *testing.T) {
|
||||
MkdirAll("_obj", 0777);
|
||||
const Path = "_obj/_TestTruncate_";
|
||||
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666);
|
||||
MkdirAll("_obj", 0777)
|
||||
const Path = "_obj/_TestTruncate_"
|
||||
fd, err := Open(Path, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %s: %s", Path, err)
|
||||
}
|
||||
|
||||
checkSize(t, Path, 0);
|
||||
fd.Write(strings.Bytes("hello, world\n"));
|
||||
checkSize(t, Path, 13);
|
||||
fd.Truncate(10);
|
||||
checkSize(t, Path, 10);
|
||||
fd.Truncate(1024);
|
||||
checkSize(t, Path, 1024);
|
||||
fd.Truncate(0);
|
||||
checkSize(t, Path, 0);
|
||||
fd.Write(strings.Bytes("surprise!"));
|
||||
checkSize(t, Path, 13+9); // wrote at offset past where hello, world was.
|
||||
fd.Close();
|
||||
Remove(Path);
|
||||
checkSize(t, Path, 0)
|
||||
fd.Write(strings.Bytes("hello, world\n"))
|
||||
checkSize(t, Path, 13)
|
||||
fd.Truncate(10)
|
||||
checkSize(t, Path, 10)
|
||||
fd.Truncate(1024)
|
||||
checkSize(t, Path, 1024)
|
||||
fd.Truncate(0)
|
||||
checkSize(t, Path, 0)
|
||||
fd.Write(strings.Bytes("surprise!"))
|
||||
checkSize(t, Path, 13+9) // wrote at offset past where hello, world was.
|
||||
fd.Close()
|
||||
Remove(Path)
|
||||
}
|
||||
|
||||
func TestChdirAndGetwd(t *testing.T) {
|
||||
fd, err := Open(".", O_RDONLY, 0);
|
||||
fd, err := Open(".", O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Open .: %s", err)
|
||||
}
|
||||
// These are chosen carefully not to be symlinks on a Mac
|
||||
// (unlike, say, /var, /etc, and /tmp).
|
||||
dirs := []string{"/bin", "/", "/usr/bin"};
|
||||
dirs := []string{"/bin", "/", "/usr/bin"}
|
||||
for mode := 0; mode < 2; mode++ {
|
||||
for _, d := range dirs {
|
||||
if mode == 0 {
|
||||
err = Chdir(d)
|
||||
} else {
|
||||
fd1, err := Open(d, O_RDONLY, 0);
|
||||
fd1, err := Open(d, O_RDONLY, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Open %s: %s", d, err);
|
||||
continue;
|
||||
t.Errorf("Open %s: %s", d, err)
|
||||
continue
|
||||
}
|
||||
err = fd1.Chdir();
|
||||
fd1.Close();
|
||||
err = fd1.Chdir()
|
||||
fd1.Close()
|
||||
}
|
||||
pwd, err1 := Getwd();
|
||||
err2 := fd.Chdir();
|
||||
pwd, err1 := Getwd()
|
||||
err2 := fd.Chdir()
|
||||
if err2 != nil {
|
||||
// We changed the current directory and cannot go back.
|
||||
// Don't let the tests continue; they'll scribble
|
||||
// all over some other directory.
|
||||
fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2);
|
||||
Exit(1);
|
||||
fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
|
||||
Exit(1)
|
||||
}
|
||||
if err != nil {
|
||||
fd.Close();
|
||||
t.Fatalf("Chdir %s: %s", d, err);
|
||||
fd.Close()
|
||||
t.Fatalf("Chdir %s: %s", d, err)
|
||||
}
|
||||
if err1 != nil {
|
||||
fd.Close();
|
||||
t.Fatalf("Getwd in %s: %s", d, err1);
|
||||
fd.Close()
|
||||
t.Fatalf("Getwd in %s: %s", d, err1)
|
||||
}
|
||||
if pwd != d {
|
||||
fd.Close();
|
||||
t.Fatalf("Getwd returned %q want %q", pwd, d);
|
||||
fd.Close()
|
||||
t.Fatalf("Getwd returned %q want %q", pwd, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
fd.Close();
|
||||
fd.Close()
|
||||
}
|
||||
|
||||
func TestTime(t *testing.T) {
|
||||
@ -536,25 +536,25 @@ func TestTime(t *testing.T) {
|
||||
// filling in the structure passed to the system call.
|
||||
// Too bad the compiler doesn't know that
|
||||
// 365.24*86400 is an integer.
|
||||
sec, nsec, err := Time();
|
||||
sec, nsec, err := Time()
|
||||
if sec < (2009-1970)*36524*864 {
|
||||
t.Errorf("Time() = %d, %d, %s; not plausible", sec, nsec, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeek(t *testing.T) {
|
||||
f, err := Open("_obj/seektest", O_CREAT|O_RDWR|O_TRUNC, 0666);
|
||||
f, err := Open("_obj/seektest", O_CREAT|O_RDWR|O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open _obj/seektest: %s", err)
|
||||
}
|
||||
|
||||
const data = "hello, world\n";
|
||||
io.WriteString(f, data);
|
||||
const data = "hello, world\n"
|
||||
io.WriteString(f, data)
|
||||
|
||||
type test struct {
|
||||
in int64;
|
||||
whence int;
|
||||
out int64;
|
||||
in int64
|
||||
whence int
|
||||
out int64
|
||||
}
|
||||
var tests = []test{
|
||||
test{0, 1, int64(len(data))},
|
||||
@ -565,25 +565,25 @@ func TestSeek(t *testing.T) {
|
||||
test{-1, 2, int64(len(data)) - 1},
|
||||
test{1 << 33, 0, 1 << 33},
|
||||
test{1 << 33, 2, 1<<33 + int64(len(data))},
|
||||
};
|
||||
}
|
||||
for i, tt := range tests {
|
||||
off, err := f.Seek(tt.in, tt.whence);
|
||||
off, err := f.Seek(tt.in, tt.whence)
|
||||
if off != tt.out || err != nil {
|
||||
if e, ok := err.(*PathError); ok && e.Error == EINVAL && tt.out > 1<<32 {
|
||||
// Reiserfs rejects the big seeks.
|
||||
// http://code.google.com/p/go/issues/detail?id=91
|
||||
break
|
||||
}
|
||||
t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out);
|
||||
t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
|
||||
}
|
||||
}
|
||||
f.Close();
|
||||
f.Close()
|
||||
}
|
||||
|
||||
type openErrorTest struct {
|
||||
path string;
|
||||
mode int;
|
||||
error string;
|
||||
path string
|
||||
mode int
|
||||
error string
|
||||
}
|
||||
|
||||
var openErrorTests = []openErrorTest{
|
||||
@ -606,11 +606,11 @@ var openErrorTests = []openErrorTest{
|
||||
|
||||
func TestOpenError(t *testing.T) {
|
||||
for _, tt := range openErrorTests {
|
||||
f, err := Open(tt.path, tt.mode, 0);
|
||||
f, err := Open(tt.path, tt.mode, 0)
|
||||
if err == nil {
|
||||
t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode);
|
||||
f.Close();
|
||||
continue;
|
||||
t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
|
||||
f.Close()
|
||||
continue
|
||||
}
|
||||
if s := err.String(); s != tt.error {
|
||||
t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, s, tt.error)
|
||||
@ -620,20 +620,20 @@ func TestOpenError(t *testing.T) {
|
||||
|
||||
func run(t *testing.T, cmd []string) string {
|
||||
// Run /bin/hostname and collect output.
|
||||
r, w, err := Pipe();
|
||||
r, w, err := Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pid, err := ForkExec("/bin/hostname", []string{"hostname"}, nil, "/", []*File{nil, w, Stderr});
|
||||
pid, err := ForkExec("/bin/hostname", []string{"hostname"}, nil, "/", []*File{nil, w, Stderr})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w.Close();
|
||||
w.Close()
|
||||
|
||||
var b bytes.Buffer;
|
||||
io.Copy(&b, r);
|
||||
Wait(pid, 0);
|
||||
output := b.String();
|
||||
var b bytes.Buffer
|
||||
io.Copy(&b, r)
|
||||
Wait(pid, 0)
|
||||
output := b.String()
|
||||
if n := len(output); n > 0 && output[n-1] == '\n' {
|
||||
output = output[0 : n-1]
|
||||
}
|
||||
@ -641,32 +641,32 @@ func run(t *testing.T, cmd []string) string {
|
||||
t.Fatalf("%v produced no output", cmd)
|
||||
}
|
||||
|
||||
return output;
|
||||
return output
|
||||
}
|
||||
|
||||
|
||||
func TestHostname(t *testing.T) {
|
||||
// Check internal Hostname() against the output of /bin/hostname.
|
||||
hostname, err := Hostname();
|
||||
hostname, err := Hostname()
|
||||
if err != nil {
|
||||
t.Fatalf("%v", err)
|
||||
}
|
||||
want := run(t, []string{"/bin/hostname"});
|
||||
want := run(t, []string{"/bin/hostname"})
|
||||
if hostname != want {
|
||||
t.Errorf("Hostname() = %q, want %q", hostname, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadAt(t *testing.T) {
|
||||
f, err := Open("_obj/readtest", O_CREAT|O_RDWR|O_TRUNC, 0666);
|
||||
f, err := Open("_obj/readtest", O_CREAT|O_RDWR|O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open _obj/readtest: %s", err)
|
||||
}
|
||||
const data = "hello, world\n";
|
||||
io.WriteString(f, data);
|
||||
const data = "hello, world\n"
|
||||
io.WriteString(f, data)
|
||||
|
||||
b := make([]byte, 5);
|
||||
n, err := f.ReadAt(b, 7);
|
||||
b := make([]byte, 5)
|
||||
n, err := f.ReadAt(b, 7)
|
||||
if err != nil || n != len(b) {
|
||||
t.Fatalf("ReadAt 7: %d, %r", n, err)
|
||||
}
|
||||
@ -676,19 +676,19 @@ func TestReadAt(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWriteAt(t *testing.T) {
|
||||
f, err := Open("_obj/writetest", O_CREAT|O_RDWR|O_TRUNC, 0666);
|
||||
f, err := Open("_obj/writetest", O_CREAT|O_RDWR|O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open _obj/writetest: %s", err)
|
||||
}
|
||||
const data = "hello, world\n";
|
||||
io.WriteString(f, data);
|
||||
const data = "hello, world\n"
|
||||
io.WriteString(f, data)
|
||||
|
||||
n, err := f.WriteAt(strings.Bytes("WORLD"), 7);
|
||||
n, err := f.WriteAt(strings.Bytes("WORLD"), 7)
|
||||
if err != nil || n != 5 {
|
||||
t.Fatalf("WriteAt 7: %d, %v", n, err)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile("_obj/writetest");
|
||||
b, err := ioutil.ReadFile("_obj/writetest")
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile _obj/writetest: %v", err)
|
||||
}
|
||||
|
@ -14,45 +14,45 @@ package os
|
||||
// and returns nil.
|
||||
func MkdirAll(path string, perm int) Error {
|
||||
// If path exists, stop with success or error.
|
||||
dir, err := Lstat(path);
|
||||
dir, err := Lstat(path)
|
||||
if err == nil {
|
||||
if dir.IsDirectory() {
|
||||
return nil
|
||||
}
|
||||
return &PathError{"mkdir", path, ENOTDIR};
|
||||
return &PathError{"mkdir", path, ENOTDIR}
|
||||
}
|
||||
|
||||
// Doesn't already exist; make sure parent does.
|
||||
i := len(path);
|
||||
for i > 0 && path[i-1] == '/' { // Skip trailing slashes.
|
||||
i := len(path)
|
||||
for i > 0 && path[i-1] == '/' { // Skip trailing slashes.
|
||||
i--
|
||||
}
|
||||
|
||||
j := i;
|
||||
for j > 0 && path[j-1] != '/' { // Scan backward over element.
|
||||
j := i
|
||||
for j > 0 && path[j-1] != '/' { // Scan backward over element.
|
||||
j--
|
||||
}
|
||||
|
||||
if j > 0 {
|
||||
// Create parent
|
||||
err = MkdirAll(path[0:j-1], perm);
|
||||
err = MkdirAll(path[0:j-1], perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Now parent exists, try to create.
|
||||
err = Mkdir(path, perm);
|
||||
err = Mkdir(path, perm)
|
||||
if err != nil {
|
||||
// Handle arguments like "foo/." by
|
||||
// double-checking that directory doesn't exist.
|
||||
dir, err1 := Lstat(path);
|
||||
dir, err1 := Lstat(path)
|
||||
if err1 == nil && dir.IsDirectory() {
|
||||
return nil
|
||||
}
|
||||
return err;
|
||||
return err
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveAll removes path and any children it contains.
|
||||
@ -61,18 +61,18 @@ func MkdirAll(path string, perm int) Error {
|
||||
// returns nil (no error).
|
||||
func RemoveAll(path string) Error {
|
||||
// Simple case: if Remove works, we're done.
|
||||
err := Remove(path);
|
||||
err := Remove(path)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise, is this a directory we need to recurse into?
|
||||
dir, serr := Lstat(path);
|
||||
dir, serr := Lstat(path)
|
||||
if serr != nil {
|
||||
if serr, ok := serr.(*PathError); ok && serr.Error == ENOENT {
|
||||
return nil
|
||||
}
|
||||
return serr;
|
||||
return serr
|
||||
}
|
||||
if !dir.IsDirectory() {
|
||||
// Not a directory; return the error from Remove.
|
||||
@ -80,18 +80,18 @@ func RemoveAll(path string) Error {
|
||||
}
|
||||
|
||||
// Directory.
|
||||
fd, err := Open(path, O_RDONLY, 0);
|
||||
fd, err := Open(path, O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close();
|
||||
defer fd.Close()
|
||||
|
||||
// Remove contents & return first error.
|
||||
err = nil;
|
||||
err = nil
|
||||
for {
|
||||
names, err1 := fd.Readdirnames(100);
|
||||
names, err1 := fd.Readdirnames(100)
|
||||
for _, name := range names {
|
||||
err1 := RemoveAll(path + "/" + name);
|
||||
err1 := RemoveAll(path + "/" + name)
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
@ -106,9 +106,9 @@ func RemoveAll(path string) Error {
|
||||
}
|
||||
|
||||
// Remove directory.
|
||||
err1 := Remove(path);
|
||||
err1 := Remove(path)
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
return err;
|
||||
return err
|
||||
}
|
||||
|
@ -5,38 +5,38 @@
|
||||
package os_test
|
||||
|
||||
import (
|
||||
. "os";
|
||||
"testing";
|
||||
. "os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMkdirAll(t *testing.T) {
|
||||
// Create new dir, in _obj so it will get
|
||||
// cleaned up by make if not by us.
|
||||
path := "_obj/_TestMkdirAll_/dir/./dir2";
|
||||
err := MkdirAll(path, 0777);
|
||||
path := "_obj/_TestMkdirAll_/dir/./dir2"
|
||||
err := MkdirAll(path, 0777)
|
||||
if err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", path, err)
|
||||
}
|
||||
|
||||
// Already exists, should succeed.
|
||||
err = MkdirAll(path, 0777);
|
||||
err = MkdirAll(path, 0777)
|
||||
if err != nil {
|
||||
t.Fatalf("MkdirAll %q (second time): %s", path, err)
|
||||
}
|
||||
|
||||
// Make file.
|
||||
fpath := path + "/file";
|
||||
_, err = Open(fpath, O_WRONLY|O_CREAT, 0666);
|
||||
fpath := path + "/file"
|
||||
_, err = Open(fpath, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err)
|
||||
}
|
||||
|
||||
// Can't make directory named after file.
|
||||
err = MkdirAll(fpath, 0777);
|
||||
err = MkdirAll(fpath, 0777)
|
||||
if err == nil {
|
||||
t.Fatalf("MkdirAll %q: no error")
|
||||
}
|
||||
perr, ok := err.(*PathError);
|
||||
perr, ok := err.(*PathError)
|
||||
if !ok {
|
||||
t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
|
||||
}
|
||||
@ -45,12 +45,12 @@ func TestMkdirAll(t *testing.T) {
|
||||
}
|
||||
|
||||
// Can't make subdirectory of file.
|
||||
ffpath := fpath + "/subdir";
|
||||
err = MkdirAll(ffpath, 0777);
|
||||
ffpath := fpath + "/subdir"
|
||||
err = MkdirAll(ffpath, 0777)
|
||||
if err == nil {
|
||||
t.Fatalf("MkdirAll %q: no error")
|
||||
}
|
||||
perr, ok = err.(*PathError);
|
||||
perr, ok = err.(*PathError)
|
||||
if !ok {
|
||||
t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
|
||||
}
|
||||
@ -58,24 +58,24 @@ func TestMkdirAll(t *testing.T) {
|
||||
t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, perr.Path, fpath)
|
||||
}
|
||||
|
||||
RemoveAll("_obj/_TestMkdirAll_");
|
||||
RemoveAll("_obj/_TestMkdirAll_")
|
||||
}
|
||||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
// Work directory.
|
||||
path := "_obj/_TestRemoveAll_";
|
||||
fpath := path + "/file";
|
||||
dpath := path + "/dir";
|
||||
path := "_obj/_TestRemoveAll_"
|
||||
fpath := path + "/file"
|
||||
dpath := path + "/dir"
|
||||
|
||||
// Make directory with 1 file and remove.
|
||||
if err := MkdirAll(path, 0777); err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", path, err)
|
||||
}
|
||||
fd, err := Open(fpath, O_WRONLY|O_CREAT, 0666);
|
||||
fd, err := Open(fpath, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err)
|
||||
}
|
||||
fd.Close();
|
||||
fd.Close()
|
||||
if err = RemoveAll(path); err != nil {
|
||||
t.Fatalf("RemoveAll %q (first): %s", path, err)
|
||||
}
|
||||
@ -87,16 +87,16 @@ func TestRemoveAll(t *testing.T) {
|
||||
if err = MkdirAll(dpath, 0777); err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", dpath, err)
|
||||
}
|
||||
fd, err = Open(fpath, O_WRONLY|O_CREAT, 0666);
|
||||
fd, err = Open(fpath, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err)
|
||||
}
|
||||
fd.Close();
|
||||
fd, err = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666);
|
||||
fd.Close()
|
||||
fd, err = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err)
|
||||
}
|
||||
fd.Close();
|
||||
fd.Close()
|
||||
if err = RemoveAll(path); err != nil {
|
||||
t.Fatalf("RemoveAll %q (second): %s", path, err)
|
||||
}
|
||||
@ -104,30 +104,30 @@ func TestRemoveAll(t *testing.T) {
|
||||
t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
|
||||
}
|
||||
|
||||
if Getuid() != 0 { // Test fails as root
|
||||
if Getuid() != 0 { // Test fails as root
|
||||
// Make directory with file and subdirectory and trigger error.
|
||||
if err = MkdirAll(dpath, 0777); err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", dpath, err)
|
||||
}
|
||||
|
||||
for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
|
||||
fd, err = Open(s, O_WRONLY|O_CREAT, 0666);
|
||||
fd, err = Open(s, O_WRONLY|O_CREAT, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", s, err)
|
||||
}
|
||||
fd.Close();
|
||||
fd.Close()
|
||||
}
|
||||
if err = Chmod(dpath, 0); err != nil {
|
||||
t.Fatalf("Chmod %q 0: %s", dpath, err)
|
||||
}
|
||||
if err = RemoveAll(path); err == nil {
|
||||
_, err := Lstat(path);
|
||||
_, err := Lstat(path)
|
||||
if err == nil {
|
||||
t.Errorf("Can lstat %q after supposed RemoveAll", path)
|
||||
}
|
||||
t.Fatalf("RemoveAll %q succeeded with chmod 0 subdirectory", path, err);
|
||||
t.Fatalf("RemoveAll %q succeeded with chmod 0 subdirectory", path, err)
|
||||
}
|
||||
perr, ok := err.(*PathError);
|
||||
perr, ok := err.(*PathError)
|
||||
if !ok {
|
||||
t.Fatalf("RemoveAll %q returned %T not *PathError", path, err)
|
||||
}
|
||||
|
@ -8,28 +8,28 @@ package os
|
||||
|
||||
import "syscall"
|
||||
|
||||
var Args []string // provided by runtime
|
||||
var Envs []string // provided by runtime
|
||||
var Args []string // provided by runtime
|
||||
var Envs []string // provided by runtime
|
||||
|
||||
|
||||
// Getuid returns the numeric user id of the caller.
|
||||
func Getuid() int { return syscall.Getuid() }
|
||||
func Getuid() int { return syscall.Getuid() }
|
||||
|
||||
// Geteuid returns the numeric effective user id of the caller.
|
||||
func Geteuid() int { return syscall.Geteuid() }
|
||||
func Geteuid() int { return syscall.Geteuid() }
|
||||
|
||||
// Getgid returns the numeric group id of the caller.
|
||||
func Getgid() int { return syscall.Getgid() }
|
||||
func Getgid() int { return syscall.Getgid() }
|
||||
|
||||
// Getegid returns the numeric effective group id of the caller.
|
||||
func Getegid() int { return syscall.Getegid() }
|
||||
func Getegid() int { return syscall.Getegid() }
|
||||
|
||||
// Getgroups returns a list of the numeric ids of groups that the caller belongs to.
|
||||
func Getgroups() ([]int, Error) {
|
||||
gids, errno := syscall.Getgroups();
|
||||
return gids, NewSyscallError("getgroups", errno);
|
||||
gids, errno := syscall.Getgroups()
|
||||
return gids, NewSyscallError("getgroups", errno)
|
||||
}
|
||||
|
||||
// Exit causes the current program to exit with the given status code.
|
||||
// Conventionally, code zero indicates success, non-zero an error.
|
||||
func Exit(code int) { syscall.Exit(code) }
|
||||
func Exit(code int) { syscall.Exit(code) }
|
||||
|
@ -11,28 +11,28 @@ func isSymlink(stat *syscall.Stat_t) bool {
|
||||
}
|
||||
|
||||
func dirFromStat(name string, dir *Dir, lstat, stat *syscall.Stat_t) *Dir {
|
||||
dir.Dev = uint64(stat.Dev);
|
||||
dir.Ino = stat.Ino;
|
||||
dir.Nlink = uint64(stat.Nlink);
|
||||
dir.Mode = uint32(stat.Mode);
|
||||
dir.Uid = stat.Uid;
|
||||
dir.Gid = stat.Gid;
|
||||
dir.Rdev = uint64(stat.Rdev);
|
||||
dir.Size = uint64(stat.Size);
|
||||
dir.Blksize = uint64(stat.Blksize);
|
||||
dir.Blocks = uint64(stat.Blocks);
|
||||
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atimespec));
|
||||
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtimespec));
|
||||
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctimespec));
|
||||
dir.Dev = uint64(stat.Dev)
|
||||
dir.Ino = stat.Ino
|
||||
dir.Nlink = uint64(stat.Nlink)
|
||||
dir.Mode = uint32(stat.Mode)
|
||||
dir.Uid = stat.Uid
|
||||
dir.Gid = stat.Gid
|
||||
dir.Rdev = uint64(stat.Rdev)
|
||||
dir.Size = uint64(stat.Size)
|
||||
dir.Blksize = uint64(stat.Blksize)
|
||||
dir.Blocks = uint64(stat.Blocks)
|
||||
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atimespec))
|
||||
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtimespec))
|
||||
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctimespec))
|
||||
for i := len(name) - 1; i >= 0; i-- {
|
||||
if name[i] == '/' {
|
||||
name = name[i+1:];
|
||||
break;
|
||||
name = name[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
dir.Name = name;
|
||||
dir.Name = name
|
||||
if isSymlink(lstat) && !isSymlink(stat) {
|
||||
dir.FollowedSymlink = true
|
||||
}
|
||||
return dir;
|
||||
return dir
|
||||
}
|
||||
|
@ -11,28 +11,28 @@ func isSymlink(stat *syscall.Stat_t) bool {
|
||||
}
|
||||
|
||||
func dirFromStat(name string, dir *Dir, lstat, stat *syscall.Stat_t) *Dir {
|
||||
dir.Dev = uint64(stat.Dev);
|
||||
dir.Ino = uint64(stat.Ino);
|
||||
dir.Nlink = uint64(stat.Nlink);
|
||||
dir.Mode = uint32(stat.Mode);
|
||||
dir.Uid = stat.Uid;
|
||||
dir.Gid = stat.Gid;
|
||||
dir.Rdev = uint64(stat.Rdev);
|
||||
dir.Size = uint64(stat.Size);
|
||||
dir.Blksize = uint64(stat.Blksize);
|
||||
dir.Blocks = uint64(stat.Blocks);
|
||||
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atimespec));
|
||||
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtimespec));
|
||||
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctimespec));
|
||||
dir.Dev = uint64(stat.Dev)
|
||||
dir.Ino = uint64(stat.Ino)
|
||||
dir.Nlink = uint64(stat.Nlink)
|
||||
dir.Mode = uint32(stat.Mode)
|
||||
dir.Uid = stat.Uid
|
||||
dir.Gid = stat.Gid
|
||||
dir.Rdev = uint64(stat.Rdev)
|
||||
dir.Size = uint64(stat.Size)
|
||||
dir.Blksize = uint64(stat.Blksize)
|
||||
dir.Blocks = uint64(stat.Blocks)
|
||||
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atimespec))
|
||||
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtimespec))
|
||||
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctimespec))
|
||||
for i := len(name) - 1; i >= 0; i-- {
|
||||
if name[i] == '/' {
|
||||
name = name[i+1:];
|
||||
break;
|
||||
name = name[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
dir.Name = name;
|
||||
dir.Name = name
|
||||
if isSymlink(lstat) && !isSymlink(stat) {
|
||||
dir.FollowedSymlink = true
|
||||
}
|
||||
return dir;
|
||||
return dir
|
||||
}
|
||||
|
@ -11,28 +11,28 @@ func isSymlink(stat *syscall.Stat_t) bool {
|
||||
}
|
||||
|
||||
func dirFromStat(name string, dir *Dir, lstat, stat *syscall.Stat_t) *Dir {
|
||||
dir.Dev = stat.Dev;
|
||||
dir.Ino = uint64(stat.Ino);
|
||||
dir.Nlink = uint64(stat.Nlink);
|
||||
dir.Mode = stat.Mode;
|
||||
dir.Uid = stat.Uid;
|
||||
dir.Gid = stat.Gid;
|
||||
dir.Rdev = stat.Rdev;
|
||||
dir.Size = uint64(stat.Size);
|
||||
dir.Blksize = uint64(stat.Blksize);
|
||||
dir.Blocks = uint64(stat.Blocks);
|
||||
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atim));
|
||||
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtim));
|
||||
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctim));
|
||||
dir.Dev = stat.Dev
|
||||
dir.Ino = uint64(stat.Ino)
|
||||
dir.Nlink = uint64(stat.Nlink)
|
||||
dir.Mode = stat.Mode
|
||||
dir.Uid = stat.Uid
|
||||
dir.Gid = stat.Gid
|
||||
dir.Rdev = stat.Rdev
|
||||
dir.Size = uint64(stat.Size)
|
||||
dir.Blksize = uint64(stat.Blksize)
|
||||
dir.Blocks = uint64(stat.Blocks)
|
||||
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atim))
|
||||
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtim))
|
||||
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctim))
|
||||
for i := len(name) - 1; i >= 0; i-- {
|
||||
if name[i] == '/' {
|
||||
name = name[i+1:];
|
||||
break;
|
||||
name = name[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
dir.Name = name;
|
||||
dir.Name = name
|
||||
if isSymlink(lstat) && !isSymlink(stat) {
|
||||
dir.FollowedSymlink = true
|
||||
}
|
||||
return dir;
|
||||
return dir
|
||||
}
|
||||
|
@ -11,28 +11,28 @@ func isSymlink(stat *syscall.Stat_t) bool {
|
||||
}
|
||||
|
||||
func dirFromStat(name string, dir *Dir, lstat, stat *syscall.Stat_t) *Dir {
|
||||
dir.Dev = uint64(stat.Dev);
|
||||
dir.Ino = uint64(stat.Ino);
|
||||
dir.Nlink = uint64(stat.Nlink);
|
||||
dir.Mode = stat.Mode;
|
||||
dir.Uid = stat.Uid;
|
||||
dir.Gid = stat.Gid;
|
||||
dir.Rdev = uint64(stat.Rdev);
|
||||
dir.Size = uint64(stat.Size);
|
||||
dir.Blksize = uint64(stat.Blksize);
|
||||
dir.Blocks = uint64(stat.Blocks);
|
||||
dir.Atime_ns = uint64(stat.Atime) * 1e9;
|
||||
dir.Mtime_ns = uint64(stat.Mtime) * 1e9;
|
||||
dir.Ctime_ns = uint64(stat.Ctime) * 1e9;
|
||||
dir.Dev = uint64(stat.Dev)
|
||||
dir.Ino = uint64(stat.Ino)
|
||||
dir.Nlink = uint64(stat.Nlink)
|
||||
dir.Mode = stat.Mode
|
||||
dir.Uid = stat.Uid
|
||||
dir.Gid = stat.Gid
|
||||
dir.Rdev = uint64(stat.Rdev)
|
||||
dir.Size = uint64(stat.Size)
|
||||
dir.Blksize = uint64(stat.Blksize)
|
||||
dir.Blocks = uint64(stat.Blocks)
|
||||
dir.Atime_ns = uint64(stat.Atime) * 1e9
|
||||
dir.Mtime_ns = uint64(stat.Mtime) * 1e9
|
||||
dir.Ctime_ns = uint64(stat.Ctime) * 1e9
|
||||
for i := len(name) - 1; i >= 0; i-- {
|
||||
if name[i] == '/' {
|
||||
name = name[i+1:];
|
||||
break;
|
||||
name = name[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
dir.Name = name;
|
||||
dir.Name = name
|
||||
if isSymlink(lstat) && !isSymlink(stat) {
|
||||
dir.FollowedSymlink = true
|
||||
}
|
||||
return dir;
|
||||
return dir
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ package os
|
||||
import "syscall"
|
||||
|
||||
func Hostname() (name string, err Error) {
|
||||
var errno int;
|
||||
name, errno = syscall.Sysctl("kern.hostname");
|
||||
var errno int
|
||||
name, errno = syscall.Sysctl("kern.hostname")
|
||||
if errno != 0 {
|
||||
return "", NewSyscallError("sysctl kern.hostname", errno)
|
||||
}
|
||||
return name, nil;
|
||||
return name, nil
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ package os
|
||||
import "syscall"
|
||||
|
||||
func Hostname() (name string, err Error) {
|
||||
var errno int;
|
||||
name, errno = syscall.Sysctl("kern.hostname");
|
||||
var errno int
|
||||
name, errno = syscall.Sysctl("kern.hostname")
|
||||
if errno != 0 {
|
||||
return "", NewSyscallError("sysctl kern.hostname", errno)
|
||||
}
|
||||
return name, nil;
|
||||
return name, nil
|
||||
}
|
||||
|
@ -9,14 +9,14 @@ package os
|
||||
|
||||
// Hostname returns the host name reported by the kernel.
|
||||
func Hostname() (name string, err Error) {
|
||||
f, err := Open("/proc/sys/kernel/hostname", O_RDONLY, 0);
|
||||
f, err := Open("/proc/sys/kernel/hostname", O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close();
|
||||
defer f.Close()
|
||||
|
||||
var buf [512]byte; // Enough for a DNS name.
|
||||
n, err := f.Read(&buf);
|
||||
var buf [512]byte // Enough for a DNS name.
|
||||
n, err := f.Read(&buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -24,5 +24,5 @@ func Hostname() (name string, err Error) {
|
||||
if n > 0 && buf[n-1] == '\n' {
|
||||
n--
|
||||
}
|
||||
return string(buf[0:n]), nil;
|
||||
return string(buf[0:n]), nil
|
||||
}
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
package os
|
||||
|
||||
func Hostname() (name string, err Error) { return "nacl", nil }
|
||||
func Hostname() (name string, err Error) { return "nacl", nil }
|
||||
|
@ -12,9 +12,9 @@ import "syscall"
|
||||
// time is thus 1e9*sec+nsec, in nanoseconds. The zero of
|
||||
// time is the Unix epoch.
|
||||
func Time() (sec int64, nsec int64, err Error) {
|
||||
var tv syscall.Timeval;
|
||||
var tv syscall.Timeval
|
||||
if errno := syscall.Gettimeofday(&tv); errno != 0 {
|
||||
return 0, 0, NewSyscallError("gettimeofday", errno)
|
||||
}
|
||||
return int64(tv.Sec), int64(tv.Usec) * 1000, err;
|
||||
return int64(tv.Sec), int64(tv.Usec) * 1000, err
|
||||
}
|
||||
|
@ -10,47 +10,47 @@ import "syscall"
|
||||
// OS-specific routines in this directory convert the OS-local versions to these.
|
||||
|
||||
// Getpagesize returns the underlying system's memory page size.
|
||||
func Getpagesize() int { return syscall.Getpagesize() }
|
||||
func Getpagesize() int { return syscall.Getpagesize() }
|
||||
|
||||
// A Dir describes a file and is returned by Stat, Fstat, and Lstat
|
||||
type Dir struct {
|
||||
Dev uint64; // device number of file system holding file.
|
||||
Ino uint64; // inode number.
|
||||
Nlink uint64; // number of hard links.
|
||||
Mode uint32; // permission and mode bits.
|
||||
Uid uint32; // user id of owner.
|
||||
Gid uint32; // group id of owner.
|
||||
Rdev uint64; // device type for special file.
|
||||
Size uint64; // length in bytes.
|
||||
Blksize uint64; // size of blocks, in bytes.
|
||||
Blocks uint64; // number of blocks allocated for file.
|
||||
Atime_ns uint64; // access time; nanoseconds since epoch.
|
||||
Mtime_ns uint64; // modified time; nanoseconds since epoch.
|
||||
Ctime_ns uint64; // status change time; nanoseconds since epoch.
|
||||
Name string; // name of file as presented to Open.
|
||||
FollowedSymlink bool; // followed a symlink to get this information
|
||||
Dev uint64 // device number of file system holding file.
|
||||
Ino uint64 // inode number.
|
||||
Nlink uint64 // number of hard links.
|
||||
Mode uint32 // permission and mode bits.
|
||||
Uid uint32 // user id of owner.
|
||||
Gid uint32 // group id of owner.
|
||||
Rdev uint64 // device type for special file.
|
||||
Size uint64 // length in bytes.
|
||||
Blksize uint64 // size of blocks, in bytes.
|
||||
Blocks uint64 // number of blocks allocated for file.
|
||||
Atime_ns uint64 // access time; nanoseconds since epoch.
|
||||
Mtime_ns uint64 // modified time; nanoseconds since epoch.
|
||||
Ctime_ns uint64 // status change time; nanoseconds since epoch.
|
||||
Name string // name of file as presented to Open.
|
||||
FollowedSymlink bool // followed a symlink to get this information
|
||||
}
|
||||
|
||||
// IsFifo reports whether the Dir describes a FIFO file.
|
||||
func (dir *Dir) IsFifo() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFIFO }
|
||||
func (dir *Dir) IsFifo() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFIFO }
|
||||
|
||||
// IsChar reports whether the Dir describes a character special file.
|
||||
func (dir *Dir) IsChar() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFCHR }
|
||||
func (dir *Dir) IsChar() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFCHR }
|
||||
|
||||
// IsDirectory reports whether the Dir describes a directory.
|
||||
func (dir *Dir) IsDirectory() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFDIR }
|
||||
func (dir *Dir) IsDirectory() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFDIR }
|
||||
|
||||
// IsBlock reports whether the Dir describes a block special file.
|
||||
func (dir *Dir) IsBlock() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFBLK }
|
||||
func (dir *Dir) IsBlock() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFBLK }
|
||||
|
||||
// IsRegular reports whether the Dir describes a regular file.
|
||||
func (dir *Dir) IsRegular() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFREG }
|
||||
func (dir *Dir) IsRegular() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFREG }
|
||||
|
||||
// IsSymlink reports whether the Dir describes a symbolic link.
|
||||
func (dir *Dir) IsSymlink() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFLNK }
|
||||
func (dir *Dir) IsSymlink() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFLNK }
|
||||
|
||||
// IsSocket reports whether the Dir describes a socket.
|
||||
func (dir *Dir) IsSocket() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFSOCK }
|
||||
func (dir *Dir) IsSocket() bool { return (dir.Mode & syscall.S_IFMT) == syscall.S_IFSOCK }
|
||||
|
||||
// Permission returns the file permission bits.
|
||||
func (dir *Dir) Permission() int { return int(dir.Mode & 0777) }
|
||||
func (dir *Dir) Permission() int { return int(dir.Mode & 0777) }
|
||||
|
@ -8,11 +8,11 @@ import "os"
|
||||
|
||||
// An Op is a single operation to execute to apply a patch.
|
||||
type Op struct {
|
||||
Verb Verb; // action
|
||||
Src string; // source file
|
||||
Dst string; // destination file
|
||||
Mode int; // mode for destination (if non-zero)
|
||||
Data []byte; // data for destination (if non-nil)
|
||||
Verb Verb // action
|
||||
Src string // source file
|
||||
Dst string // destination file
|
||||
Mode int // mode for destination (if non-zero)
|
||||
Data []byte // data for destination (if non-nil)
|
||||
}
|
||||
|
||||
// Apply applies the patch set to the files named in the patch set,
|
||||
@ -24,31 +24,31 @@ type Op struct {
|
||||
// Typically this function will be io.ReadFile.
|
||||
//
|
||||
func (set *Set) Apply(readFile func(string) ([]byte, os.Error)) ([]Op, os.Error) {
|
||||
op := make([]Op, len(set.File));
|
||||
op := make([]Op, len(set.File))
|
||||
|
||||
for i, f := range set.File {
|
||||
o := &op[i];
|
||||
o.Verb = f.Verb;
|
||||
o.Src = f.Src;
|
||||
o.Dst = f.Dst;
|
||||
o.Mode = f.NewMode;
|
||||
o := &op[i]
|
||||
o.Verb = f.Verb
|
||||
o.Src = f.Src
|
||||
o.Dst = f.Dst
|
||||
o.Mode = f.NewMode
|
||||
if f.Diff != NoDiff || o.Verb != Edit {
|
||||
// Clients assume o.Data == nil means no data diff.
|
||||
// Start with a non-nil data.
|
||||
var old []byte = make([]byte, 0); // not nil
|
||||
var err os.Error;
|
||||
var old []byte = make([]byte, 0) // not nil
|
||||
var err os.Error
|
||||
if f.Src != "" {
|
||||
old, err = readFile(f.Src);
|
||||
old, err = readFile(f.Src)
|
||||
if err != nil {
|
||||
return nil, &os.PathError{string(f.Verb), f.Src, err}
|
||||
}
|
||||
}
|
||||
o.Data, err = f.Diff.Apply(old);
|
||||
o.Data, err = f.Diff.Apply(old)
|
||||
if err != nil {
|
||||
return nil, &os.PathError{string(f.Verb), f.Src, err}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return op, nil;
|
||||
return op, nil
|
||||
}
|
||||
|
@ -5,13 +5,13 @@
|
||||
package patch
|
||||
|
||||
import (
|
||||
"bytes";
|
||||
"compress/zlib";
|
||||
"crypto/sha1";
|
||||
"encoding/git85";
|
||||
"fmt";
|
||||
"io";
|
||||
"os";
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"crypto/sha1"
|
||||
"encoding/git85"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func gitSHA1(data []byte) []byte {
|
||||
@ -19,18 +19,18 @@ func gitSHA1(data []byte) []byte {
|
||||
// special case: 0 length is all zeros sum
|
||||
return make([]byte, 20)
|
||||
}
|
||||
h := sha1.New();
|
||||
fmt.Fprintf(h, "blob %d\x00", len(data));
|
||||
h.Write(data);
|
||||
return h.Sum();
|
||||
h := sha1.New()
|
||||
fmt.Fprintf(h, "blob %d\x00", len(data))
|
||||
h.Write(data)
|
||||
return h.Sum()
|
||||
}
|
||||
|
||||
// BUG(rsc): The Git binary delta format is not implemented, only Git binary literals.
|
||||
|
||||
// GitBinaryLiteral represents a Git binary literal diff.
|
||||
type GitBinaryLiteral struct {
|
||||
OldSHA1 []byte; // if non-empty, the SHA1 hash of the original
|
||||
New []byte; // the new contents
|
||||
OldSHA1 []byte // if non-empty, the SHA1 hash of the original
|
||||
New []byte // the new contents
|
||||
}
|
||||
|
||||
// Apply implements the Diff interface's Apply method.
|
||||
@ -38,7 +38,7 @@ func (d *GitBinaryLiteral) Apply(old []byte) ([]byte, os.Error) {
|
||||
if sum := gitSHA1(old); !bytes.HasPrefix(sum, d.OldSHA1) {
|
||||
return nil, ErrPatchFailure
|
||||
}
|
||||
return d.New, nil;
|
||||
return d.New, nil
|
||||
}
|
||||
|
||||
func unhex(c byte) uint8 {
|
||||
@ -50,60 +50,60 @@ func unhex(c byte) uint8 {
|
||||
case 'A' <= c && c <= 'F':
|
||||
return c - 'A' + 10
|
||||
}
|
||||
return 255;
|
||||
return 255
|
||||
}
|
||||
|
||||
func getHex(s []byte) (data []byte, rest []byte) {
|
||||
n := 0;
|
||||
n := 0
|
||||
for n < len(s) && unhex(s[n]) != 255 {
|
||||
n++
|
||||
}
|
||||
n &^= 1; // Only take an even number of hex digits.
|
||||
data = make([]byte, n/2);
|
||||
n &^= 1 // Only take an even number of hex digits.
|
||||
data = make([]byte, n/2)
|
||||
for i := range data {
|
||||
data[i] = unhex(s[2*i])<<4 | unhex(s[2*i+1])
|
||||
}
|
||||
rest = s[n:];
|
||||
return;
|
||||
rest = s[n:]
|
||||
return
|
||||
}
|
||||
|
||||
// ParseGitBinary parses raw as a Git binary patch.
|
||||
func ParseGitBinary(raw []byte) (Diff, os.Error) {
|
||||
var oldSHA1, newSHA1 []byte;
|
||||
var sawBinary bool;
|
||||
var oldSHA1, newSHA1 []byte
|
||||
var sawBinary bool
|
||||
|
||||
for {
|
||||
var first []byte;
|
||||
first, raw, _ = getLine(raw, 1);
|
||||
first = bytes.TrimSpace(first);
|
||||
var first []byte
|
||||
first, raw, _ = getLine(raw, 1)
|
||||
first = bytes.TrimSpace(first)
|
||||
if s, ok := skip(first, "index "); ok {
|
||||
oldSHA1, s = getHex(s);
|
||||
oldSHA1, s = getHex(s)
|
||||
if s, ok = skip(s, ".."); !ok {
|
||||
continue
|
||||
}
|
||||
newSHA1, s = getHex(s);
|
||||
continue;
|
||||
newSHA1, s = getHex(s)
|
||||
continue
|
||||
}
|
||||
if _, ok := skip(first, "GIT binary patch"); ok {
|
||||
sawBinary = true;
|
||||
continue;
|
||||
sawBinary = true
|
||||
continue
|
||||
}
|
||||
if n, _, ok := atoi(first, "literal ", 10); ok && sawBinary {
|
||||
data := make([]byte, n);
|
||||
d := git85.NewDecoder(bytes.NewBuffer(raw));
|
||||
z, err := zlib.NewInflater(d);
|
||||
data := make([]byte, n)
|
||||
d := git85.NewDecoder(bytes.NewBuffer(raw))
|
||||
z, err := zlib.NewInflater(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer z.Close();
|
||||
defer z.Close()
|
||||
if _, err = io.ReadFull(z, data); err != nil {
|
||||
if err == os.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil, err;
|
||||
return nil, err
|
||||
}
|
||||
var buf [1]byte;
|
||||
m, err := z.Read(&buf);
|
||||
var buf [1]byte
|
||||
m, err := z.Read(&buf)
|
||||
if m != 0 || err != os.EOF {
|
||||
return nil, os.NewError("Git binary literal longer than expected")
|
||||
}
|
||||
@ -111,11 +111,11 @@ func ParseGitBinary(raw []byte) (Diff, os.Error) {
|
||||
if sum := gitSHA1(data); !bytes.HasPrefix(sum, newSHA1) {
|
||||
return nil, os.NewError("Git binary literal SHA1 mismatch")
|
||||
}
|
||||
return &GitBinaryLiteral{oldSHA1, data}, nil;
|
||||
return &GitBinaryLiteral{oldSHA1, data}, nil
|
||||
}
|
||||
if !sawBinary {
|
||||
return nil, os.NewError("unexpected Git patch header: " + string(first))
|
||||
}
|
||||
}
|
||||
panic("unreachable");
|
||||
panic("unreachable")
|
||||
}
|
||||
|
@ -8,37 +8,37 @@
|
||||
package patch
|
||||
|
||||
import (
|
||||
"bytes";
|
||||
"os";
|
||||
"path";
|
||||
"strings";
|
||||
"bytes"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Set represents a set of patches to be applied as a single atomic unit.
|
||||
// Patch sets are often preceded by a descriptive header.
|
||||
type Set struct {
|
||||
Header string; // free-form text
|
||||
File []*File;
|
||||
Header string // free-form text
|
||||
File []*File
|
||||
}
|
||||
|
||||
// A File represents a collection of changes to be made to a single file.
|
||||
type File struct {
|
||||
Verb Verb;
|
||||
Src string; // source for Verb == Copy, Verb == Rename
|
||||
Dst string;
|
||||
OldMode, NewMode int; // 0 indicates not used
|
||||
Diff; // changes to data; == NoDiff if operation does not edit file
|
||||
Verb Verb
|
||||
Src string // source for Verb == Copy, Verb == Rename
|
||||
Dst string
|
||||
OldMode, NewMode int // 0 indicates not used
|
||||
Diff // changes to data; == NoDiff if operation does not edit file
|
||||
}
|
||||
|
||||
// A Verb is an action performed on a file.
|
||||
type Verb string
|
||||
|
||||
const (
|
||||
Add Verb = "add";
|
||||
Copy Verb = "copy";
|
||||
Delete Verb = "delete";
|
||||
Edit Verb = "edit";
|
||||
Rename Verb = "rename";
|
||||
Add Verb = "add"
|
||||
Copy Verb = "copy"
|
||||
Delete Verb = "delete"
|
||||
Edit Verb = "edit"
|
||||
Rename Verb = "rename"
|
||||
)
|
||||
|
||||
// A Diff is any object that describes changes to transform
|
||||
@ -47,7 +47,7 @@ type Diff interface {
|
||||
// Apply applies the changes listed in the diff
|
||||
// to the string s, returning the new version of the string.
|
||||
// Note that the string s need not be a text string.
|
||||
Apply(old []byte) (new []byte, err os.Error);
|
||||
Apply(old []byte) (new []byte, err os.Error)
|
||||
}
|
||||
|
||||
// NoDiff is a no-op Diff implementation: it passes the
|
||||
@ -63,7 +63,7 @@ func (noDiffType) Apply(old []byte) ([]byte, os.Error) {
|
||||
// A SyntaxError represents a syntax error encountered while parsing a patch.
|
||||
type SyntaxError string
|
||||
|
||||
func (e SyntaxError) String() string { return string(e) }
|
||||
func (e SyntaxError) String() string { return string(e) }
|
||||
|
||||
var newline = []byte{'\n'}
|
||||
|
||||
@ -82,37 +82,37 @@ func Parse(text []byte) (*Set, os.Error) {
|
||||
// diff [--git] a/file/path b/file/path.
|
||||
//
|
||||
// First look for Index: lines. If none, fall back on diff lines.
|
||||
text, files := sections(text, "Index: ");
|
||||
text, files := sections(text, "Index: ")
|
||||
if len(files) == 0 {
|
||||
text, files = sections(text, "diff ")
|
||||
}
|
||||
|
||||
set := &Set{string(text), make([]*File, len(files))};
|
||||
set := &Set{string(text), make([]*File, len(files))}
|
||||
|
||||
// Parse file header and then
|
||||
// parse files into patch chunks.
|
||||
// Each chunk begins with @@.
|
||||
for i, raw := range files {
|
||||
p := new(File);
|
||||
set.File[i] = p;
|
||||
p := new(File)
|
||||
set.File[i] = p
|
||||
|
||||
// First line of hdr is the Index: that
|
||||
// begins the section. After that is the file name.
|
||||
s, raw, _ := getLine(raw, 1);
|
||||
s, raw, _ := getLine(raw, 1)
|
||||
if hasPrefix(s, "Index: ") {
|
||||
p.Dst = string(bytes.TrimSpace(s[7:]));
|
||||
goto HaveName;
|
||||
p.Dst = string(bytes.TrimSpace(s[7:]))
|
||||
goto HaveName
|
||||
} else if hasPrefix(s, "diff ") {
|
||||
str := string(bytes.TrimSpace(s));
|
||||
i := strings.LastIndex(str, " b/");
|
||||
str := string(bytes.TrimSpace(s))
|
||||
i := strings.LastIndex(str, " b/")
|
||||
if i >= 0 {
|
||||
p.Dst = str[i+3:];
|
||||
goto HaveName;
|
||||
p.Dst = str[i+3:]
|
||||
goto HaveName
|
||||
}
|
||||
}
|
||||
return nil, SyntaxError("unexpected patch header line: " + string(s));
|
||||
return nil, SyntaxError("unexpected patch header line: " + string(s))
|
||||
HaveName:
|
||||
p.Dst = path.Clean(p.Dst);
|
||||
p.Dst = path.Clean(p.Dst)
|
||||
if strings.HasPrefix(p.Dst, "../") || strings.HasPrefix(p.Dst, "/") {
|
||||
return nil, SyntaxError("invalid path: " + p.Dst)
|
||||
}
|
||||
@ -126,55 +126,55 @@ func Parse(text []byte) (*Set, os.Error) {
|
||||
// rename to %s
|
||||
// copy from %s - file copied from other file
|
||||
// copy to %s
|
||||
p.Verb = Edit;
|
||||
p.Verb = Edit
|
||||
for len(raw) > 0 {
|
||||
oldraw := raw;
|
||||
var l []byte;
|
||||
l, raw, _ = getLine(raw, 1);
|
||||
l = bytes.TrimSpace(l);
|
||||
oldraw := raw
|
||||
var l []byte
|
||||
l, raw, _ = getLine(raw, 1)
|
||||
l = bytes.TrimSpace(l)
|
||||
if m, s, ok := atoi(l, "new file mode ", 8); ok && len(s) == 0 {
|
||||
p.NewMode = m;
|
||||
p.Verb = Add;
|
||||
continue;
|
||||
p.NewMode = m
|
||||
p.Verb = Add
|
||||
continue
|
||||
}
|
||||
if m, s, ok := atoi(l, "deleted file mode ", 8); ok && len(s) == 0 {
|
||||
p.OldMode = m;
|
||||
p.Verb = Delete;
|
||||
p.Src = p.Dst;
|
||||
p.Dst = "";
|
||||
continue;
|
||||
p.OldMode = m
|
||||
p.Verb = Delete
|
||||
p.Src = p.Dst
|
||||
p.Dst = ""
|
||||
continue
|
||||
}
|
||||
if m, s, ok := atoi(l, "old file mode ", 8); ok && len(s) == 0 {
|
||||
// usually implies p.Verb = "rename" or "copy"
|
||||
// but we'll get that from the rename or copy line.
|
||||
p.OldMode = m;
|
||||
continue;
|
||||
p.OldMode = m
|
||||
continue
|
||||
}
|
||||
if m, s, ok := atoi(l, "old mode ", 8); ok && len(s) == 0 {
|
||||
p.OldMode = m;
|
||||
continue;
|
||||
p.OldMode = m
|
||||
continue
|
||||
}
|
||||
if m, s, ok := atoi(l, "new mode ", 8); ok && len(s) == 0 {
|
||||
p.NewMode = m;
|
||||
continue;
|
||||
p.NewMode = m
|
||||
continue
|
||||
}
|
||||
if s, ok := skip(l, "rename from "); ok && len(s) > 0 {
|
||||
p.Src = string(s);
|
||||
p.Verb = Rename;
|
||||
continue;
|
||||
p.Src = string(s)
|
||||
p.Verb = Rename
|
||||
continue
|
||||
}
|
||||
if s, ok := skip(l, "rename to "); ok && len(s) > 0 {
|
||||
p.Verb = Rename;
|
||||
continue;
|
||||
p.Verb = Rename
|
||||
continue
|
||||
}
|
||||
if s, ok := skip(l, "copy from "); ok && len(s) > 0 {
|
||||
p.Src = string(s);
|
||||
p.Verb = Copy;
|
||||
continue;
|
||||
p.Src = string(s)
|
||||
p.Verb = Copy
|
||||
continue
|
||||
}
|
||||
if s, ok := skip(l, "copy to "); ok && len(s) > 0 {
|
||||
p.Verb = Copy;
|
||||
continue;
|
||||
p.Verb = Copy
|
||||
continue
|
||||
}
|
||||
if s, ok := skip(l, "Binary file "); ok && len(s) > 0 {
|
||||
// Hg prints
|
||||
@ -200,22 +200,22 @@ func Parse(text []byte) (*Set, os.Error) {
|
||||
continue
|
||||
}
|
||||
if hasPrefix(l, "@@ -") {
|
||||
diff, err := ParseTextDiff(oldraw);
|
||||
diff, err := ParseTextDiff(oldraw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.Diff = diff;
|
||||
break;
|
||||
p.Diff = diff
|
||||
break
|
||||
}
|
||||
if hasPrefix(l, "index ") || hasPrefix(l, "GIT binary patch") {
|
||||
diff, err := ParseGitBinary(oldraw);
|
||||
diff, err := ParseGitBinary(oldraw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.Diff = diff;
|
||||
break;
|
||||
p.Diff = diff
|
||||
break
|
||||
}
|
||||
return nil, SyntaxError("unexpected patch header line: " + string(l));
|
||||
return nil, SyntaxError("unexpected patch header line: " + string(l))
|
||||
}
|
||||
if p.Diff == nil {
|
||||
p.Diff = NoDiff
|
||||
@ -225,25 +225,25 @@ func Parse(text []byte) (*Set, os.Error) {
|
||||
}
|
||||
}
|
||||
|
||||
return set, nil;
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// getLine returns the first n lines of data and the remainder.
|
||||
// If data has no newline, getLine returns data, nil, false
|
||||
func getLine(data []byte, n int) (first []byte, rest []byte, ok bool) {
|
||||
rest = data;
|
||||
ok = true;
|
||||
rest = data
|
||||
ok = true
|
||||
for ; n > 0; n-- {
|
||||
nl := bytes.Index(rest, newline);
|
||||
nl := bytes.Index(rest, newline)
|
||||
if nl < 0 {
|
||||
rest = nil;
|
||||
ok = false;
|
||||
break;
|
||||
rest = nil
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
rest = rest[nl+1:];
|
||||
rest = rest[nl+1:]
|
||||
}
|
||||
first = data[0 : len(data)-len(rest)];
|
||||
return;
|
||||
first = data[0 : len(data)-len(rest)]
|
||||
return
|
||||
}
|
||||
|
||||
// sections returns a collection of file sections,
|
||||
@ -251,34 +251,34 @@ func getLine(data []byte, n int) (first []byte, rest []byte, ok bool) {
|
||||
// text before the first instance of such a line is
|
||||
// returned separately.
|
||||
func sections(text []byte, prefix string) ([]byte, [][]byte) {
|
||||
n := 0;
|
||||
n := 0
|
||||
for b := text; ; {
|
||||
if hasPrefix(b, prefix) {
|
||||
n++
|
||||
}
|
||||
nl := bytes.Index(b, newline);
|
||||
nl := bytes.Index(b, newline)
|
||||
if nl < 0 {
|
||||
break
|
||||
}
|
||||
b = b[nl+1:];
|
||||
b = b[nl+1:]
|
||||
}
|
||||
|
||||
sect := make([][]byte, n+1);
|
||||
n = 0;
|
||||
sect := make([][]byte, n+1)
|
||||
n = 0
|
||||
for b := text; ; {
|
||||
if hasPrefix(b, prefix) {
|
||||
sect[n] = text[0 : len(text)-len(b)];
|
||||
n++;
|
||||
text = b;
|
||||
sect[n] = text[0 : len(text)-len(b)]
|
||||
n++
|
||||
text = b
|
||||
}
|
||||
nl := bytes.Index(b, newline);
|
||||
nl := bytes.Index(b, newline)
|
||||
if nl < 0 {
|
||||
sect[n] = text;
|
||||
break;
|
||||
sect[n] = text
|
||||
break
|
||||
}
|
||||
b = b[nl+1:];
|
||||
b = b[nl+1:]
|
||||
}
|
||||
return sect[0], sect[1:];
|
||||
return sect[0], sect[1:]
|
||||
}
|
||||
|
||||
// if s begins with the prefix t, skip returns
|
||||
@ -287,7 +287,7 @@ func skip(s []byte, t string) (ss []byte, ok bool) {
|
||||
if len(s) < len(t) || string(s[0:len(t)]) != t {
|
||||
return nil, false
|
||||
}
|
||||
return s[len(t):], true;
|
||||
return s[len(t):], true
|
||||
}
|
||||
|
||||
// if s begins with the prefix t and then is a sequence
|
||||
@ -298,22 +298,22 @@ func atoi(s []byte, t string, base int) (n int, ss []byte, ok bool) {
|
||||
if s, ok = skip(s, t); !ok {
|
||||
return
|
||||
}
|
||||
var i int;
|
||||
var i int
|
||||
for i = 0; i < len(s) && '0' <= s[i] && s[i] <= byte('0'+base-1); i++ {
|
||||
n = n*base + int(s[i]-'0')
|
||||
}
|
||||
if i == 0 {
|
||||
return
|
||||
}
|
||||
return n, s[i:], true;
|
||||
return n, s[i:], true
|
||||
}
|
||||
|
||||
// hasPrefix returns true if s begins with t.
|
||||
func hasPrefix(s []byte, t string) bool {
|
||||
_, ok := skip(s, t);
|
||||
return ok;
|
||||
_, ok := skip(s, t)
|
||||
return ok
|
||||
}
|
||||
|
||||
// splitLines returns the result of splitting s into lines.
|
||||
// The \n on each line is preserved.
|
||||
func splitLines(s []byte) [][]byte { return bytes.SplitAfter(s, newline, 0) }
|
||||
func splitLines(s []byte) [][]byte { return bytes.SplitAfter(s, newline, 0) }
|
||||
|
@ -7,31 +7,31 @@ package patch
|
||||
// TODO(rsc): test Apply
|
||||
|
||||
import (
|
||||
"strings";
|
||||
"testing";
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type Test struct {
|
||||
in string;
|
||||
out string;
|
||||
diff string;
|
||||
in string
|
||||
out string
|
||||
diff string
|
||||
}
|
||||
|
||||
func TestFileApply(t *testing.T) {
|
||||
for i, test := range tests {
|
||||
set, err := Parse(strings.Bytes(test.diff));
|
||||
set, err := Parse(strings.Bytes(test.diff))
|
||||
if err != nil {
|
||||
t.Errorf("#%d: Parse: %s", i, err);
|
||||
continue;
|
||||
t.Errorf("#%d: Parse: %s", i, err)
|
||||
continue
|
||||
}
|
||||
if len(set.File) != 1 {
|
||||
t.Errorf("#%d: Parse returned %d patches, want 1", i, len(set.File));
|
||||
continue;
|
||||
t.Errorf("#%d: Parse returned %d patches, want 1", i, len(set.File))
|
||||
continue
|
||||
}
|
||||
new, err := set.File[0].Apply(strings.Bytes(test.in));
|
||||
new, err := set.File[0].Apply(strings.Bytes(test.in))
|
||||
if err != nil {
|
||||
t.Errorf("#%d: Apply: %s", i, err);
|
||||
continue;
|
||||
t.Errorf("#%d: Apply: %s", i, err)
|
||||
continue
|
||||
}
|
||||
if s := string(new); s != test.out {
|
||||
t.Errorf("#%d:\n--- have\n%s--- want\n%s", i, s, test.out)
|
||||
|
@ -1,8 +1,8 @@
|
||||
package patch
|
||||
|
||||
import (
|
||||
"bytes";
|
||||
"os";
|
||||
"bytes"
|
||||
"os"
|
||||
)
|
||||
|
||||
type TextDiff []TextChunk
|
||||
@ -11,25 +11,25 @@ type TextDiff []TextChunk
|
||||
// the text beginning at Line, which should be exactly Old,
|
||||
// is to be replaced with New.
|
||||
type TextChunk struct {
|
||||
Line int;
|
||||
Old []byte;
|
||||
New []byte;
|
||||
Line int
|
||||
Old []byte
|
||||
New []byte
|
||||
}
|
||||
|
||||
func ParseTextDiff(raw []byte) (TextDiff, os.Error) {
|
||||
// Copy raw so it is safe to keep references to slices.
|
||||
_, chunks := sections(raw, "@@ -");
|
||||
delta := 0;
|
||||
diff := make(TextDiff, len(chunks));
|
||||
_, chunks := sections(raw, "@@ -")
|
||||
delta := 0
|
||||
diff := make(TextDiff, len(chunks))
|
||||
for i, raw := range chunks {
|
||||
c := &diff[i];
|
||||
c := &diff[i]
|
||||
|
||||
// Parse start line: @@ -oldLine,oldCount +newLine,newCount @@ junk
|
||||
chunk := splitLines(raw);
|
||||
chunkHeader := chunk[0];
|
||||
var ok bool;
|
||||
var oldLine, oldCount, newLine, newCount int;
|
||||
s := chunkHeader;
|
||||
chunk := splitLines(raw)
|
||||
chunkHeader := chunk[0]
|
||||
var ok bool
|
||||
var oldLine, oldCount, newLine, newCount int
|
||||
s := chunkHeader
|
||||
if oldLine, s, ok = atoi(s, "@@ -", 10); !ok {
|
||||
ErrChunkHdr:
|
||||
return nil, SyntaxError("unexpected chunk header line: " + string(chunkHeader))
|
||||
@ -61,16 +61,16 @@ func ParseTextDiff(raw []byte) (TextDiff, os.Error) {
|
||||
}
|
||||
|
||||
// Count lines in text
|
||||
var dropOldNL, dropNewNL bool;
|
||||
var nold, nnew int;
|
||||
var lastch byte;
|
||||
chunk = chunk[1:];
|
||||
var dropOldNL, dropNewNL bool
|
||||
var nold, nnew int
|
||||
var lastch byte
|
||||
chunk = chunk[1:]
|
||||
for _, l := range chunk {
|
||||
if nold == oldCount && nnew == newCount && (len(l) == 0 || l[0] != '\\') {
|
||||
if len(bytes.TrimSpace(l)) != 0 {
|
||||
return nil, SyntaxError("too many chunk lines")
|
||||
}
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
if len(l) == 0 {
|
||||
return nil, SyntaxError("empty chunk line")
|
||||
@ -81,8 +81,8 @@ func ParseTextDiff(raw []byte) (TextDiff, os.Error) {
|
||||
case '-':
|
||||
nold++
|
||||
case ' ':
|
||||
nnew++;
|
||||
nold++;
|
||||
nnew++
|
||||
nold++
|
||||
case '\\':
|
||||
if _, ok := skip(l, "\\ No newline at end of file"); ok {
|
||||
switch lastch {
|
||||
@ -91,18 +91,18 @@ func ParseTextDiff(raw []byte) (TextDiff, os.Error) {
|
||||
case '+':
|
||||
dropNewNL = true
|
||||
case ' ':
|
||||
dropOldNL = true;
|
||||
dropNewNL = true;
|
||||
dropOldNL = true
|
||||
dropNewNL = true
|
||||
default:
|
||||
return nil, SyntaxError("message `\\ No newline at end of file' out of context")
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
fallthrough;
|
||||
fallthrough
|
||||
default:
|
||||
return nil, SyntaxError("unexpected chunk line: " + string(l))
|
||||
}
|
||||
lastch = l[0];
|
||||
lastch = l[0]
|
||||
}
|
||||
|
||||
// Does it match the header?
|
||||
@ -112,31 +112,31 @@ func ParseTextDiff(raw []byte) (TextDiff, os.Error) {
|
||||
if oldLine+delta != newLine {
|
||||
return nil, SyntaxError("chunk delta is out of sync with previous chunks")
|
||||
}
|
||||
delta += nnew - nold;
|
||||
c.Line = oldLine;
|
||||
delta += nnew - nold
|
||||
c.Line = oldLine
|
||||
|
||||
var old, new bytes.Buffer;
|
||||
nold = 0;
|
||||
nnew = 0;
|
||||
var old, new bytes.Buffer
|
||||
nold = 0
|
||||
nnew = 0
|
||||
for _, l := range chunk {
|
||||
if nold == oldCount && nnew == newCount {
|
||||
break
|
||||
}
|
||||
ch, l := l[0], l[1:];
|
||||
ch, l := l[0], l[1:]
|
||||
if ch == '\\' {
|
||||
continue
|
||||
}
|
||||
if ch != '+' {
|
||||
old.Write(l);
|
||||
nold++;
|
||||
old.Write(l)
|
||||
nold++
|
||||
}
|
||||
if ch != '-' {
|
||||
new.Write(l);
|
||||
nnew++;
|
||||
new.Write(l)
|
||||
nnew++
|
||||
}
|
||||
}
|
||||
c.Old = old.Bytes();
|
||||
c.New = new.Bytes();
|
||||
c.Old = old.Bytes()
|
||||
c.New = new.Bytes()
|
||||
if dropOldNL {
|
||||
c.Old = c.Old[0 : len(c.Old)-1]
|
||||
}
|
||||
@ -144,7 +144,7 @@ func ParseTextDiff(raw []byte) (TextDiff, os.Error) {
|
||||
c.New = c.New[0 : len(c.New)-1]
|
||||
}
|
||||
}
|
||||
return diff, nil;
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
var ErrPatchFailure = os.NewError("patch did not apply cleanly")
|
||||
@ -152,20 +152,20 @@ var ErrPatchFailure = os.NewError("patch did not apply cleanly")
|
||||
// Apply applies the changes listed in the diff
|
||||
// to the data, returning the new version.
|
||||
func (d TextDiff) Apply(data []byte) ([]byte, os.Error) {
|
||||
var buf bytes.Buffer;
|
||||
line := 1;
|
||||
var buf bytes.Buffer
|
||||
line := 1
|
||||
for _, c := range d {
|
||||
var ok bool;
|
||||
var prefix []byte;
|
||||
prefix, data, ok = getLine(data, c.Line-line);
|
||||
var ok bool
|
||||
var prefix []byte
|
||||
prefix, data, ok = getLine(data, c.Line-line)
|
||||
if !ok || !bytes.HasPrefix(data, c.Old) {
|
||||
return nil, ErrPatchFailure
|
||||
}
|
||||
buf.Write(prefix);
|
||||
data = data[len(c.Old):];
|
||||
buf.Write(c.New);
|
||||
line = c.Line + bytes.Count(c.Old, newline);
|
||||
buf.Write(prefix)
|
||||
data = data[len(c.Old):]
|
||||
buf.Write(c.New)
|
||||
line = c.Line + bytes.Count(c.Old, newline)
|
||||
}
|
||||
buf.Write(data);
|
||||
return buf.Bytes(), nil;
|
||||
buf.Write(data)
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
package path
|
||||
|
||||
import (
|
||||
"io/ioutil";
|
||||
"os";
|
||||
"strings";
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Clean returns the shortest path name equivalent to path
|
||||
@ -34,16 +34,16 @@ func Clean(path string) string {
|
||||
return "."
|
||||
}
|
||||
|
||||
rooted := path[0] == '/';
|
||||
n := len(path);
|
||||
rooted := path[0] == '/'
|
||||
n := len(path)
|
||||
|
||||
// Invariants:
|
||||
// reading from path; r is index of next byte to process.
|
||||
// writing to buf; w is index of next byte to write.
|
||||
// dotdot is index in buf where .. must stop, either because
|
||||
// it is the leading slash or it is a leading ../../.. prefix.
|
||||
buf := strings.Bytes(path);
|
||||
r, w, dotdot := 0, 0, 0;
|
||||
buf := strings.Bytes(path)
|
||||
r, w, dotdot := 0, 0, 0
|
||||
if rooted {
|
||||
r, w, dotdot = 1, 1, 1
|
||||
}
|
||||
@ -58,48 +58,48 @@ func Clean(path string) string {
|
||||
r++
|
||||
case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'):
|
||||
// .. element: remove to last /
|
||||
r += 2;
|
||||
r += 2
|
||||
switch {
|
||||
case w > dotdot:
|
||||
// can backtrack
|
||||
w--;
|
||||
w--
|
||||
for w > dotdot && buf[w] != '/' {
|
||||
w--
|
||||
}
|
||||
case !rooted:
|
||||
// cannot backtrack, but not rooted, so append .. element.
|
||||
if w > 0 {
|
||||
buf[w] = '/';
|
||||
w++;
|
||||
buf[w] = '/'
|
||||
w++
|
||||
}
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
dotdot = w;
|
||||
buf[w] = '.'
|
||||
w++
|
||||
buf[w] = '.'
|
||||
w++
|
||||
dotdot = w
|
||||
}
|
||||
default:
|
||||
// real path element.
|
||||
// add slash if needed
|
||||
if rooted && w != 1 || !rooted && w != 0 {
|
||||
buf[w] = '/';
|
||||
w++;
|
||||
buf[w] = '/'
|
||||
w++
|
||||
}
|
||||
// copy element
|
||||
for ; r < n && path[r] != '/'; r++ {
|
||||
buf[w] = path[r];
|
||||
w++;
|
||||
buf[w] = path[r]
|
||||
w++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Turn empty string into "."
|
||||
if w == 0 {
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
buf[w] = '.'
|
||||
w++
|
||||
}
|
||||
|
||||
return string(buf[0:w]);
|
||||
return string(buf[0:w])
|
||||
}
|
||||
|
||||
// Split splits path immediately following the final slash,
|
||||
@ -112,7 +112,7 @@ func Split(path string) (dir, file string) {
|
||||
return path[0 : i+1], path[i+1:]
|
||||
}
|
||||
}
|
||||
return "", path;
|
||||
return "", path
|
||||
}
|
||||
|
||||
// Join joins dir and file into a single path, adding a separating
|
||||
@ -121,7 +121,7 @@ func Join(dir, file string) string {
|
||||
if dir == "" {
|
||||
return file
|
||||
}
|
||||
return Clean(dir + "/" + file);
|
||||
return Clean(dir + "/" + file)
|
||||
}
|
||||
|
||||
// Ext returns the file name extension used by path.
|
||||
@ -134,28 +134,28 @@ func Ext(path string) string {
|
||||
return path[i:]
|
||||
}
|
||||
}
|
||||
return "";
|
||||
return ""
|
||||
}
|
||||
|
||||
// Visitor methods are invoked for corresponding file tree entries
|
||||
// visited by Walk. The parameter path is the full path of d relative
|
||||
// to root.
|
||||
type Visitor interface {
|
||||
VisitDir(path string, d *os.Dir) bool;
|
||||
VisitFile(path string, d *os.Dir);
|
||||
VisitDir(path string, d *os.Dir) bool
|
||||
VisitFile(path string, d *os.Dir)
|
||||
}
|
||||
|
||||
func walk(path string, d *os.Dir, v Visitor, errors chan<- os.Error) {
|
||||
if !d.IsDirectory() {
|
||||
v.VisitFile(path, d);
|
||||
return;
|
||||
v.VisitFile(path, d)
|
||||
return
|
||||
}
|
||||
|
||||
if !v.VisitDir(path, d) {
|
||||
return // skip directory entries
|
||||
return // skip directory entries
|
||||
}
|
||||
|
||||
list, err := ioutil.ReadDir(path);
|
||||
list, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
if errors != nil {
|
||||
errors <- err
|
||||
@ -175,12 +175,12 @@ func walk(path string, d *os.Dir, v Visitor, errors chan<- os.Error) {
|
||||
// If errors != nil, Walk sends each directory read error
|
||||
// to the channel. Otherwise Walk discards the error.
|
||||
func Walk(root string, v Visitor, errors chan<- os.Error) {
|
||||
d, err := os.Lstat(root);
|
||||
d, err := os.Lstat(root)
|
||||
if err != nil {
|
||||
if errors != nil {
|
||||
errors <- err
|
||||
}
|
||||
return; // can't progress
|
||||
return // can't progress
|
||||
}
|
||||
walk(root, d, v, errors);
|
||||
walk(root, d, v, errors)
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
package path
|
||||
|
||||
import (
|
||||
"os";
|
||||
"testing";
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type CleanTest struct {
|
||||
path, clean string;
|
||||
path, clean string
|
||||
}
|
||||
|
||||
var cleantests = []CleanTest{
|
||||
@ -72,7 +72,7 @@ func TestClean(t *testing.T) {
|
||||
}
|
||||
|
||||
type SplitTest struct {
|
||||
path, dir, file string;
|
||||
path, dir, file string
|
||||
}
|
||||
|
||||
var splittests = []SplitTest{
|
||||
@ -92,7 +92,7 @@ func TestSplit(t *testing.T) {
|
||||
}
|
||||
|
||||
type JoinTest struct {
|
||||
dir, file, path string;
|
||||
dir, file, path string
|
||||
}
|
||||
|
||||
var jointests = []JoinTest{
|
||||
@ -114,7 +114,7 @@ func TestJoin(t *testing.T) {
|
||||
}
|
||||
|
||||
type ExtTest struct {
|
||||
path, ext string;
|
||||
path, ext string
|
||||
}
|
||||
|
||||
var exttests = []ExtTest{
|
||||
@ -134,9 +134,9 @@ func TestExt(t *testing.T) {
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
name string;
|
||||
entries []*Node; // nil if the entry is a file
|
||||
mark int;
|
||||
name string
|
||||
entries []*Node // nil if the entry is a file
|
||||
mark int
|
||||
}
|
||||
|
||||
var tree = &Node{
|
||||
@ -166,7 +166,7 @@ var tree = &Node{
|
||||
}
|
||||
|
||||
func walkTree(n *Node, path string, f func(path string, n *Node)) {
|
||||
f(path, n);
|
||||
f(path, n)
|
||||
for _, e := range n.entries {
|
||||
walkTree(e, Join(path, e.name), f)
|
||||
}
|
||||
@ -175,25 +175,25 @@ func walkTree(n *Node, path string, f func(path string, n *Node)) {
|
||||
func makeTree(t *testing.T) {
|
||||
walkTree(tree, tree.name, func(path string, n *Node) {
|
||||
if n.entries == nil {
|
||||
fd, err := os.Open(path, os.O_CREAT, 0660);
|
||||
fd, err := os.Open(path, os.O_CREAT, 0660)
|
||||
if err != nil {
|
||||
t.Errorf("makeTree: %v", err)
|
||||
}
|
||||
fd.Close();
|
||||
fd.Close()
|
||||
} else {
|
||||
os.Mkdir(path, 0770)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) }
|
||||
func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) }
|
||||
|
||||
func checkMarks(t *testing.T) {
|
||||
walkTree(tree, tree.name, func(path string, n *Node) {
|
||||
if n.mark != 1 {
|
||||
t.Errorf("node %s mark = %d; expected 1", path, n.mark)
|
||||
}
|
||||
n.mark = 0;
|
||||
n.mark = 0
|
||||
})
|
||||
}
|
||||
|
||||
@ -209,8 +209,8 @@ func mark(name string) {
|
||||
type TestVisitor struct{}
|
||||
|
||||
func (v *TestVisitor) VisitDir(path string, d *os.Dir) bool {
|
||||
mark(d.Name);
|
||||
return true;
|
||||
mark(d.Name)
|
||||
return true
|
||||
}
|
||||
|
||||
func (v *TestVisitor) VisitFile(path string, d *os.Dir) {
|
||||
@ -218,52 +218,52 @@ func (v *TestVisitor) VisitFile(path string, d *os.Dir) {
|
||||
}
|
||||
|
||||
func TestWalk(t *testing.T) {
|
||||
makeTree(t);
|
||||
makeTree(t)
|
||||
|
||||
// 1) ignore error handling, expect none
|
||||
v := &TestVisitor{};
|
||||
Walk(tree.name, v, nil);
|
||||
checkMarks(t);
|
||||
v := &TestVisitor{}
|
||||
Walk(tree.name, v, nil)
|
||||
checkMarks(t)
|
||||
|
||||
// 2) handle errors, expect none
|
||||
errors := make(chan os.Error, 64);
|
||||
Walk(tree.name, v, errors);
|
||||
errors := make(chan os.Error, 64)
|
||||
Walk(tree.name, v, errors)
|
||||
if err, ok := <-errors; ok {
|
||||
t.Errorf("no error expected, found: s", err)
|
||||
}
|
||||
checkMarks(t);
|
||||
checkMarks(t)
|
||||
|
||||
if os.Getuid() != 0 {
|
||||
// introduce 2 errors: chmod top-level directories to 0
|
||||
os.Chmod(Join(tree.name, tree.entries[1].name), 0);
|
||||
os.Chmod(Join(tree.name, tree.entries[3].name), 0);
|
||||
os.Chmod(Join(tree.name, tree.entries[1].name), 0)
|
||||
os.Chmod(Join(tree.name, tree.entries[3].name), 0)
|
||||
// mark respective subtrees manually
|
||||
markTree(tree.entries[1]);
|
||||
markTree(tree.entries[3]);
|
||||
markTree(tree.entries[1])
|
||||
markTree(tree.entries[3])
|
||||
// correct double-marking of directory itself
|
||||
tree.entries[1].mark--;
|
||||
tree.entries[3].mark--;
|
||||
tree.entries[1].mark--
|
||||
tree.entries[3].mark--
|
||||
|
||||
// 3) handle errors, expect two
|
||||
errors = make(chan os.Error, 64);
|
||||
os.Chmod(Join(tree.name, tree.entries[1].name), 0);
|
||||
Walk(tree.name, v, errors);
|
||||
errors = make(chan os.Error, 64)
|
||||
os.Chmod(Join(tree.name, tree.entries[1].name), 0)
|
||||
Walk(tree.name, v, errors)
|
||||
for i := 1; i <= 2; i++ {
|
||||
if _, ok := <-errors; !ok {
|
||||
t.Errorf("%d. error expected, none found", i);
|
||||
break;
|
||||
t.Errorf("%d. error expected, none found", i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if err, ok := <-errors; ok {
|
||||
t.Errorf("only two errors expected, found 3rd: %v", err)
|
||||
}
|
||||
// the inaccessible subtrees were marked manually
|
||||
checkMarks(t);
|
||||
checkMarks(t)
|
||||
}
|
||||
|
||||
// cleanup
|
||||
os.Chmod(Join(tree.name, tree.entries[1].name), 0770);
|
||||
os.Chmod(Join(tree.name, tree.entries[3].name), 0770);
|
||||
os.Chmod(Join(tree.name, tree.entries[1].name), 0770)
|
||||
os.Chmod(Join(tree.name, tree.entries[3].name), 0770)
|
||||
if err := os.RemoveAll(tree.name); err != nil {
|
||||
t.Errorf("removeTree: %v", err)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
package rand
|
||||
|
||||
import (
|
||||
"math";
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -17,7 +17,7 @@ import (
|
||||
*/
|
||||
|
||||
const (
|
||||
re = 7.69711747013104972;
|
||||
re = 7.69711747013104972
|
||||
)
|
||||
|
||||
// ExpFloat64 returns an exponentially distributed float64 in the range
|
||||
@ -30,9 +30,9 @@ const (
|
||||
//
|
||||
func (r *Rand) ExpFloat64() float64 {
|
||||
for {
|
||||
j := r.Uint32();
|
||||
i := j & 0xFF;
|
||||
x := float64(j) * float64(we[i]);
|
||||
j := r.Uint32()
|
||||
i := j & 0xFF
|
||||
x := float64(j) * float64(we[i])
|
||||
if j < ke[i] {
|
||||
return x
|
||||
}
|
||||
@ -43,7 +43,7 @@ func (r *Rand) ExpFloat64() float64 {
|
||||
return x
|
||||
}
|
||||
}
|
||||
panic("unreachable");
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var ke = [256]uint32{
|
||||
|
@ -5,7 +5,7 @@
|
||||
package rand
|
||||
|
||||
import (
|
||||
"math";
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -17,14 +17,14 @@ import (
|
||||
*/
|
||||
|
||||
const (
|
||||
rn = 3.442619855899;
|
||||
rn = 3.442619855899
|
||||
)
|
||||
|
||||
func absInt32(i int32) uint32 {
|
||||
if i < 0 {
|
||||
return uint32(-i)
|
||||
}
|
||||
return uint32(i);
|
||||
return uint32(i)
|
||||
}
|
||||
|
||||
// NormFloat64 returns a normally distributed float64 in the range
|
||||
@ -37,9 +37,9 @@ func absInt32(i int32) uint32 {
|
||||
//
|
||||
func (r *Rand) NormFloat64() float64 {
|
||||
for {
|
||||
j := int32(r.Uint32()); // Possibly negative
|
||||
i := j & 0x7F;
|
||||
x := float64(j) * float64(wn[i]);
|
||||
j := int32(r.Uint32()) // Possibly negative
|
||||
i := j & 0x7F
|
||||
x := float64(j) * float64(wn[i])
|
||||
if absInt32(j) < kn[i] {
|
||||
// This case should be hit better than 99% of the time.
|
||||
return x
|
||||
@ -48,8 +48,8 @@ func (r *Rand) NormFloat64() float64 {
|
||||
if i == 0 {
|
||||
// This extra work is only required for the base strip.
|
||||
for {
|
||||
x = -math.Log(r.Float64()) * (1.0 / rn);
|
||||
y := -math.Log(r.Float64());
|
||||
x = -math.Log(r.Float64()) * (1.0 / rn)
|
||||
y := -math.Log(r.Float64())
|
||||
if y+y >= x*x {
|
||||
break
|
||||
}
|
||||
@ -57,13 +57,13 @@ func (r *Rand) NormFloat64() float64 {
|
||||
if j > 0 {
|
||||
return rn + x
|
||||
}
|
||||
return -rn - x;
|
||||
return -rn - x
|
||||
}
|
||||
if fn[i]+float32(r.Float64())*(fn[i-1]-fn[i]) < float32(math.Exp(-.5*x*x)) {
|
||||
return x
|
||||
}
|
||||
}
|
||||
panic("unreachable");
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var kn = [128]uint32{
|
||||
|
@ -10,42 +10,42 @@ import "sync"
|
||||
// A Source represents a source of uniformly-distributed
|
||||
// pseudo-random int64 values in the range [0, 1<<63).
|
||||
type Source interface {
|
||||
Int63() int64;
|
||||
Seed(seed int64);
|
||||
Int63() int64
|
||||
Seed(seed int64)
|
||||
}
|
||||
|
||||
// NewSource returns a new pseudo-random Source seeded with the given value.
|
||||
func NewSource(seed int64) Source {
|
||||
var rng rngSource;
|
||||
rng.Seed(seed);
|
||||
return &rng;
|
||||
var rng rngSource
|
||||
rng.Seed(seed)
|
||||
return &rng
|
||||
}
|
||||
|
||||
// A Rand is a source of random numbers.
|
||||
type Rand struct {
|
||||
src Source;
|
||||
src Source
|
||||
}
|
||||
|
||||
// New returns a new Rand that uses random values from src
|
||||
// to generate other random values.
|
||||
func New(src Source) *Rand { return &Rand{src} }
|
||||
func New(src Source) *Rand { return &Rand{src} }
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
func (r *Rand) Seed(seed int64) { r.src.Seed(seed) }
|
||||
func (r *Rand) Seed(seed int64) { r.src.Seed(seed) }
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
|
||||
func (r *Rand) Int63() int64 { return r.src.Int63() }
|
||||
func (r *Rand) Int63() int64 { return r.src.Int63() }
|
||||
|
||||
// Uint32 returns a pseudo-random 32-bit value as a uint32.
|
||||
func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) }
|
||||
func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) }
|
||||
|
||||
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
|
||||
func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) }
|
||||
func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) }
|
||||
|
||||
// Int returns a non-negative pseudo-random int.
|
||||
func (r *Rand) Int() int {
|
||||
u := uint(r.Int63());
|
||||
return int(u << 1 >> 1); // clear sign bit if int == int32
|
||||
u := uint(r.Int63())
|
||||
return int(u << 1 >> 1) // clear sign bit if int == int32
|
||||
}
|
||||
|
||||
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
|
||||
@ -53,40 +53,40 @@ func (r *Rand) Int63n(n int64) int64 {
|
||||
if n <= 0 {
|
||||
return 0
|
||||
}
|
||||
max := int64((1 << 63) - 1 - (1<<63)%uint64(n));
|
||||
v := r.Int63();
|
||||
max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
|
||||
v := r.Int63()
|
||||
for v > max {
|
||||
v = r.Int63()
|
||||
}
|
||||
return v % n;
|
||||
return v % n
|
||||
}
|
||||
|
||||
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
|
||||
func (r *Rand) Int31n(n int32) int32 { return int32(r.Int63n(int64(n))) }
|
||||
func (r *Rand) Int31n(n int32) int32 { return int32(r.Int63n(int64(n))) }
|
||||
|
||||
// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
|
||||
func (r *Rand) Intn(n int) int { return int(r.Int63n(int64(n))) }
|
||||
func (r *Rand) Intn(n int) int { return int(r.Int63n(int64(n))) }
|
||||
|
||||
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float64() float64 { return float64(r.Int63()) / (1 << 63) }
|
||||
func (r *Rand) Float64() float64 { return float64(r.Int63()) / (1 << 63) }
|
||||
|
||||
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float32() float32 { return float32(r.Float64()) }
|
||||
func (r *Rand) Float32() float32 { return float32(r.Float64()) }
|
||||
|
||||
// Float returns, as a float, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float() float { return float(r.Float64()) }
|
||||
func (r *Rand) Float() float { return float(r.Float64()) }
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
|
||||
func (r *Rand) Perm(n int) []int {
|
||||
m := make([]int, n);
|
||||
m := make([]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
m[i] = i
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
j := r.Intn(i + 1);
|
||||
m[i], m[j] = m[j], m[i];
|
||||
j := r.Intn(i + 1)
|
||||
m[i], m[j] = m[j], m[i]
|
||||
}
|
||||
return m;
|
||||
return m
|
||||
}
|
||||
|
||||
/*
|
||||
@ -96,40 +96,40 @@ func (r *Rand) Perm(n int) []int {
|
||||
var globalRand = New(&lockedSource{src: NewSource(1)})
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
func Seed(seed int64) { globalRand.Seed(seed) }
|
||||
func Seed(seed int64) { globalRand.Seed(seed) }
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
|
||||
func Int63() int64 { return globalRand.Int63() }
|
||||
func Int63() int64 { return globalRand.Int63() }
|
||||
|
||||
// Uint32 returns a pseudo-random 32-bit value as a uint32.
|
||||
func Uint32() uint32 { return globalRand.Uint32() }
|
||||
func Uint32() uint32 { return globalRand.Uint32() }
|
||||
|
||||
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
|
||||
func Int31() int32 { return globalRand.Int31() }
|
||||
func Int31() int32 { return globalRand.Int31() }
|
||||
|
||||
// Int returns a non-negative pseudo-random int.
|
||||
func Int() int { return globalRand.Int() }
|
||||
func Int() int { return globalRand.Int() }
|
||||
|
||||
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
|
||||
func Int63n(n int64) int64 { return globalRand.Int63n(n) }
|
||||
func Int63n(n int64) int64 { return globalRand.Int63n(n) }
|
||||
|
||||
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
|
||||
func Int31n(n int32) int32 { return globalRand.Int31n(n) }
|
||||
func Int31n(n int32) int32 { return globalRand.Int31n(n) }
|
||||
|
||||
// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
|
||||
func Intn(n int) int { return globalRand.Intn(n) }
|
||||
func Intn(n int) int { return globalRand.Intn(n) }
|
||||
|
||||
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
|
||||
func Float64() float64 { return globalRand.Float64() }
|
||||
func Float64() float64 { return globalRand.Float64() }
|
||||
|
||||
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
|
||||
func Float32() float32 { return globalRand.Float32() }
|
||||
func Float32() float32 { return globalRand.Float32() }
|
||||
|
||||
// Float returns, as a float, a pseudo-random number in [0.0,1.0).
|
||||
func Float() float { return globalRand.Float() }
|
||||
func Float() float { return globalRand.Float() }
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
|
||||
func Perm(n int) []int { return globalRand.Perm(n) }
|
||||
func Perm(n int) []int { return globalRand.Perm(n) }
|
||||
|
||||
// NormFloat64 returns a normally distributed float64 in the range
|
||||
// [-math.MaxFloat64, +math.MaxFloat64] with
|
||||
@ -139,7 +139,7 @@ func Perm(n int) []int { return globalRand.Perm(n) }
|
||||
//
|
||||
// sample = NormFloat64() * desiredStdDev + desiredMean
|
||||
//
|
||||
func NormFloat64() float64 { return globalRand.NormFloat64() }
|
||||
func NormFloat64() float64 { return globalRand.NormFloat64() }
|
||||
|
||||
// ExpFloat64 returns an exponentially distributed float64 in the range
|
||||
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
|
||||
@ -149,22 +149,22 @@ func NormFloat64() float64 { return globalRand.NormFloat64() }
|
||||
//
|
||||
// sample = ExpFloat64() / desiredRateParameter
|
||||
//
|
||||
func ExpFloat64() float64 { return globalRand.ExpFloat64() }
|
||||
func ExpFloat64() float64 { return globalRand.ExpFloat64() }
|
||||
|
||||
type lockedSource struct {
|
||||
lk sync.Mutex;
|
||||
src Source;
|
||||
lk sync.Mutex
|
||||
src Source
|
||||
}
|
||||
|
||||
func (r *lockedSource) Int63() (n int64) {
|
||||
r.lk.Lock();
|
||||
n = r.src.Int63();
|
||||
r.lk.Unlock();
|
||||
return;
|
||||
r.lk.Lock()
|
||||
n = r.src.Int63()
|
||||
r.lk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (r *lockedSource) Seed(seed int64) {
|
||||
r.lk.Lock();
|
||||
r.src.Seed(seed);
|
||||
r.lk.Unlock();
|
||||
r.lk.Lock()
|
||||
r.src.Seed(seed)
|
||||
r.lk.Unlock()
|
||||
}
|
||||
|
@ -5,36 +5,36 @@
|
||||
package rand
|
||||
|
||||
import (
|
||||
"math";
|
||||
"fmt";
|
||||
"os";
|
||||
"testing";
|
||||
"math"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
numTestSamples = 10000;
|
||||
numTestSamples = 10000
|
||||
)
|
||||
|
||||
type statsResults struct {
|
||||
mean float64;
|
||||
stddev float64;
|
||||
closeEnough float64;
|
||||
maxError float64;
|
||||
mean float64
|
||||
stddev float64
|
||||
closeEnough float64
|
||||
maxError float64
|
||||
}
|
||||
|
||||
func max(a, b float64) float64 {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b;
|
||||
return b
|
||||
}
|
||||
|
||||
func nearEqual(a, b, closeEnough, maxError float64) bool {
|
||||
absDiff := math.Fabs(a - b);
|
||||
if absDiff < closeEnough { // Necessary when one value is zero and one value is close to zero.
|
||||
absDiff := math.Fabs(a - b)
|
||||
if absDiff < closeEnough { // Necessary when one value is zero and one value is close to zero.
|
||||
return true
|
||||
}
|
||||
return absDiff/max(math.Fabs(a), math.Fabs(b)) < maxError;
|
||||
return absDiff/max(math.Fabs(a), math.Fabs(b)) < maxError
|
||||
}
|
||||
|
||||
var testSeeds = []int64{1, 1754801282, 1698661970, 1550503961}
|
||||
@ -43,52 +43,52 @@ var testSeeds = []int64{1, 1754801282, 1698661970, 1550503961}
|
||||
// two statsResults are similar.
|
||||
func (this *statsResults) checkSimilarDistribution(expected *statsResults) os.Error {
|
||||
if !nearEqual(this.mean, expected.mean, expected.closeEnough, expected.maxError) {
|
||||
s := fmt.Sprintf("mean %v != %v (allowed error %v, %v)", this.mean, expected.mean, expected.closeEnough, expected.maxError);
|
||||
fmt.Println(s);
|
||||
return os.ErrorString(s);
|
||||
s := fmt.Sprintf("mean %v != %v (allowed error %v, %v)", this.mean, expected.mean, expected.closeEnough, expected.maxError)
|
||||
fmt.Println(s)
|
||||
return os.ErrorString(s)
|
||||
}
|
||||
if !nearEqual(this.stddev, expected.stddev, 0, expected.maxError) {
|
||||
s := fmt.Sprintf("stddev %v != %v (allowed error %v, %v)", this.stddev, expected.stddev, expected.closeEnough, expected.maxError);
|
||||
fmt.Println(s);
|
||||
return os.ErrorString(s);
|
||||
s := fmt.Sprintf("stddev %v != %v (allowed error %v, %v)", this.stddev, expected.stddev, expected.closeEnough, expected.maxError)
|
||||
fmt.Println(s)
|
||||
return os.ErrorString(s)
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
func getStatsResults(samples []float64) *statsResults {
|
||||
res := new(statsResults);
|
||||
var sum float64;
|
||||
res := new(statsResults)
|
||||
var sum float64
|
||||
for i := range samples {
|
||||
sum += samples[i]
|
||||
}
|
||||
res.mean = sum / float64(len(samples));
|
||||
var devsum float64;
|
||||
res.mean = sum / float64(len(samples))
|
||||
var devsum float64
|
||||
for i := range samples {
|
||||
devsum += math.Pow(samples[i]-res.mean, 2)
|
||||
}
|
||||
res.stddev = math.Sqrt(devsum / float64(len(samples)));
|
||||
return res;
|
||||
res.stddev = math.Sqrt(devsum / float64(len(samples)))
|
||||
return res
|
||||
}
|
||||
|
||||
func checkSampleDistribution(t *testing.T, samples []float64, expected *statsResults) {
|
||||
actual := getStatsResults(samples);
|
||||
err := actual.checkSimilarDistribution(expected);
|
||||
actual := getStatsResults(samples)
|
||||
err := actual.checkSimilarDistribution(expected)
|
||||
if err != nil {
|
||||
t.Errorf(err.String())
|
||||
}
|
||||
}
|
||||
|
||||
func checkSampleSliceDistributions(t *testing.T, samples []float64, nslices int, expected *statsResults) {
|
||||
chunk := len(samples) / nslices;
|
||||
chunk := len(samples) / nslices
|
||||
for i := 0; i < nslices; i++ {
|
||||
low := i * chunk;
|
||||
var high int;
|
||||
low := i * chunk
|
||||
var high int
|
||||
if i == nslices-1 {
|
||||
high = len(samples) - 1
|
||||
} else {
|
||||
high = (i + 1) * chunk
|
||||
}
|
||||
checkSampleDistribution(t, samples[low:high], expected);
|
||||
checkSampleDistribution(t, samples[low:high], expected)
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,29 +97,29 @@ func checkSampleSliceDistributions(t *testing.T, samples []float64, nslices int,
|
||||
//
|
||||
|
||||
func generateNormalSamples(nsamples int, mean, stddev float64, seed int64) []float64 {
|
||||
r := New(NewSource(seed));
|
||||
samples := make([]float64, nsamples);
|
||||
r := New(NewSource(seed))
|
||||
samples := make([]float64, nsamples)
|
||||
for i := range samples {
|
||||
samples[i] = r.NormFloat64()*stddev + mean
|
||||
}
|
||||
return samples;
|
||||
return samples
|
||||
}
|
||||
|
||||
func testNormalDistribution(t *testing.T, nsamples int, mean, stddev float64, seed int64) {
|
||||
//fmt.Printf("testing nsamples=%v mean=%v stddev=%v seed=%v\n", nsamples, mean, stddev, seed);
|
||||
|
||||
samples := generateNormalSamples(nsamples, mean, stddev, seed);
|
||||
errorScale := max(1.0, stddev); // Error scales with stddev
|
||||
expected := &statsResults{mean, stddev, 0.10 * errorScale, 0.08 * errorScale};
|
||||
samples := generateNormalSamples(nsamples, mean, stddev, seed)
|
||||
errorScale := max(1.0, stddev) // Error scales with stddev
|
||||
expected := &statsResults{mean, stddev, 0.10 * errorScale, 0.08 * errorScale}
|
||||
|
||||
// Make sure that the entire set matches the expected distribution.
|
||||
checkSampleDistribution(t, samples, expected);
|
||||
checkSampleDistribution(t, samples, expected)
|
||||
|
||||
// Make sure that each half of the set matches the expected distribution.
|
||||
checkSampleSliceDistributions(t, samples, 2, expected);
|
||||
checkSampleSliceDistributions(t, samples, 2, expected)
|
||||
|
||||
// Make sure that each 7th of the set matches the expected distribution.
|
||||
checkSampleSliceDistributions(t, samples, 7, expected);
|
||||
checkSampleSliceDistributions(t, samples, 7, expected)
|
||||
}
|
||||
|
||||
// Actual tests
|
||||
@ -145,32 +145,32 @@ func TestNonStandardNormalValues(t *testing.T) {
|
||||
//
|
||||
|
||||
func generateExponentialSamples(nsamples int, rate float64, seed int64) []float64 {
|
||||
r := New(NewSource(seed));
|
||||
samples := make([]float64, nsamples);
|
||||
r := New(NewSource(seed))
|
||||
samples := make([]float64, nsamples)
|
||||
for i := range samples {
|
||||
samples[i] = r.ExpFloat64() / rate
|
||||
}
|
||||
return samples;
|
||||
return samples
|
||||
}
|
||||
|
||||
func testExponentialDistribution(t *testing.T, nsamples int, rate float64, seed int64) {
|
||||
//fmt.Printf("testing nsamples=%v rate=%v seed=%v\n", nsamples, rate, seed);
|
||||
|
||||
mean := 1 / rate;
|
||||
stddev := mean;
|
||||
mean := 1 / rate
|
||||
stddev := mean
|
||||
|
||||
samples := generateExponentialSamples(nsamples, rate, seed);
|
||||
errorScale := max(1.0, 1/rate); // Error scales with the inverse of the rate
|
||||
expected := &statsResults{mean, stddev, 0.10 * errorScale, 0.20 * errorScale};
|
||||
samples := generateExponentialSamples(nsamples, rate, seed)
|
||||
errorScale := max(1.0, 1/rate) // Error scales with the inverse of the rate
|
||||
expected := &statsResults{mean, stddev, 0.10 * errorScale, 0.20 * errorScale}
|
||||
|
||||
// Make sure that the entire set matches the expected distribution.
|
||||
checkSampleDistribution(t, samples, expected);
|
||||
checkSampleDistribution(t, samples, expected)
|
||||
|
||||
// Make sure that each half of the set matches the expected distribution.
|
||||
checkSampleSliceDistributions(t, samples, 2, expected);
|
||||
checkSampleSliceDistributions(t, samples, 2, expected)
|
||||
|
||||
// Make sure that each 7th of the set matches the expected distribution.
|
||||
checkSampleSliceDistributions(t, samples, 7, expected);
|
||||
checkSampleSliceDistributions(t, samples, 7, expected)
|
||||
}
|
||||
|
||||
// Actual tests
|
||||
@ -194,61 +194,61 @@ func TestNonStandardExponentialValues(t *testing.T) {
|
||||
//
|
||||
|
||||
func initNorm() (testKn []uint32, testWn, testFn []float32) {
|
||||
const m1 = 1 << 31;
|
||||
const m1 = 1 << 31
|
||||
var (
|
||||
dn float64 = rn;
|
||||
tn = dn;
|
||||
vn float64 = 9.91256303526217e-3;
|
||||
dn float64 = rn
|
||||
tn = dn
|
||||
vn float64 = 9.91256303526217e-3
|
||||
)
|
||||
|
||||
testKn = make([]uint32, 128);
|
||||
testWn = make([]float32, 128);
|
||||
testFn = make([]float32, 128);
|
||||
testKn = make([]uint32, 128)
|
||||
testWn = make([]float32, 128)
|
||||
testFn = make([]float32, 128)
|
||||
|
||||
q := vn / math.Exp(-0.5*dn*dn);
|
||||
testKn[0] = uint32((dn / q) * m1);
|
||||
testKn[1] = 0;
|
||||
testWn[0] = float32(q / m1);
|
||||
testWn[127] = float32(dn / m1);
|
||||
testFn[0] = 1.0;
|
||||
testFn[127] = float32(math.Exp(-0.5 * dn * dn));
|
||||
q := vn / math.Exp(-0.5*dn*dn)
|
||||
testKn[0] = uint32((dn / q) * m1)
|
||||
testKn[1] = 0
|
||||
testWn[0] = float32(q / m1)
|
||||
testWn[127] = float32(dn / m1)
|
||||
testFn[0] = 1.0
|
||||
testFn[127] = float32(math.Exp(-0.5 * dn * dn))
|
||||
for i := 126; i >= 1; i-- {
|
||||
dn = math.Sqrt(-2.0 * math.Log(vn/dn+math.Exp(-0.5*dn*dn)));
|
||||
testKn[i+1] = uint32((dn / tn) * m1);
|
||||
tn = dn;
|
||||
testFn[i] = float32(math.Exp(-0.5 * dn * dn));
|
||||
testWn[i] = float32(dn / m1);
|
||||
dn = math.Sqrt(-2.0 * math.Log(vn/dn+math.Exp(-0.5*dn*dn)))
|
||||
testKn[i+1] = uint32((dn / tn) * m1)
|
||||
tn = dn
|
||||
testFn[i] = float32(math.Exp(-0.5 * dn * dn))
|
||||
testWn[i] = float32(dn / m1)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func initExp() (testKe []uint32, testWe, testFe []float32) {
|
||||
const m2 = 1 << 32;
|
||||
const m2 = 1 << 32
|
||||
var (
|
||||
de float64 = re;
|
||||
te = de;
|
||||
ve float64 = 3.9496598225815571993e-3;
|
||||
de float64 = re
|
||||
te = de
|
||||
ve float64 = 3.9496598225815571993e-3
|
||||
)
|
||||
|
||||
testKe = make([]uint32, 256);
|
||||
testWe = make([]float32, 256);
|
||||
testFe = make([]float32, 256);
|
||||
testKe = make([]uint32, 256)
|
||||
testWe = make([]float32, 256)
|
||||
testFe = make([]float32, 256)
|
||||
|
||||
q := ve / math.Exp(-de);
|
||||
testKe[0] = uint32((de / q) * m2);
|
||||
testKe[1] = 0;
|
||||
testWe[0] = float32(q / m2);
|
||||
testWe[255] = float32(de / m2);
|
||||
testFe[0] = 1.0;
|
||||
testFe[255] = float32(math.Exp(-de));
|
||||
q := ve / math.Exp(-de)
|
||||
testKe[0] = uint32((de / q) * m2)
|
||||
testKe[1] = 0
|
||||
testWe[0] = float32(q / m2)
|
||||
testWe[255] = float32(de / m2)
|
||||
testFe[0] = 1.0
|
||||
testFe[255] = float32(math.Exp(-de))
|
||||
for i := 254; i >= 1; i-- {
|
||||
de = -math.Log(ve/de + math.Exp(-de));
|
||||
testKe[i+1] = uint32((de / te) * m2);
|
||||
te = de;
|
||||
testFe[i] = float32(math.Exp(-de));
|
||||
testWe[i] = float32(de / m2);
|
||||
de = -math.Log(ve/de + math.Exp(-de))
|
||||
testKe[i+1] = uint32((de / te) * m2)
|
||||
te = de
|
||||
testFe[i] = float32(math.Exp(-de))
|
||||
testWe[i] = float32(de / m2)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// compareUint32Slices returns the first index where the two slices
|
||||
@ -259,14 +259,14 @@ func compareUint32Slices(s1, s2 []uint32) int {
|
||||
if len(s1) > len(s2) {
|
||||
return len(s2) + 1
|
||||
}
|
||||
return len(s1) + 1;
|
||||
return len(s1) + 1
|
||||
}
|
||||
for i := range s1 {
|
||||
if s1[i] != s2[i] {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
|
||||
// compareFloat32Slices returns the first index where the two slices
|
||||
@ -277,18 +277,18 @@ func compareFloat32Slices(s1, s2 []float32) int {
|
||||
if len(s1) > len(s2) {
|
||||
return len(s2) + 1
|
||||
}
|
||||
return len(s1) + 1;
|
||||
return len(s1) + 1
|
||||
}
|
||||
for i := range s1 {
|
||||
if !nearEqual(float64(s1[i]), float64(s2[i]), 0, 1e-7) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
|
||||
func TestNormTables(t *testing.T) {
|
||||
testKn, testWn, testFn := initNorm();
|
||||
testKn, testWn, testFn := initNorm()
|
||||
if i := compareUint32Slices(kn[0:], testKn); i >= 0 {
|
||||
t.Errorf("kn disagrees at index %v; %v != %v\n", i, kn[i], testKn[i])
|
||||
}
|
||||
@ -301,7 +301,7 @@ func TestNormTables(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExpTables(t *testing.T) {
|
||||
testKe, testWe, testFe := initExp();
|
||||
testKe, testWe, testFe := initExp()
|
||||
if i := compareUint32Slices(ke[0:], testKe); i >= 0 {
|
||||
t.Errorf("ke disagrees at index %v; %v != %v\n", i, ke[i], testKe[i])
|
||||
}
|
||||
@ -322,7 +322,7 @@ func BenchmarkInt63Threadsafe(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkInt63Unthreadsafe(b *testing.B) {
|
||||
r := New(NewSource(1));
|
||||
r := New(NewSource(1))
|
||||
for n := b.N; n > 0; n-- {
|
||||
r.Int63()
|
||||
}
|
||||
|
@ -12,14 +12,14 @@ package rand
|
||||
*/
|
||||
|
||||
const (
|
||||
_LEN = 607;
|
||||
_TAP = 273;
|
||||
_MAX = 1 << 63;
|
||||
_MASK = _MAX - 1;
|
||||
_A = 48271;
|
||||
_M = (1 << 31) - 1;
|
||||
_Q = 44488;
|
||||
_R = 3399;
|
||||
_LEN = 607
|
||||
_TAP = 273
|
||||
_MAX = 1 << 63
|
||||
_MASK = _MAX - 1
|
||||
_A = 48271
|
||||
_M = (1 << 31) - 1
|
||||
_Q = 44488
|
||||
_R = 3399
|
||||
)
|
||||
|
||||
var (
|
||||
@ -179,32 +179,32 @@ var (
|
||||
4922828954023452664, 2879211533496425641, 5896236396443472108, 8465043815351752425,
|
||||
7329020396871624740, 8915471717014488588, 2944902635677463047, 7052079073493465134,
|
||||
8382142935188824023, 9103922860780351547, 4152330101494654406,
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
type rngSource struct {
|
||||
tap int; // index into vec
|
||||
feed int; // index into vec
|
||||
vec [_LEN]int64; // current feedback register
|
||||
tap int // index into vec
|
||||
feed int // index into vec
|
||||
vec [_LEN]int64 // current feedback register
|
||||
}
|
||||
|
||||
// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
|
||||
func seedrand(x int32) int32 {
|
||||
hi := x / _Q;
|
||||
lo := x % _Q;
|
||||
x = _A*lo - _R*hi;
|
||||
hi := x / _Q
|
||||
lo := x % _Q
|
||||
x = _A*lo - _R*hi
|
||||
if x < 0 {
|
||||
x += _M
|
||||
}
|
||||
return x;
|
||||
return x
|
||||
}
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
func (rng *rngSource) Seed(seed int64) {
|
||||
rng.tap = 0;
|
||||
rng.feed = _LEN - _TAP;
|
||||
rng.tap = 0
|
||||
rng.feed = _LEN - _TAP
|
||||
|
||||
seed = seed % _M;
|
||||
seed = seed % _M
|
||||
if seed < 0 {
|
||||
seed += _M
|
||||
}
|
||||
@ -212,35 +212,35 @@ func (rng *rngSource) Seed(seed int64) {
|
||||
seed = 89482311
|
||||
}
|
||||
|
||||
x := int32(seed);
|
||||
x := int32(seed)
|
||||
for i := -20; i < _LEN; i++ {
|
||||
x = seedrand(x);
|
||||
x = seedrand(x)
|
||||
if i >= 0 {
|
||||
var u int64;
|
||||
u = int64(x) << 40;
|
||||
x = seedrand(x);
|
||||
u ^= int64(x) << 20;
|
||||
x = seedrand(x);
|
||||
u ^= int64(x);
|
||||
u ^= rng_cooked[i];
|
||||
rng.vec[i] = u & _MASK;
|
||||
var u int64
|
||||
u = int64(x) << 40
|
||||
x = seedrand(x)
|
||||
u ^= int64(x) << 20
|
||||
x = seedrand(x)
|
||||
u ^= int64(x)
|
||||
u ^= rng_cooked[i]
|
||||
rng.vec[i] = u & _MASK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
|
||||
func (rng *rngSource) Int63() int64 {
|
||||
rng.tap--;
|
||||
rng.tap--
|
||||
if rng.tap < 0 {
|
||||
rng.tap += _LEN
|
||||
}
|
||||
|
||||
rng.feed--;
|
||||
rng.feed--
|
||||
if rng.feed < 0 {
|
||||
rng.feed += _LEN
|
||||
}
|
||||
|
||||
x := (rng.vec[rng.feed] + rng.vec[rng.tap]) & _MASK;
|
||||
rng.vec[rng.feed] = x;
|
||||
return x;
|
||||
x := (rng.vec[rng.feed] + rng.vec[rng.tap]) & _MASK
|
||||
rng.vec[rng.feed] = x
|
||||
return x
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,10 @@ package reflect
|
||||
// checks in progress are true when it reencounters them.
|
||||
// Visited are stored in a map indexed by 17 * a1 + a2;
|
||||
type visit struct {
|
||||
a1 uintptr;
|
||||
a2 uintptr;
|
||||
typ Type;
|
||||
next *visit;
|
||||
a1 uintptr
|
||||
a2 uintptr
|
||||
typ Type
|
||||
next *visit
|
||||
}
|
||||
|
||||
// Tests for deep equality using reflected types. The map argument tracks
|
||||
@ -31,8 +31,8 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
||||
|
||||
// if depth > 10 { panic("deepValueEqual") } // for debugging
|
||||
|
||||
addr1 := v1.Addr();
|
||||
addr2 := v2.Addr();
|
||||
addr1 := v1.Addr()
|
||||
addr2 := v2.Addr()
|
||||
if addr1 > addr2 {
|
||||
// Canonicalize order to reduce number of entries in visited.
|
||||
addr1, addr2 = addr2, addr1
|
||||
@ -44,9 +44,9 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
||||
}
|
||||
|
||||
// ... or already seen
|
||||
h := 17*addr1 + addr2;
|
||||
seen, _ := visited[h];
|
||||
typ := v1.Type();
|
||||
h := 17*addr1 + addr2
|
||||
seen, _ := visited[h]
|
||||
typ := v1.Type()
|
||||
for p := seen; p != nil; p = p.next {
|
||||
if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ {
|
||||
return true
|
||||
@ -54,12 +54,12 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
||||
}
|
||||
|
||||
// Remember for later.
|
||||
visited[h] = &visit{addr1, addr2, typ, seen};
|
||||
visited[h] = &visit{addr1, addr2, typ, seen}
|
||||
|
||||
switch v := v1.(type) {
|
||||
case *ArrayValue:
|
||||
arr1 := v;
|
||||
arr2 := v2.(*ArrayValue);
|
||||
arr1 := v
|
||||
arr2 := v2.(*ArrayValue)
|
||||
if arr1.Len() != arr2.Len() {
|
||||
return false
|
||||
}
|
||||
@ -68,10 +68,10 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
case *SliceValue:
|
||||
arr1 := v;
|
||||
arr2 := v2.(*SliceValue);
|
||||
arr1 := v
|
||||
arr2 := v2.(*SliceValue)
|
||||
if arr1.Len() != arr2.Len() {
|
||||
return false
|
||||
}
|
||||
@ -80,28 +80,28 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
case *InterfaceValue:
|
||||
i1 := v.Interface();
|
||||
i2 := v2.Interface();
|
||||
i1 := v.Interface()
|
||||
i2 := v2.Interface()
|
||||
if i1 == nil || i2 == nil {
|
||||
return i1 == i2
|
||||
}
|
||||
return deepValueEqual(NewValue(i1), NewValue(i2), visited, depth+1);
|
||||
return deepValueEqual(NewValue(i1), NewValue(i2), visited, depth+1)
|
||||
case *PtrValue:
|
||||
return deepValueEqual(v.Elem(), v2.(*PtrValue).Elem(), visited, depth+1)
|
||||
case *StructValue:
|
||||
struct1 := v;
|
||||
struct2 := v2.(*StructValue);
|
||||
struct1 := v
|
||||
struct2 := v2.(*StructValue)
|
||||
for i, n := 0, v.NumField(); i < n; i++ {
|
||||
if !deepValueEqual(struct1.Field(i), struct2.Field(i), visited, depth+1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
case *MapValue:
|
||||
map1 := v;
|
||||
map2 := v2.(*MapValue);
|
||||
map1 := v
|
||||
map2 := v2.(*MapValue)
|
||||
if map1.Len() != map2.Len() {
|
||||
return false
|
||||
}
|
||||
@ -110,13 +110,13 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
default:
|
||||
// Normal equality suffices
|
||||
return v1.Interface() == v2.Interface()
|
||||
}
|
||||
|
||||
panic("Not reached");
|
||||
panic("Not reached")
|
||||
}
|
||||
|
||||
// DeepEqual tests for deep equality. It uses normal == equality where possible
|
||||
@ -126,10 +126,10 @@ func DeepEqual(a1, a2 interface{}) bool {
|
||||
if a1 == nil || a2 == nil {
|
||||
return a1 == a2
|
||||
}
|
||||
v1 := NewValue(a1);
|
||||
v2 := NewValue(a2);
|
||||
v1 := NewValue(a1)
|
||||
v2 := NewValue(a2)
|
||||
if v1.Type() != v2.Type() {
|
||||
return false
|
||||
}
|
||||
return deepValueEqual(v1, v2, make(map[uintptr]*visit), 0);
|
||||
return deepValueEqual(v1, v2, make(map[uintptr]*visit), 0)
|
||||
}
|
||||
|
@ -9,18 +9,18 @@
|
||||
package reflect_test
|
||||
|
||||
import (
|
||||
. "reflect";
|
||||
"strconv";
|
||||
. "reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// valueToString returns a textual representation of the reflection value val.
|
||||
// For debugging only.
|
||||
func valueToString(val Value) string {
|
||||
var str string;
|
||||
var str string
|
||||
if val == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
typ := val.Type();
|
||||
typ := val.Type()
|
||||
switch val := val.(type) {
|
||||
case *IntValue:
|
||||
return strconv.Uitoa64(uint64(val.Get()))
|
||||
@ -61,57 +61,57 @@ func valueToString(val Value) string {
|
||||
return "false"
|
||||
}
|
||||
case *PtrValue:
|
||||
v := val;
|
||||
str = typ.String() + "(";
|
||||
v := val
|
||||
str = typ.String() + "("
|
||||
if v.IsNil() {
|
||||
str += "0"
|
||||
} else {
|
||||
str += "&" + valueToString(v.Elem())
|
||||
}
|
||||
str += ")";
|
||||
return str;
|
||||
str += ")"
|
||||
return str
|
||||
case ArrayOrSliceValue:
|
||||
v := val;
|
||||
str += typ.String();
|
||||
str += "{";
|
||||
v := val
|
||||
str += typ.String()
|
||||
str += "{"
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if i > 0 {
|
||||
str += ", "
|
||||
}
|
||||
str += valueToString(v.Elem(i));
|
||||
str += valueToString(v.Elem(i))
|
||||
}
|
||||
str += "}";
|
||||
return str;
|
||||
str += "}"
|
||||
return str
|
||||
case *MapValue:
|
||||
t := typ.(*MapType);
|
||||
str = t.String();
|
||||
str += "{";
|
||||
str += "<can't iterate on maps>";
|
||||
str += "}";
|
||||
return str;
|
||||
t := typ.(*MapType)
|
||||
str = t.String()
|
||||
str += "{"
|
||||
str += "<can't iterate on maps>"
|
||||
str += "}"
|
||||
return str
|
||||
case *ChanValue:
|
||||
str = typ.String();
|
||||
return str;
|
||||
str = typ.String()
|
||||
return str
|
||||
case *StructValue:
|
||||
t := typ.(*StructType);
|
||||
v := val;
|
||||
str += t.String();
|
||||
str += "{";
|
||||
t := typ.(*StructType)
|
||||
v := val
|
||||
str += t.String()
|
||||
str += "{"
|
||||
for i, n := 0, v.NumField(); i < n; i++ {
|
||||
if i > 0 {
|
||||
str += ", "
|
||||
}
|
||||
str += valueToString(v.Field(i));
|
||||
str += valueToString(v.Field(i))
|
||||
}
|
||||
str += "}";
|
||||
return str;
|
||||
str += "}"
|
||||
return str
|
||||
case *InterfaceValue:
|
||||
return typ.String() + "(" + valueToString(val.Elem()) + ")"
|
||||
case *FuncValue:
|
||||
v := val;
|
||||
return typ.String() + "(" + strconv.Itoa64(int64(v.Get())) + ")";
|
||||
v := val
|
||||
return typ.String() + "(" + strconv.Itoa64(int64(v.Get())) + ")"
|
||||
default:
|
||||
panicln("valueToString: can't print type ", typ.String())
|
||||
}
|
||||
return "valueToString: can't happen";
|
||||
return "valueToString: can't happen"
|
||||
}
|
||||
|
@ -16,9 +16,9 @@
|
||||
package reflect
|
||||
|
||||
import (
|
||||
"runtime";
|
||||
"strconv";
|
||||
"unsafe";
|
||||
"runtime"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -35,198 +35,198 @@ import (
|
||||
*/
|
||||
|
||||
type commonType struct {
|
||||
size uintptr;
|
||||
hash uint32;
|
||||
alg uint8;
|
||||
align uint8;
|
||||
fieldAlign uint8;
|
||||
string *string;
|
||||
*uncommonType;
|
||||
size uintptr
|
||||
hash uint32
|
||||
alg uint8
|
||||
align uint8
|
||||
fieldAlign uint8
|
||||
string *string
|
||||
*uncommonType
|
||||
}
|
||||
|
||||
type method struct {
|
||||
hash uint32;
|
||||
name *string;
|
||||
pkgPath *string;
|
||||
typ *runtime.Type;
|
||||
ifn unsafe.Pointer;
|
||||
tfn unsafe.Pointer;
|
||||
hash uint32
|
||||
name *string
|
||||
pkgPath *string
|
||||
typ *runtime.Type
|
||||
ifn unsafe.Pointer
|
||||
tfn unsafe.Pointer
|
||||
}
|
||||
|
||||
type uncommonType struct {
|
||||
name *string;
|
||||
pkgPath *string;
|
||||
methods []method;
|
||||
name *string
|
||||
pkgPath *string
|
||||
methods []method
|
||||
}
|
||||
|
||||
// BoolType represents a boolean type.
|
||||
type BoolType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Float32Type represents a float32 type.
|
||||
type Float32Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Float64Type represents a float64 type.
|
||||
type Float64Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// FloatType represents a float type.
|
||||
type FloatType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Int16Type represents an int16 type.
|
||||
type Int16Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Int32Type represents an int32 type.
|
||||
type Int32Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Int64Type represents an int64 type.
|
||||
type Int64Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Int8Type represents an int8 type.
|
||||
type Int8Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// IntType represents an int type.
|
||||
type IntType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Uint16Type represents a uint16 type.
|
||||
type Uint16Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Uint32Type represents a uint32 type.
|
||||
type Uint32Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Uint64Type represents a uint64 type.
|
||||
type Uint64Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// Uint8Type represents a uint8 type.
|
||||
type Uint8Type struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// UintType represents a uint type.
|
||||
type UintType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// StringType represents a string type.
|
||||
type StringType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// UintptrType represents a uintptr type.
|
||||
type UintptrType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// DotDotDotType represents the ... that can
|
||||
// be used as the type of the final function parameter.
|
||||
type DotDotDotType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// UnsafePointerType represents an unsafe.Pointer type.
|
||||
type UnsafePointerType struct {
|
||||
commonType;
|
||||
commonType
|
||||
}
|
||||
|
||||
// ArrayType represents a fixed array type.
|
||||
type ArrayType struct {
|
||||
commonType;
|
||||
elem *runtime.Type;
|
||||
len uintptr;
|
||||
commonType
|
||||
elem *runtime.Type
|
||||
len uintptr
|
||||
}
|
||||
|
||||
// ChanDir represents a channel type's direction.
|
||||
type ChanDir int
|
||||
|
||||
const (
|
||||
RecvDir ChanDir = 1 << iota;
|
||||
SendDir;
|
||||
BothDir = RecvDir | SendDir;
|
||||
RecvDir ChanDir = 1 << iota
|
||||
SendDir
|
||||
BothDir = RecvDir | SendDir
|
||||
)
|
||||
|
||||
// ChanType represents a channel type.
|
||||
type ChanType struct {
|
||||
commonType;
|
||||
elem *runtime.Type;
|
||||
dir uintptr;
|
||||
commonType
|
||||
elem *runtime.Type
|
||||
dir uintptr
|
||||
}
|
||||
|
||||
// FuncType represents a function type.
|
||||
type FuncType struct {
|
||||
commonType;
|
||||
in []*runtime.Type;
|
||||
out []*runtime.Type;
|
||||
commonType
|
||||
in []*runtime.Type
|
||||
out []*runtime.Type
|
||||
}
|
||||
|
||||
// Method on interface type
|
||||
type imethod struct {
|
||||
hash uint32;
|
||||
perm uint32;
|
||||
name *string;
|
||||
pkgPath *string;
|
||||
typ *runtime.Type;
|
||||
hash uint32
|
||||
perm uint32
|
||||
name *string
|
||||
pkgPath *string
|
||||
typ *runtime.Type
|
||||
}
|
||||
|
||||
// InterfaceType represents an interface type.
|
||||
type InterfaceType struct {
|
||||
commonType;
|
||||
methods []imethod;
|
||||
commonType
|
||||
methods []imethod
|
||||
}
|
||||
|
||||
// MapType represents a map type.
|
||||
type MapType struct {
|
||||
commonType;
|
||||
key *runtime.Type;
|
||||
elem *runtime.Type;
|
||||
commonType
|
||||
key *runtime.Type
|
||||
elem *runtime.Type
|
||||
}
|
||||
|
||||
// PtrType represents a pointer type.
|
||||
type PtrType struct {
|
||||
commonType;
|
||||
elem *runtime.Type;
|
||||
commonType
|
||||
elem *runtime.Type
|
||||
}
|
||||
|
||||
// SliceType represents a slice type.
|
||||
type SliceType struct {
|
||||
commonType;
|
||||
elem *runtime.Type;
|
||||
commonType
|
||||
elem *runtime.Type
|
||||
}
|
||||
|
||||
// Struct field
|
||||
type structField struct {
|
||||
name *string;
|
||||
pkgPath *string;
|
||||
typ *runtime.Type;
|
||||
tag *string;
|
||||
offset uintptr;
|
||||
name *string
|
||||
pkgPath *string
|
||||
typ *runtime.Type
|
||||
tag *string
|
||||
offset uintptr
|
||||
}
|
||||
|
||||
// StructType represents a struct type.
|
||||
type StructType struct {
|
||||
commonType;
|
||||
fields []structField;
|
||||
commonType
|
||||
fields []structField
|
||||
}
|
||||
|
||||
|
||||
@ -237,10 +237,10 @@ type StructType struct {
|
||||
|
||||
// Method represents a single method.
|
||||
type Method struct {
|
||||
PkgPath string; // empty for uppercase Name
|
||||
Name string;
|
||||
Type *FuncType;
|
||||
Func *FuncValue;
|
||||
PkgPath string // empty for uppercase Name
|
||||
Name string
|
||||
Type *FuncType
|
||||
Func *FuncValue
|
||||
}
|
||||
|
||||
// Type is the runtime representation of a Go type.
|
||||
@ -253,37 +253,37 @@ type Type interface {
|
||||
// PkgPath returns the type's package path.
|
||||
// The package path is a full package import path like "container/vector".
|
||||
// PkgPath returns an empty string for unnamed types.
|
||||
PkgPath() string;
|
||||
PkgPath() string
|
||||
|
||||
// Name returns the type's name within its package.
|
||||
// Name returns an empty string for unnamed types.
|
||||
Name() string;
|
||||
Name() string
|
||||
|
||||
// String returns a string representation of the type.
|
||||
// The string representation may use shortened package names
|
||||
// (e.g., vector instead of "container/vector") and is not
|
||||
// guaranteed to be unique among types. To test for equality,
|
||||
// compare the Types directly.
|
||||
String() string;
|
||||
String() string
|
||||
|
||||
// Size returns the number of bytes needed to store
|
||||
// a value of the given type; it is analogous to unsafe.Sizeof.
|
||||
Size() uintptr;
|
||||
Size() uintptr
|
||||
|
||||
// Align returns the alignment of a value of this type
|
||||
// when allocated in memory.
|
||||
Align() int;
|
||||
Align() int
|
||||
|
||||
// FieldAlign returns the alignment of a value of this type
|
||||
// when used as a field in a struct.
|
||||
FieldAlign() int;
|
||||
FieldAlign() int
|
||||
|
||||
// For non-interface types, Method returns the i'th method with receiver T.
|
||||
// For interface types, Method returns the i'th method in the interface.
|
||||
// NumMethod returns the number of such methods.
|
||||
Method(int) Method;
|
||||
NumMethod() int;
|
||||
uncommon() *uncommonType;
|
||||
Method(int) Method
|
||||
NumMethod() int
|
||||
uncommon() *uncommonType
|
||||
}
|
||||
|
||||
func (t *uncommonType) uncommon() *uncommonType {
|
||||
@ -294,70 +294,70 @@ func (t *uncommonType) PkgPath() string {
|
||||
if t == nil || t.pkgPath == nil {
|
||||
return ""
|
||||
}
|
||||
return *t.pkgPath;
|
||||
return *t.pkgPath
|
||||
}
|
||||
|
||||
func (t *uncommonType) Name() string {
|
||||
if t == nil || t.name == nil {
|
||||
return ""
|
||||
}
|
||||
return *t.name;
|
||||
return *t.name
|
||||
}
|
||||
|
||||
func (t *commonType) String() string { return *t.string }
|
||||
func (t *commonType) String() string { return *t.string }
|
||||
|
||||
func (t *commonType) Size() uintptr { return t.size }
|
||||
func (t *commonType) Size() uintptr { return t.size }
|
||||
|
||||
func (t *commonType) Align() int { return int(t.align) }
|
||||
func (t *commonType) Align() int { return int(t.align) }
|
||||
|
||||
func (t *commonType) FieldAlign() int { return int(t.fieldAlign) }
|
||||
func (t *commonType) FieldAlign() int { return int(t.fieldAlign) }
|
||||
|
||||
func (t *uncommonType) Method(i int) (m Method) {
|
||||
if t == nil || i < 0 || i >= len(t.methods) {
|
||||
return
|
||||
}
|
||||
p := &t.methods[i];
|
||||
p := &t.methods[i]
|
||||
if p.name != nil {
|
||||
m.Name = *p.name
|
||||
}
|
||||
if p.pkgPath != nil {
|
||||
m.PkgPath = *p.pkgPath
|
||||
}
|
||||
m.Type = toType(*p.typ).(*FuncType);
|
||||
fn := p.tfn;
|
||||
m.Func = newFuncValue(m.Type, addr(&fn), true);
|
||||
return;
|
||||
m.Type = toType(*p.typ).(*FuncType)
|
||||
fn := p.tfn
|
||||
m.Func = newFuncValue(m.Type, addr(&fn), true)
|
||||
return
|
||||
}
|
||||
|
||||
func (t *uncommonType) NumMethod() int {
|
||||
if t == nil {
|
||||
return 0
|
||||
}
|
||||
return len(t.methods);
|
||||
return len(t.methods)
|
||||
}
|
||||
|
||||
// TODO(rsc): 6g supplies these, but they are not
|
||||
// as efficient as they could be: they have commonType
|
||||
// as the receiver instead of *commonType.
|
||||
func (t *commonType) NumMethod() int { return t.uncommonType.NumMethod() }
|
||||
func (t *commonType) NumMethod() int { return t.uncommonType.NumMethod() }
|
||||
|
||||
func (t *commonType) Method(i int) (m Method) { return t.uncommonType.Method(i) }
|
||||
func (t *commonType) Method(i int) (m Method) { return t.uncommonType.Method(i) }
|
||||
|
||||
func (t *commonType) PkgPath() string { return t.uncommonType.PkgPath() }
|
||||
func (t *commonType) PkgPath() string { return t.uncommonType.PkgPath() }
|
||||
|
||||
func (t *commonType) Name() string { return t.uncommonType.Name() }
|
||||
func (t *commonType) Name() string { return t.uncommonType.Name() }
|
||||
|
||||
// Len returns the number of elements in the array.
|
||||
func (t *ArrayType) Len() int { return int(t.len) }
|
||||
func (t *ArrayType) Len() int { return int(t.len) }
|
||||
|
||||
// Elem returns the type of the array's elements.
|
||||
func (t *ArrayType) Elem() Type { return toType(*t.elem) }
|
||||
func (t *ArrayType) Elem() Type { return toType(*t.elem) }
|
||||
|
||||
// Dir returns the channel direction.
|
||||
func (t *ChanType) Dir() ChanDir { return ChanDir(t.dir) }
|
||||
func (t *ChanType) Dir() ChanDir { return ChanDir(t.dir) }
|
||||
|
||||
// Elem returns the channel's element type.
|
||||
func (t *ChanType) Elem() Type { return toType(*t.elem) }
|
||||
func (t *ChanType) Elem() Type { return toType(*t.elem) }
|
||||
|
||||
func (d ChanDir) String() string {
|
||||
switch d {
|
||||
@ -368,7 +368,7 @@ func (d ChanDir) String() string {
|
||||
case BothDir:
|
||||
return "chan"
|
||||
}
|
||||
return "ChanDir" + strconv.Itoa(int(d));
|
||||
return "ChanDir" + strconv.Itoa(int(d))
|
||||
}
|
||||
|
||||
// In returns the type of the i'th function input parameter.
|
||||
@ -376,60 +376,60 @@ func (t *FuncType) In(i int) Type {
|
||||
if i < 0 || i >= len(t.in) {
|
||||
return nil
|
||||
}
|
||||
return toType(*t.in[i]);
|
||||
return toType(*t.in[i])
|
||||
}
|
||||
|
||||
// NumIn returns the number of input parameters.
|
||||
func (t *FuncType) NumIn() int { return len(t.in) }
|
||||
func (t *FuncType) NumIn() int { return len(t.in) }
|
||||
|
||||
// Out returns the type of the i'th function output parameter.
|
||||
func (t *FuncType) Out(i int) Type {
|
||||
if i < 0 || i >= len(t.out) {
|
||||
return nil
|
||||
}
|
||||
return toType(*t.out[i]);
|
||||
return toType(*t.out[i])
|
||||
}
|
||||
|
||||
// NumOut returns the number of function output parameters.
|
||||
func (t *FuncType) NumOut() int { return len(t.out) }
|
||||
func (t *FuncType) NumOut() int { return len(t.out) }
|
||||
|
||||
// Method returns the i'th interface method.
|
||||
func (t *InterfaceType) Method(i int) (m Method) {
|
||||
if i < 0 || i >= len(t.methods) {
|
||||
return
|
||||
}
|
||||
p := &t.methods[i];
|
||||
m.Name = *p.name;
|
||||
p := &t.methods[i]
|
||||
m.Name = *p.name
|
||||
if p.pkgPath != nil {
|
||||
m.PkgPath = *p.pkgPath
|
||||
}
|
||||
m.Type = toType(*p.typ).(*FuncType);
|
||||
return;
|
||||
m.Type = toType(*p.typ).(*FuncType)
|
||||
return
|
||||
}
|
||||
|
||||
// NumMethod returns the number of interface methods.
|
||||
func (t *InterfaceType) NumMethod() int { return len(t.methods) }
|
||||
func (t *InterfaceType) NumMethod() int { return len(t.methods) }
|
||||
|
||||
// Key returns the map key type.
|
||||
func (t *MapType) Key() Type { return toType(*t.key) }
|
||||
func (t *MapType) Key() Type { return toType(*t.key) }
|
||||
|
||||
// Elem returns the map element type.
|
||||
func (t *MapType) Elem() Type { return toType(*t.elem) }
|
||||
func (t *MapType) Elem() Type { return toType(*t.elem) }
|
||||
|
||||
// Elem returns the pointer element type.
|
||||
func (t *PtrType) Elem() Type { return toType(*t.elem) }
|
||||
func (t *PtrType) Elem() Type { return toType(*t.elem) }
|
||||
|
||||
// Elem returns the type of the slice's elements.
|
||||
func (t *SliceType) Elem() Type { return toType(*t.elem) }
|
||||
func (t *SliceType) Elem() Type { return toType(*t.elem) }
|
||||
|
||||
type StructField struct {
|
||||
PkgPath string; // empty for uppercase Name
|
||||
Name string;
|
||||
Type Type;
|
||||
Tag string;
|
||||
Offset uintptr;
|
||||
Index []int;
|
||||
Anonymous bool;
|
||||
PkgPath string // empty for uppercase Name
|
||||
Name string
|
||||
Type Type
|
||||
Tag string
|
||||
Offset uintptr
|
||||
Index []int
|
||||
Anonymous bool
|
||||
}
|
||||
|
||||
// Field returns the i'th struct field.
|
||||
@ -437,17 +437,17 @@ func (t *StructType) Field(i int) (f StructField) {
|
||||
if i < 0 || i >= len(t.fields) {
|
||||
return
|
||||
}
|
||||
p := t.fields[i];
|
||||
f.Type = toType(*p.typ);
|
||||
p := t.fields[i]
|
||||
f.Type = toType(*p.typ)
|
||||
if p.name != nil {
|
||||
f.Name = *p.name
|
||||
} else {
|
||||
t := f.Type;
|
||||
t := f.Type
|
||||
if pt, ok := t.(*PtrType); ok {
|
||||
t = pt.Elem()
|
||||
}
|
||||
f.Name = t.Name();
|
||||
f.Anonymous = true;
|
||||
f.Name = t.Name()
|
||||
f.Anonymous = true
|
||||
}
|
||||
if p.pkgPath != nil {
|
||||
f.PkgPath = *p.pkgPath
|
||||
@ -455,9 +455,9 @@ func (t *StructType) Field(i int) (f StructField) {
|
||||
if p.tag != nil {
|
||||
f.Tag = *p.tag
|
||||
}
|
||||
f.Offset = p.offset;
|
||||
f.Index = []int{i};
|
||||
return;
|
||||
f.Offset = p.offset
|
||||
f.Index = []int{i}
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(gri): Should there be an error/bool indicator if the index
|
||||
@ -467,45 +467,45 @@ func (t *StructType) Field(i int) (f StructField) {
|
||||
func (t *StructType) FieldByIndex(index []int) (f StructField) {
|
||||
for i, x := range index {
|
||||
if i > 0 {
|
||||
ft := f.Type;
|
||||
ft := f.Type
|
||||
if pt, ok := ft.(*PtrType); ok {
|
||||
ft = pt.Elem()
|
||||
}
|
||||
if st, ok := ft.(*StructType); ok {
|
||||
t = st
|
||||
} else {
|
||||
var f0 StructField;
|
||||
f = f0;
|
||||
return;
|
||||
var f0 StructField
|
||||
f = f0
|
||||
return
|
||||
}
|
||||
}
|
||||
f = t.Field(x);
|
||||
f = t.Field(x)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const inf = 1 << 30 // infinity - no struct has that many nesting levels
|
||||
const inf = 1 << 30 // infinity - no struct has that many nesting levels
|
||||
|
||||
func (t *StructType) fieldByName(name string, mark map[*StructType]bool, depth int) (ff StructField, fd int) {
|
||||
fd = inf; // field depth
|
||||
fd = inf // field depth
|
||||
|
||||
if _, marked := mark[t]; marked {
|
||||
// Struct already seen.
|
||||
return
|
||||
}
|
||||
mark[t] = true;
|
||||
mark[t] = true
|
||||
|
||||
var fi int; // field index
|
||||
n := 0; // number of matching fields at depth fd
|
||||
L: for i, _ := range t.fields {
|
||||
f := t.Field(i);
|
||||
d := inf;
|
||||
var fi int // field index
|
||||
n := 0 // number of matching fields at depth fd
|
||||
L: for i, _ := range t.fields {
|
||||
f := t.Field(i)
|
||||
d := inf
|
||||
switch {
|
||||
case f.Name == name:
|
||||
// Matching top-level field.
|
||||
d = depth
|
||||
case f.Anonymous:
|
||||
ft := f.Type;
|
||||
ft := f.Type
|
||||
if pt, ok := ft.(*PtrType); ok {
|
||||
ft = pt.Elem()
|
||||
}
|
||||
@ -524,12 +524,12 @@ L: for i, _ := range t.fields {
|
||||
switch {
|
||||
case d < fd:
|
||||
// Found field at shallower depth.
|
||||
ff, fi, fd = f, i, d;
|
||||
n = 1;
|
||||
ff, fi, fd = f, i, d
|
||||
n = 1
|
||||
case d == fd:
|
||||
// More than one matching field at the same depth (or d, fd == inf).
|
||||
// Same as no field found at this depth.
|
||||
n++;
|
||||
n++
|
||||
if d == depth {
|
||||
// Impossible to find a field at lower depth.
|
||||
break L
|
||||
@ -542,28 +542,28 @@ L: for i, _ := range t.fields {
|
||||
if len(ff.Index) <= depth {
|
||||
ff.Index = make([]int, depth+1)
|
||||
}
|
||||
ff.Index[depth] = fi;
|
||||
ff.Index[depth] = fi
|
||||
} else {
|
||||
// None or more than one matching field found.
|
||||
fd = inf
|
||||
}
|
||||
|
||||
mark[t] = false, false;
|
||||
return;
|
||||
mark[t] = false, false
|
||||
return
|
||||
}
|
||||
|
||||
// FieldByName returns the struct field with the given name
|
||||
// and a boolean to indicate if the field was found.
|
||||
func (t *StructType) FieldByName(name string) (f StructField, present bool) {
|
||||
if ff, fd := t.fieldByName(name, make(map[*StructType]bool), 0); fd < inf {
|
||||
ff.Index = ff.Index[0 : fd+1];
|
||||
f, present = ff, true;
|
||||
ff.Index = ff.Index[0 : fd+1]
|
||||
f, present = ff, true
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// NumField returns the number of struct fields.
|
||||
func (t *StructType) NumField() int { return len(t.fields) }
|
||||
func (t *StructType) NumField() int { return len(t.fields) }
|
||||
|
||||
// Convert runtime type to reflect type.
|
||||
// Same memory layouts, different method sets.
|
||||
@ -624,15 +624,15 @@ func toType(i interface{}) Type {
|
||||
case *runtime.StructType:
|
||||
return (*StructType)(unsafe.Pointer(v))
|
||||
}
|
||||
panicln("toType", i);
|
||||
panicln("toType", i)
|
||||
}
|
||||
|
||||
// ArrayOrSliceType is the common interface implemented
|
||||
// by both ArrayType and SliceType.
|
||||
type ArrayOrSliceType interface {
|
||||
Type;
|
||||
Elem() Type;
|
||||
Type
|
||||
Elem() Type
|
||||
}
|
||||
|
||||
// Typeof returns the reflection Type of the value in the interface{}.
|
||||
func Typeof(i interface{}) Type { return toType(unsafe.Typeof(i)) }
|
||||
func Typeof(i interface{}) Type { return toType(unsafe.Typeof(i)) }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,9 +5,9 @@
|
||||
package regexp
|
||||
|
||||
import (
|
||||
"os";
|
||||
"strings";
|
||||
"testing";
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var good_re = []string{
|
||||
@ -32,8 +32,8 @@ var good_re = []string{
|
||||
|
||||
// TODO: nice to do this with a map
|
||||
type stringError struct {
|
||||
re string;
|
||||
err os.Error;
|
||||
re string
|
||||
err os.Error
|
||||
}
|
||||
|
||||
var bad_re = []stringError{
|
||||
@ -54,9 +54,9 @@ var bad_re = []stringError{
|
||||
type vec []int
|
||||
|
||||
type tester struct {
|
||||
re string;
|
||||
text string;
|
||||
match vec;
|
||||
re string
|
||||
text string
|
||||
match vec
|
||||
}
|
||||
|
||||
var matches = []tester{
|
||||
@ -100,27 +100,27 @@ var matches = []tester{
|
||||
}
|
||||
|
||||
func compileTest(t *testing.T, expr string, error os.Error) *Regexp {
|
||||
re, err := Compile(expr);
|
||||
re, err := Compile(expr)
|
||||
if err != error {
|
||||
t.Error("compiling `", expr, "`; unexpected error: ", err.String())
|
||||
}
|
||||
return re;
|
||||
return re
|
||||
}
|
||||
|
||||
func printVec(t *testing.T, m []int) {
|
||||
l := len(m);
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
t.Log("\t<no match>")
|
||||
} else {
|
||||
if m[len(m)-1] == -1 {
|
||||
m = m[0 : len(m)-2]
|
||||
}
|
||||
t.Log("\t", m);
|
||||
t.Log("\t", m)
|
||||
}
|
||||
}
|
||||
|
||||
func equal(m1, m2 []int) bool {
|
||||
l := len(m1);
|
||||
l := len(m1)
|
||||
if l != len(m2) {
|
||||
return false
|
||||
}
|
||||
@ -129,11 +129,11 @@ func equal(m1, m2 []int) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
func equalStrings(m1, m2 []string) bool {
|
||||
l := len(m1);
|
||||
l := len(m1)
|
||||
if l != len(m2) {
|
||||
return false
|
||||
}
|
||||
@ -142,28 +142,28 @@ func equalStrings(m1, m2 []string) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
func executeTest(t *testing.T, expr string, str string, match []int) {
|
||||
re := compileTest(t, expr, nil);
|
||||
re := compileTest(t, expr, nil)
|
||||
if re == nil {
|
||||
return
|
||||
}
|
||||
m := re.ExecuteString(str);
|
||||
m := re.ExecuteString(str)
|
||||
if !equal(m, match) {
|
||||
t.Errorf("ExecuteString failure on %#q matching %q:", expr, str);
|
||||
printVec(t, m);
|
||||
t.Log("should be:");
|
||||
printVec(t, match);
|
||||
t.Errorf("ExecuteString failure on %#q matching %q:", expr, str)
|
||||
printVec(t, m)
|
||||
t.Log("should be:")
|
||||
printVec(t, match)
|
||||
}
|
||||
// now try bytes
|
||||
m = re.Execute(strings.Bytes(str));
|
||||
m = re.Execute(strings.Bytes(str))
|
||||
if !equal(m, match) {
|
||||
t.Errorf("Execute failure on %#q matching %q:", expr, str);
|
||||
printVec(t, m);
|
||||
t.Log("should be:");
|
||||
printVec(t, match);
|
||||
t.Errorf("Execute failure on %#q matching %q:", expr, str)
|
||||
printVec(t, m)
|
||||
t.Log("should be:")
|
||||
printVec(t, match)
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,22 +181,22 @@ func TestBadCompile(t *testing.T) {
|
||||
|
||||
func TestExecute(t *testing.T) {
|
||||
for i := 0; i < len(matches); i++ {
|
||||
test := &matches[i];
|
||||
executeTest(t, test.re, test.text, test.match);
|
||||
test := &matches[i]
|
||||
executeTest(t, test.re, test.text, test.match)
|
||||
}
|
||||
}
|
||||
|
||||
func matchTest(t *testing.T, expr string, str string, match []int) {
|
||||
re := compileTest(t, expr, nil);
|
||||
re := compileTest(t, expr, nil)
|
||||
if re == nil {
|
||||
return
|
||||
}
|
||||
m := re.MatchString(str);
|
||||
m := re.MatchString(str)
|
||||
if m != (len(match) > 0) {
|
||||
t.Errorf("MatchString failure on %#q matching %q: %t should be %t", expr, str, m, len(match) > 0)
|
||||
}
|
||||
// now try bytes
|
||||
m = re.Match(strings.Bytes(str));
|
||||
m = re.Match(strings.Bytes(str))
|
||||
if m != (len(match) > 0) {
|
||||
t.Errorf("Match failure on %#q matching %q: %t should be %t", expr, str, m, len(match) > 0)
|
||||
}
|
||||
@ -204,20 +204,20 @@ func matchTest(t *testing.T, expr string, str string, match []int) {
|
||||
|
||||
func TestMatch(t *testing.T) {
|
||||
for i := 0; i < len(matches); i++ {
|
||||
test := &matches[i];
|
||||
matchTest(t, test.re, test.text, test.match);
|
||||
test := &matches[i]
|
||||
matchTest(t, test.re, test.text, test.match)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchStrings(t *testing.T) {
|
||||
for i := 0; i < len(matches); i++ {
|
||||
test := &matches[i];
|
||||
matchTest(t, test.re, test.text, test.match);
|
||||
test := &matches[i]
|
||||
matchTest(t, test.re, test.text, test.match)
|
||||
}
|
||||
}
|
||||
|
||||
func matchFunctionTest(t *testing.T, expr string, str string, match []int) {
|
||||
m, err := MatchString(expr, str);
|
||||
m, err := MatchString(expr, str)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
@ -228,13 +228,13 @@ func matchFunctionTest(t *testing.T, expr string, str string, match []int) {
|
||||
|
||||
func TestMatchFunction(t *testing.T) {
|
||||
for i := 0; i < len(matches); i++ {
|
||||
test := &matches[i];
|
||||
matchFunctionTest(t, test.re, test.text, test.match);
|
||||
test := &matches[i]
|
||||
matchFunctionTest(t, test.re, test.text, test.match)
|
||||
}
|
||||
}
|
||||
|
||||
type ReplaceTest struct {
|
||||
pattern, replacement, input, output string;
|
||||
pattern, replacement, input, output string
|
||||
}
|
||||
|
||||
var replaceTests = []ReplaceTest{
|
||||
@ -301,18 +301,18 @@ var replaceTests = []ReplaceTest{
|
||||
|
||||
func TestReplaceAll(t *testing.T) {
|
||||
for _, tc := range replaceTests {
|
||||
re, err := Compile(tc.pattern);
|
||||
re, err := Compile(tc.pattern)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err);
|
||||
continue;
|
||||
t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
|
||||
continue
|
||||
}
|
||||
actual := re.ReplaceAllString(tc.input, tc.replacement);
|
||||
actual := re.ReplaceAllString(tc.input, tc.replacement)
|
||||
if actual != tc.output {
|
||||
t.Errorf("%q.Replace(%q,%q) = %q; want %q",
|
||||
tc.pattern, tc.input, tc.replacement, actual, tc.output)
|
||||
}
|
||||
// now try bytes
|
||||
actual = string(re.ReplaceAll(strings.Bytes(tc.input), strings.Bytes(tc.replacement)));
|
||||
actual = string(re.ReplaceAll(strings.Bytes(tc.input), strings.Bytes(tc.replacement)))
|
||||
if actual != tc.output {
|
||||
t.Errorf("%q.Replace(%q,%q) = %q; want %q",
|
||||
tc.pattern, tc.input, tc.replacement, actual, tc.output)
|
||||
@ -321,7 +321,7 @@ func TestReplaceAll(t *testing.T) {
|
||||
}
|
||||
|
||||
type QuoteMetaTest struct {
|
||||
pattern, output string;
|
||||
pattern, output string
|
||||
}
|
||||
|
||||
var quoteMetaTests = []QuoteMetaTest{
|
||||
@ -333,25 +333,25 @@ var quoteMetaTests = []QuoteMetaTest{
|
||||
func TestQuoteMeta(t *testing.T) {
|
||||
for _, tc := range quoteMetaTests {
|
||||
// Verify that QuoteMeta returns the expected string.
|
||||
quoted := QuoteMeta(tc.pattern);
|
||||
quoted := QuoteMeta(tc.pattern)
|
||||
if quoted != tc.output {
|
||||
t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
|
||||
tc.pattern, quoted, tc.output);
|
||||
continue;
|
||||
tc.pattern, quoted, tc.output)
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify that the quoted string is in fact treated as expected
|
||||
// by Compile -- i.e. that it matches the original, unquoted string.
|
||||
if tc.pattern != "" {
|
||||
re, err := Compile(quoted);
|
||||
re, err := Compile(quoted)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err);
|
||||
continue;
|
||||
t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
|
||||
continue
|
||||
}
|
||||
src := "abc" + tc.pattern + "def";
|
||||
repl := "xyz";
|
||||
replaced := re.ReplaceAllString(src, repl);
|
||||
expected := "abcxyzdef";
|
||||
src := "abc" + tc.pattern + "def"
|
||||
repl := "xyz"
|
||||
replaced := re.ReplaceAllString(src, repl)
|
||||
expected := "abcxyzdef"
|
||||
if replaced != expected {
|
||||
t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
|
||||
tc.pattern, src, repl, replaced, expected)
|
||||
@ -361,11 +361,11 @@ func TestQuoteMeta(t *testing.T) {
|
||||
}
|
||||
|
||||
type matchCase struct {
|
||||
matchfunc string;
|
||||
input string;
|
||||
n int;
|
||||
regexp string;
|
||||
expected []string;
|
||||
matchfunc string
|
||||
input string
|
||||
n int
|
||||
regexp string
|
||||
expected []string
|
||||
}
|
||||
|
||||
var matchCases = []matchCase{
|
||||
@ -392,90 +392,90 @@ func printStringSlice(t *testing.T, s []string) {
|
||||
}
|
||||
|
||||
func TestAllMatches(t *testing.T) {
|
||||
ch := make(chan matchCase);
|
||||
ch := make(chan matchCase)
|
||||
go func() {
|
||||
for _, c := range matchCases {
|
||||
ch <- c;
|
||||
ch <- c
|
||||
stringCase := matchCase{
|
||||
"string" + c.matchfunc,
|
||||
c.input,
|
||||
c.n,
|
||||
c.regexp,
|
||||
c.expected,
|
||||
};
|
||||
ch <- stringCase;
|
||||
}
|
||||
ch <- stringCase
|
||||
}
|
||||
close(ch);
|
||||
}();
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
for c := range ch {
|
||||
var result []string;
|
||||
re, _ := Compile(c.regexp);
|
||||
var result []string
|
||||
re, _ := Compile(c.regexp)
|
||||
|
||||
switch c.matchfunc {
|
||||
case "matchit":
|
||||
result = make([]string, len(c.input)+1);
|
||||
i := 0;
|
||||
b := strings.Bytes(c.input);
|
||||
result = make([]string, len(c.input)+1)
|
||||
i := 0
|
||||
b := strings.Bytes(c.input)
|
||||
for match := range re.AllMatchesIter(b, c.n) {
|
||||
result[i] = string(match);
|
||||
i++;
|
||||
result[i] = string(match)
|
||||
i++
|
||||
}
|
||||
result = result[0:i];
|
||||
result = result[0:i]
|
||||
case "stringmatchit":
|
||||
result = make([]string, len(c.input)+1);
|
||||
i := 0;
|
||||
result = make([]string, len(c.input)+1)
|
||||
i := 0
|
||||
for match := range re.AllMatchesStringIter(c.input, c.n) {
|
||||
result[i] = match;
|
||||
i++;
|
||||
result[i] = match
|
||||
i++
|
||||
}
|
||||
result = result[0:i];
|
||||
result = result[0:i]
|
||||
case "match":
|
||||
result = make([]string, len(c.input)+1);
|
||||
b := strings.Bytes(c.input);
|
||||
i := 0;
|
||||
result = make([]string, len(c.input)+1)
|
||||
b := strings.Bytes(c.input)
|
||||
i := 0
|
||||
for _, match := range re.AllMatches(b, c.n) {
|
||||
result[i] = string(match);
|
||||
i++;
|
||||
result[i] = string(match)
|
||||
i++
|
||||
}
|
||||
result = result[0:i];
|
||||
result = result[0:i]
|
||||
case "stringmatch":
|
||||
result = re.AllMatchesString(c.input, c.n)
|
||||
}
|
||||
|
||||
if !equalStrings(result, c.expected) {
|
||||
t.Errorf("testing '%s'.%s('%s', %d), expected: ",
|
||||
c.regexp, c.matchfunc, c.input, c.n);
|
||||
printStringSlice(t, c.expected);
|
||||
t.Log("got: ");
|
||||
printStringSlice(t, result);
|
||||
t.Log("\n");
|
||||
c.regexp, c.matchfunc, c.input, c.n)
|
||||
printStringSlice(t, c.expected)
|
||||
t.Log("got: ")
|
||||
printStringSlice(t, result)
|
||||
t.Log("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLiteral(b *testing.B) {
|
||||
x := strings.Repeat("x", 50);
|
||||
b.StopTimer();
|
||||
re, _ := Compile(x);
|
||||
b.StartTimer();
|
||||
x := strings.Repeat("x", 50)
|
||||
b.StopTimer()
|
||||
re, _ := Compile(x)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if !re.MatchString(x) {
|
||||
println("no match!");
|
||||
break;
|
||||
println("no match!")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNotLiteral(b *testing.B) {
|
||||
x := strings.Repeat("x", 49);
|
||||
b.StopTimer();
|
||||
re, _ := Compile("^" + x);
|
||||
b.StartTimer();
|
||||
x := strings.Repeat("x", 49)
|
||||
b.StopTimer()
|
||||
re, _ := Compile("^" + x)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if !re.MatchString(x) {
|
||||
println("no match!");
|
||||
break;
|
||||
println("no match!")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,84 +5,84 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"bufio";
|
||||
"gob";
|
||||
"http";
|
||||
"io";
|
||||
"log";
|
||||
"net";
|
||||
"os";
|
||||
"sync";
|
||||
"bufio"
|
||||
"gob"
|
||||
"http"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Call represents an active RPC.
|
||||
type Call struct {
|
||||
ServiceMethod string; // The name of the service and method to call.
|
||||
Args interface{}; // The argument to the function (*struct).
|
||||
Reply interface{}; // The reply from the function (*struct).
|
||||
Error os.Error; // After completion, the error status.
|
||||
Done chan *Call; // Strobes when call is complete; value is the error status.
|
||||
seq uint64;
|
||||
ServiceMethod string // The name of the service and method to call.
|
||||
Args interface{} // The argument to the function (*struct).
|
||||
Reply interface{} // The reply from the function (*struct).
|
||||
Error os.Error // After completion, the error status.
|
||||
Done chan *Call // Strobes when call is complete; value is the error status.
|
||||
seq uint64
|
||||
}
|
||||
|
||||
// Client represents an RPC Client.
|
||||
// There may be multiple outstanding Calls associated
|
||||
// with a single Client.
|
||||
type Client struct {
|
||||
mutex sync.Mutex; // protects pending, seq
|
||||
shutdown os.Error; // non-nil if the client is shut down
|
||||
sending sync.Mutex;
|
||||
seq uint64;
|
||||
conn io.ReadWriteCloser;
|
||||
enc *gob.Encoder;
|
||||
dec *gob.Decoder;
|
||||
pending map[uint64]*Call;
|
||||
mutex sync.Mutex // protects pending, seq
|
||||
shutdown os.Error // non-nil if the client is shut down
|
||||
sending sync.Mutex
|
||||
seq uint64
|
||||
conn io.ReadWriteCloser
|
||||
enc *gob.Encoder
|
||||
dec *gob.Decoder
|
||||
pending map[uint64]*Call
|
||||
}
|
||||
|
||||
func (client *Client) send(c *Call) {
|
||||
// Register this call.
|
||||
client.mutex.Lock();
|
||||
client.mutex.Lock()
|
||||
if client.shutdown != nil {
|
||||
c.Error = client.shutdown;
|
||||
client.mutex.Unlock();
|
||||
_ = c.Done <- c; // do not block
|
||||
return;
|
||||
c.Error = client.shutdown
|
||||
client.mutex.Unlock()
|
||||
_ = c.Done <- c // do not block
|
||||
return
|
||||
}
|
||||
c.seq = client.seq;
|
||||
client.seq++;
|
||||
client.pending[c.seq] = c;
|
||||
client.mutex.Unlock();
|
||||
c.seq = client.seq
|
||||
client.seq++
|
||||
client.pending[c.seq] = c
|
||||
client.mutex.Unlock()
|
||||
|
||||
// Encode and send the request.
|
||||
request := new(Request);
|
||||
client.sending.Lock();
|
||||
request.Seq = c.seq;
|
||||
request.ServiceMethod = c.ServiceMethod;
|
||||
client.enc.Encode(request);
|
||||
err := client.enc.Encode(c.Args);
|
||||
request := new(Request)
|
||||
client.sending.Lock()
|
||||
request.Seq = c.seq
|
||||
request.ServiceMethod = c.ServiceMethod
|
||||
client.enc.Encode(request)
|
||||
err := client.enc.Encode(c.Args)
|
||||
if err != nil {
|
||||
panicln("rpc: client encode error:", err.String())
|
||||
}
|
||||
client.sending.Unlock();
|
||||
client.sending.Unlock()
|
||||
}
|
||||
|
||||
func (client *Client) input() {
|
||||
var err os.Error;
|
||||
var err os.Error
|
||||
for err == nil {
|
||||
response := new(Response);
|
||||
err = client.dec.Decode(response);
|
||||
response := new(Response)
|
||||
err = client.dec.Decode(response)
|
||||
if err != nil {
|
||||
if err == os.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
seq := response.Seq;
|
||||
client.mutex.Lock();
|
||||
c := client.pending[seq];
|
||||
client.pending[seq] = c, false;
|
||||
client.mutex.Unlock();
|
||||
err = client.dec.Decode(c.Reply);
|
||||
seq := response.Seq
|
||||
client.mutex.Lock()
|
||||
c := client.pending[seq]
|
||||
client.pending[seq] = c, false
|
||||
client.mutex.Unlock()
|
||||
err = client.dec.Decode(c.Reply)
|
||||
// Empty strings should turn into nil os.Errors
|
||||
if response.Error != "" {
|
||||
c.Error = os.ErrorString(response.Error)
|
||||
@ -91,59 +91,59 @@ func (client *Client) input() {
|
||||
}
|
||||
// We don't want to block here. It is the caller's responsibility to make
|
||||
// sure the channel has enough buffer space. See comment in Go().
|
||||
_ = c.Done <- c; // do not block
|
||||
_ = c.Done <- c // do not block
|
||||
}
|
||||
// Terminate pending calls.
|
||||
client.mutex.Lock();
|
||||
client.shutdown = err;
|
||||
client.mutex.Lock()
|
||||
client.shutdown = err
|
||||
for _, call := range client.pending {
|
||||
call.Error = err;
|
||||
_ = call.Done <- call; // do not block
|
||||
call.Error = err
|
||||
_ = call.Done <- call // do not block
|
||||
}
|
||||
client.mutex.Unlock();
|
||||
log.Stderr("rpc: client protocol error:", err);
|
||||
client.mutex.Unlock()
|
||||
log.Stderr("rpc: client protocol error:", err)
|
||||
}
|
||||
|
||||
// NewClient returns a new Client to handle requests to the
|
||||
// set of services at the other end of the connection.
|
||||
func NewClient(conn io.ReadWriteCloser) *Client {
|
||||
client := new(Client);
|
||||
client.conn = conn;
|
||||
client.enc = gob.NewEncoder(conn);
|
||||
client.dec = gob.NewDecoder(conn);
|
||||
client.pending = make(map[uint64]*Call);
|
||||
go client.input();
|
||||
return client;
|
||||
client := new(Client)
|
||||
client.conn = conn
|
||||
client.enc = gob.NewEncoder(conn)
|
||||
client.dec = gob.NewDecoder(conn)
|
||||
client.pending = make(map[uint64]*Call)
|
||||
go client.input()
|
||||
return client
|
||||
}
|
||||
|
||||
// DialHTTP connects to an HTTP RPC server at the specified network address.
|
||||
func DialHTTP(network, address string) (*Client, os.Error) {
|
||||
conn, err := net.Dial(network, "", address);
|
||||
conn, err := net.Dial(network, "", address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
io.WriteString(conn, "CONNECT "+rpcPath+" HTTP/1.0\n\n");
|
||||
io.WriteString(conn, "CONNECT "+rpcPath+" HTTP/1.0\n\n")
|
||||
|
||||
// Require successful HTTP response
|
||||
// before switching to RPC protocol.
|
||||
resp, err := http.ReadResponse(bufio.NewReader(conn));
|
||||
resp, err := http.ReadResponse(bufio.NewReader(conn))
|
||||
if err == nil && resp.Status == connected {
|
||||
return NewClient(conn), nil
|
||||
}
|
||||
if err == nil {
|
||||
err = os.ErrorString("unexpected HTTP response: " + resp.Status)
|
||||
}
|
||||
conn.Close();
|
||||
return nil, &net.OpError{"dial-http", network + " " + address, nil, err};
|
||||
conn.Close()
|
||||
return nil, &net.OpError{"dial-http", network + " " + address, nil, err}
|
||||
}
|
||||
|
||||
// Dial connects to an RPC server at the specified network address.
|
||||
func Dial(network, address string) (*Client, os.Error) {
|
||||
conn, err := net.Dial(network, "", address);
|
||||
conn, err := net.Dial(network, "", address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewClient(conn), nil;
|
||||
return NewClient(conn), nil
|
||||
}
|
||||
|
||||
// Go invokes the function asynchronously. It returns the Call structure representing
|
||||
@ -151,12 +151,12 @@ func Dial(network, address string) (*Client, os.Error) {
|
||||
// the same Call object. If done is nil, Go will allocate a new channel.
|
||||
// If non-nil, done must be buffered or Go will deliberately crash.
|
||||
func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call {
|
||||
c := new(Call);
|
||||
c.ServiceMethod = serviceMethod;
|
||||
c.Args = args;
|
||||
c.Reply = reply;
|
||||
c := new(Call)
|
||||
c.ServiceMethod = serviceMethod
|
||||
c.Args = args
|
||||
c.Reply = reply
|
||||
if done == nil {
|
||||
done = make(chan *Call, 10) // buffered.
|
||||
done = make(chan *Call, 10) // buffered.
|
||||
} else {
|
||||
// If caller passes done != nil, it must arrange that
|
||||
// done has enough buffer for the number of simultaneous
|
||||
@ -166,14 +166,14 @@ func (client *Client) Go(serviceMethod string, args interface{}, reply interface
|
||||
log.Crash("rpc: done channel is unbuffered")
|
||||
}
|
||||
}
|
||||
c.Done = done;
|
||||
c.Done = done
|
||||
if client.shutdown != nil {
|
||||
c.Error = client.shutdown;
|
||||
_ = c.Done <- c; // do not block
|
||||
return c;
|
||||
c.Error = client.shutdown
|
||||
_ = c.Done <- c // do not block
|
||||
return c
|
||||
}
|
||||
client.send(c);
|
||||
return c;
|
||||
client.send(c)
|
||||
return c
|
||||
}
|
||||
|
||||
// Call invokes the named function, waits for it to complete, and returns its error status.
|
||||
@ -181,6 +181,6 @@ func (client *Client) Call(serviceMethod string, args interface{}, reply interfa
|
||||
if client.shutdown != nil {
|
||||
return client.shutdown
|
||||
}
|
||||
call := <-client.Go(serviceMethod, args, reply, nil).Done;
|
||||
return call.Error;
|
||||
call := <-client.Go(serviceMethod, args, reply, nil).Done
|
||||
return call.Error
|
||||
}
|
||||
|
@ -10,10 +10,10 @@ package rpc
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt";
|
||||
"http";
|
||||
"sort";
|
||||
"template";
|
||||
"fmt"
|
||||
"http"
|
||||
"sort"
|
||||
"template"
|
||||
)
|
||||
|
||||
const debugText = `<html>
|
||||
@ -39,47 +39,47 @@ const debugText = `<html>
|
||||
var debug = template.MustParse(debugText, nil)
|
||||
|
||||
type debugMethod struct {
|
||||
m *methodType;
|
||||
name string;
|
||||
m *methodType
|
||||
name string
|
||||
}
|
||||
|
||||
type methodArray []debugMethod
|
||||
|
||||
type debugService struct {
|
||||
s *service;
|
||||
name string;
|
||||
meth methodArray;
|
||||
s *service
|
||||
name string
|
||||
meth methodArray
|
||||
}
|
||||
|
||||
type serviceArray []debugService
|
||||
|
||||
func (s serviceArray) Len() int { return len(s) }
|
||||
func (s serviceArray) Less(i, j int) bool { return s[i].name < s[j].name }
|
||||
func (s serviceArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s serviceArray) Len() int { return len(s) }
|
||||
func (s serviceArray) Less(i, j int) bool { return s[i].name < s[j].name }
|
||||
func (s serviceArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
func (m methodArray) Len() int { return len(m) }
|
||||
func (m methodArray) Less(i, j int) bool { return m[i].name < m[j].name }
|
||||
func (m methodArray) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
|
||||
func (m methodArray) Len() int { return len(m) }
|
||||
func (m methodArray) Less(i, j int) bool { return m[i].name < m[j].name }
|
||||
func (m methodArray) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
|
||||
|
||||
// Runs at /debug/rpc
|
||||
func debugHTTP(c *http.Conn, req *http.Request) {
|
||||
// Build a sorted version of the data.
|
||||
var services = make(serviceArray, len(server.serviceMap));
|
||||
i := 0;
|
||||
server.Lock();
|
||||
var services = make(serviceArray, len(server.serviceMap))
|
||||
i := 0
|
||||
server.Lock()
|
||||
for sname, service := range server.serviceMap {
|
||||
services[i] = debugService{service, sname, make(methodArray, len(service.method))};
|
||||
j := 0;
|
||||
services[i] = debugService{service, sname, make(methodArray, len(service.method))}
|
||||
j := 0
|
||||
for mname, method := range service.method {
|
||||
services[i].meth[j] = debugMethod{method, mname};
|
||||
j++;
|
||||
services[i].meth[j] = debugMethod{method, mname}
|
||||
j++
|
||||
}
|
||||
sort.Sort(services[i].meth);
|
||||
i++;
|
||||
sort.Sort(services[i].meth)
|
||||
i++
|
||||
}
|
||||
server.Unlock();
|
||||
sort.Sort(services);
|
||||
err := debug.Execute(services, c);
|
||||
server.Unlock()
|
||||
sort.Sort(services)
|
||||
err := debug.Execute(services, c)
|
||||
if err != nil {
|
||||
fmt.Fprintln(c, "rpc: error executing template:", err.String())
|
||||
}
|
||||
|
@ -108,17 +108,17 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"gob";
|
||||
"http";
|
||||
"log";
|
||||
"io";
|
||||
"net";
|
||||
"os";
|
||||
"reflect";
|
||||
"strings";
|
||||
"sync";
|
||||
"unicode";
|
||||
"utf8";
|
||||
"gob"
|
||||
"http"
|
||||
"log"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"utf8"
|
||||
)
|
||||
|
||||
// Precompute the reflect type for os.Error. Can't use os.Error directly
|
||||
@ -127,40 +127,40 @@ var unusedError *os.Error
|
||||
var typeOfOsError = reflect.Typeof(unusedError).(*reflect.PtrType).Elem()
|
||||
|
||||
type methodType struct {
|
||||
sync.Mutex; // protects counters
|
||||
method reflect.Method;
|
||||
argType *reflect.PtrType;
|
||||
replyType *reflect.PtrType;
|
||||
numCalls uint;
|
||||
sync.Mutex // protects counters
|
||||
method reflect.Method
|
||||
argType *reflect.PtrType
|
||||
replyType *reflect.PtrType
|
||||
numCalls uint
|
||||
}
|
||||
|
||||
type service struct {
|
||||
name string; // name of service
|
||||
rcvr reflect.Value; // receiver of methods for the service
|
||||
typ reflect.Type; // type of the receiver
|
||||
method map[string]*methodType; // registered methods
|
||||
name string // name of service
|
||||
rcvr reflect.Value // receiver of methods for the service
|
||||
typ reflect.Type // type of the receiver
|
||||
method map[string]*methodType // registered methods
|
||||
}
|
||||
|
||||
// Request is a header written before every RPC call. It is used internally
|
||||
// but documented here as an aid to debugging, such as when analyzing
|
||||
// network traffic.
|
||||
type Request struct {
|
||||
ServiceMethod string; // format: "Service.Method"
|
||||
Seq uint64; // sequence number chosen by client
|
||||
ServiceMethod string // format: "Service.Method"
|
||||
Seq uint64 // sequence number chosen by client
|
||||
}
|
||||
|
||||
// Response is a header written before every RPC return. It is used internally
|
||||
// but documented here as an aid to debugging, such as when analyzing
|
||||
// network traffic.
|
||||
type Response struct {
|
||||
ServiceMethod string; // echoes that of the Request
|
||||
Seq uint64; // echoes that of the request
|
||||
Error string; // error, if any.
|
||||
ServiceMethod string // echoes that of the Request
|
||||
Seq uint64 // echoes that of the request
|
||||
Error string // error, if any.
|
||||
}
|
||||
|
||||
type serverType struct {
|
||||
sync.Mutex; // protects the serviceMap
|
||||
serviceMap map[string]*service;
|
||||
sync.Mutex // protects the serviceMap
|
||||
serviceMap map[string]*service
|
||||
}
|
||||
|
||||
// This variable is a global whose "public" methods are really private methods
|
||||
@ -170,198 +170,198 @@ var server = &serverType{serviceMap: make(map[string]*service)}
|
||||
|
||||
// Is this a publicly visible - upper case - name?
|
||||
func isPublic(name string) bool {
|
||||
rune, _ := utf8.DecodeRuneInString(name);
|
||||
return unicode.IsUpper(rune);
|
||||
rune, _ := utf8.DecodeRuneInString(name)
|
||||
return unicode.IsUpper(rune)
|
||||
}
|
||||
|
||||
func (server *serverType) register(rcvr interface{}) os.Error {
|
||||
server.Lock();
|
||||
defer server.Unlock();
|
||||
server.Lock()
|
||||
defer server.Unlock()
|
||||
if server.serviceMap == nil {
|
||||
server.serviceMap = make(map[string]*service)
|
||||
}
|
||||
s := new(service);
|
||||
s.typ = reflect.Typeof(rcvr);
|
||||
s.rcvr = reflect.NewValue(rcvr);
|
||||
sname := reflect.Indirect(s.rcvr).Type().Name();
|
||||
s := new(service)
|
||||
s.typ = reflect.Typeof(rcvr)
|
||||
s.rcvr = reflect.NewValue(rcvr)
|
||||
sname := reflect.Indirect(s.rcvr).Type().Name()
|
||||
if sname == "" {
|
||||
log.Exit("rpc: no service name for type", s.typ.String())
|
||||
}
|
||||
if !isPublic(sname) {
|
||||
s := "rpc Register: type " + sname + " is not public";
|
||||
log.Stderr(s);
|
||||
return os.ErrorString(s);
|
||||
s := "rpc Register: type " + sname + " is not public"
|
||||
log.Stderr(s)
|
||||
return os.ErrorString(s)
|
||||
}
|
||||
if _, present := server.serviceMap[sname]; present {
|
||||
return os.ErrorString("rpc: service already defined: " + sname)
|
||||
}
|
||||
s.name = sname;
|
||||
s.method = make(map[string]*methodType);
|
||||
s.name = sname
|
||||
s.method = make(map[string]*methodType)
|
||||
|
||||
// Install the methods
|
||||
for m := 0; m < s.typ.NumMethod(); m++ {
|
||||
method := s.typ.Method(m);
|
||||
mtype := method.Type;
|
||||
mname := method.Name;
|
||||
method := s.typ.Method(m)
|
||||
mtype := method.Type
|
||||
mname := method.Name
|
||||
if !isPublic(mname) {
|
||||
continue
|
||||
}
|
||||
// Method needs three ins: receiver, *args, *reply.
|
||||
// The args and reply must be structs until gobs are more general.
|
||||
if mtype.NumIn() != 3 {
|
||||
log.Stderr("method", mname, "has wrong number of ins:", mtype.NumIn());
|
||||
continue;
|
||||
log.Stderr("method", mname, "has wrong number of ins:", mtype.NumIn())
|
||||
continue
|
||||
}
|
||||
argType, ok := mtype.In(1).(*reflect.PtrType);
|
||||
argType, ok := mtype.In(1).(*reflect.PtrType)
|
||||
if !ok {
|
||||
log.Stderr(mname, "arg type not a pointer:", mtype.In(1));
|
||||
continue;
|
||||
log.Stderr(mname, "arg type not a pointer:", mtype.In(1))
|
||||
continue
|
||||
}
|
||||
if _, ok := argType.Elem().(*reflect.StructType); !ok {
|
||||
log.Stderr(mname, "arg type not a pointer to a struct:", argType);
|
||||
continue;
|
||||
log.Stderr(mname, "arg type not a pointer to a struct:", argType)
|
||||
continue
|
||||
}
|
||||
replyType, ok := mtype.In(2).(*reflect.PtrType);
|
||||
replyType, ok := mtype.In(2).(*reflect.PtrType)
|
||||
if !ok {
|
||||
log.Stderr(mname, "reply type not a pointer:", mtype.In(2));
|
||||
continue;
|
||||
log.Stderr(mname, "reply type not a pointer:", mtype.In(2))
|
||||
continue
|
||||
}
|
||||
if _, ok := replyType.Elem().(*reflect.StructType); !ok {
|
||||
log.Stderr(mname, "reply type not a pointer to a struct:", replyType);
|
||||
continue;
|
||||
log.Stderr(mname, "reply type not a pointer to a struct:", replyType)
|
||||
continue
|
||||
}
|
||||
if !isPublic(argType.Elem().Name()) {
|
||||
log.Stderr(mname, "argument type not public:", argType);
|
||||
continue;
|
||||
log.Stderr(mname, "argument type not public:", argType)
|
||||
continue
|
||||
}
|
||||
if !isPublic(replyType.Elem().Name()) {
|
||||
log.Stderr(mname, "reply type not public:", replyType);
|
||||
continue;
|
||||
log.Stderr(mname, "reply type not public:", replyType)
|
||||
continue
|
||||
}
|
||||
// Method needs one out: os.Error.
|
||||
if mtype.NumOut() != 1 {
|
||||
log.Stderr("method", mname, "has wrong number of outs:", mtype.NumOut());
|
||||
continue;
|
||||
log.Stderr("method", mname, "has wrong number of outs:", mtype.NumOut())
|
||||
continue
|
||||
}
|
||||
if returnType := mtype.Out(0); returnType != typeOfOsError {
|
||||
log.Stderr("method", mname, "returns", returnType.String(), "not os.Error");
|
||||
continue;
|
||||
log.Stderr("method", mname, "returns", returnType.String(), "not os.Error")
|
||||
continue
|
||||
}
|
||||
s.method[mname] = &methodType{method: method, argType: argType, replyType: replyType};
|
||||
s.method[mname] = &methodType{method: method, argType: argType, replyType: replyType}
|
||||
}
|
||||
|
||||
if len(s.method) == 0 {
|
||||
s := "rpc Register: type " + sname + " has no public methods of suitable type";
|
||||
log.Stderr(s);
|
||||
return os.ErrorString(s);
|
||||
s := "rpc Register: type " + sname + " has no public methods of suitable type"
|
||||
log.Stderr(s)
|
||||
return os.ErrorString(s)
|
||||
}
|
||||
server.serviceMap[s.name] = s;
|
||||
return nil;
|
||||
server.serviceMap[s.name] = s
|
||||
return nil
|
||||
}
|
||||
|
||||
// A value sent as a placeholder for the response when the server receives an invalid request.
|
||||
type InvalidRequest struct {
|
||||
marker int;
|
||||
marker int
|
||||
}
|
||||
|
||||
var invalidRequest = InvalidRequest{1}
|
||||
|
||||
func _new(t *reflect.PtrType) *reflect.PtrValue {
|
||||
v := reflect.MakeZero(t).(*reflect.PtrValue);
|
||||
v.PointTo(reflect.MakeZero(t.Elem()));
|
||||
return v;
|
||||
v := reflect.MakeZero(t).(*reflect.PtrValue)
|
||||
v.PointTo(reflect.MakeZero(t.Elem()))
|
||||
return v
|
||||
}
|
||||
|
||||
func sendResponse(sending *sync.Mutex, req *Request, reply interface{}, enc *gob.Encoder, errmsg string) {
|
||||
resp := new(Response);
|
||||
resp := new(Response)
|
||||
// Encode the response header
|
||||
resp.ServiceMethod = req.ServiceMethod;
|
||||
resp.ServiceMethod = req.ServiceMethod
|
||||
if errmsg != "" {
|
||||
resp.Error = errmsg
|
||||
}
|
||||
resp.Seq = req.Seq;
|
||||
sending.Lock();
|
||||
enc.Encode(resp);
|
||||
resp.Seq = req.Seq
|
||||
sending.Lock()
|
||||
enc.Encode(resp)
|
||||
// Encode the reply value.
|
||||
enc.Encode(reply);
|
||||
sending.Unlock();
|
||||
enc.Encode(reply)
|
||||
sending.Unlock()
|
||||
}
|
||||
|
||||
func (s *service) call(sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, enc *gob.Encoder) {
|
||||
mtype.Lock();
|
||||
mtype.numCalls++;
|
||||
mtype.Unlock();
|
||||
function := mtype.method.Func;
|
||||
mtype.Lock()
|
||||
mtype.numCalls++
|
||||
mtype.Unlock()
|
||||
function := mtype.method.Func
|
||||
// Invoke the method, providing a new value for the reply.
|
||||
returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv});
|
||||
returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
|
||||
// The return value for the method is an os.Error.
|
||||
errInter := returnValues[0].Interface();
|
||||
errmsg := "";
|
||||
errInter := returnValues[0].Interface()
|
||||
errmsg := ""
|
||||
if errInter != nil {
|
||||
errmsg = errInter.(os.Error).String()
|
||||
}
|
||||
sendResponse(sending, req, replyv.Interface(), enc, errmsg);
|
||||
sendResponse(sending, req, replyv.Interface(), enc, errmsg)
|
||||
}
|
||||
|
||||
func (server *serverType) input(conn io.ReadWriteCloser) {
|
||||
dec := gob.NewDecoder(conn);
|
||||
enc := gob.NewEncoder(conn);
|
||||
sending := new(sync.Mutex);
|
||||
dec := gob.NewDecoder(conn)
|
||||
enc := gob.NewEncoder(conn)
|
||||
sending := new(sync.Mutex)
|
||||
for {
|
||||
// Grab the request header.
|
||||
req := new(Request);
|
||||
err := dec.Decode(req);
|
||||
req := new(Request)
|
||||
err := dec.Decode(req)
|
||||
if err != nil {
|
||||
if err == os.EOF || err == io.ErrUnexpectedEOF {
|
||||
log.Stderr("rpc: ", err);
|
||||
break;
|
||||
log.Stderr("rpc: ", err)
|
||||
break
|
||||
}
|
||||
s := "rpc: server cannot decode request: " + err.String();
|
||||
sendResponse(sending, req, invalidRequest, enc, s);
|
||||
continue;
|
||||
s := "rpc: server cannot decode request: " + err.String()
|
||||
sendResponse(sending, req, invalidRequest, enc, s)
|
||||
continue
|
||||
}
|
||||
serviceMethod := strings.Split(req.ServiceMethod, ".", 0);
|
||||
serviceMethod := strings.Split(req.ServiceMethod, ".", 0)
|
||||
if len(serviceMethod) != 2 {
|
||||
s := "rpc: service/method request ill:formed: " + req.ServiceMethod;
|
||||
sendResponse(sending, req, invalidRequest, enc, s);
|
||||
continue;
|
||||
s := "rpc: service/method request ill:formed: " + req.ServiceMethod
|
||||
sendResponse(sending, req, invalidRequest, enc, s)
|
||||
continue
|
||||
}
|
||||
// Look up the request.
|
||||
server.Lock();
|
||||
service, ok := server.serviceMap[serviceMethod[0]];
|
||||
server.Unlock();
|
||||
server.Lock()
|
||||
service, ok := server.serviceMap[serviceMethod[0]]
|
||||
server.Unlock()
|
||||
if !ok {
|
||||
s := "rpc: can't find service " + req.ServiceMethod;
|
||||
sendResponse(sending, req, invalidRequest, enc, s);
|
||||
continue;
|
||||
s := "rpc: can't find service " + req.ServiceMethod
|
||||
sendResponse(sending, req, invalidRequest, enc, s)
|
||||
continue
|
||||
}
|
||||
mtype, ok := service.method[serviceMethod[1]];
|
||||
mtype, ok := service.method[serviceMethod[1]]
|
||||
if !ok {
|
||||
s := "rpc: can't find method " + req.ServiceMethod;
|
||||
sendResponse(sending, req, invalidRequest, enc, s);
|
||||
continue;
|
||||
s := "rpc: can't find method " + req.ServiceMethod
|
||||
sendResponse(sending, req, invalidRequest, enc, s)
|
||||
continue
|
||||
}
|
||||
// Decode the argument value.
|
||||
argv := _new(mtype.argType);
|
||||
replyv := _new(mtype.replyType);
|
||||
err = dec.Decode(argv.Interface());
|
||||
argv := _new(mtype.argType)
|
||||
replyv := _new(mtype.replyType)
|
||||
err = dec.Decode(argv.Interface())
|
||||
if err != nil {
|
||||
log.Stderr("rpc: tearing down", serviceMethod[0], "connection:", err);
|
||||
sendResponse(sending, req, replyv.Interface(), enc, err.String());
|
||||
continue;
|
||||
log.Stderr("rpc: tearing down", serviceMethod[0], "connection:", err)
|
||||
sendResponse(sending, req, replyv.Interface(), enc, err.String())
|
||||
continue
|
||||
}
|
||||
go service.call(sending, mtype, req, argv, replyv, enc);
|
||||
go service.call(sending, mtype, req, argv, replyv, enc)
|
||||
}
|
||||
conn.Close();
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func (server *serverType) accept(lis net.Listener) {
|
||||
for {
|
||||
conn, err := lis.Accept();
|
||||
conn, err := lis.Accept()
|
||||
if err != nil {
|
||||
log.Exit("rpc.Serve: accept:", err.String()) // TODO(r): exit?
|
||||
log.Exit("rpc.Serve: accept:", err.String()) // TODO(r): exit?
|
||||
}
|
||||
go server.input(conn);
|
||||
go server.input(conn)
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,17 +372,17 @@ func (server *serverType) accept(lis net.Listener) {
|
||||
// - one return value of type os.Error
|
||||
// It returns an error if the receiver is not public or has no
|
||||
// suitable methods.
|
||||
func Register(rcvr interface{}) os.Error { return server.register(rcvr) }
|
||||
func Register(rcvr interface{}) os.Error { return server.register(rcvr) }
|
||||
|
||||
// ServeConn runs the server on a single connection. When the connection
|
||||
// completes, service terminates. ServeConn blocks; the caller typically
|
||||
// invokes it in a go statement.
|
||||
func ServeConn(conn io.ReadWriteCloser) { go server.input(conn) }
|
||||
func ServeConn(conn io.ReadWriteCloser) { go server.input(conn) }
|
||||
|
||||
// Accept accepts connections on the listener and serves requests
|
||||
// for each incoming connection. Accept blocks; the caller typically
|
||||
// invokes it in a go statement.
|
||||
func Accept(lis net.Listener) { server.accept(lis) }
|
||||
func Accept(lis net.Listener) { server.accept(lis) }
|
||||
|
||||
// Can connect to RPC service using HTTP CONNECT to rpcPath.
|
||||
var rpcPath string = "/_goRPC_"
|
||||
@ -391,23 +391,23 @@ var connected = "200 Connected to Go RPC"
|
||||
|
||||
func serveHTTP(c *http.Conn, req *http.Request) {
|
||||
if req.Method != "CONNECT" {
|
||||
c.SetHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
c.WriteHeader(http.StatusMethodNotAllowed);
|
||||
io.WriteString(c, "405 must CONNECT to "+rpcPath+"\n");
|
||||
return;
|
||||
c.SetHeader("Content-Type", "text/plain; charset=utf-8")
|
||||
c.WriteHeader(http.StatusMethodNotAllowed)
|
||||
io.WriteString(c, "405 must CONNECT to "+rpcPath+"\n")
|
||||
return
|
||||
}
|
||||
conn, _, err := c.Hijack();
|
||||
conn, _, err := c.Hijack()
|
||||
if err != nil {
|
||||
log.Stderr("rpc hijacking ", c.RemoteAddr, ": ", err.String());
|
||||
return;
|
||||
log.Stderr("rpc hijacking ", c.RemoteAddr, ": ", err.String())
|
||||
return
|
||||
}
|
||||
io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n");
|
||||
server.input(conn);
|
||||
io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
|
||||
server.input(conn)
|
||||
}
|
||||
|
||||
// HandleHTTP registers an HTTP handler for RPC messages.
|
||||
// It is still necessary to invoke http.Serve(), typically in a go statement.
|
||||
func HandleHTTP() {
|
||||
http.Handle(rpcPath, http.HandlerFunc(serveHTTP));
|
||||
http.Handle(debugPath, http.HandlerFunc(debugHTTP));
|
||||
http.Handle(rpcPath, http.HandlerFunc(serveHTTP))
|
||||
http.Handle(debugPath, http.HandlerFunc(debugHTTP))
|
||||
}
|
||||
|
@ -5,13 +5,13 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"http";
|
||||
"log";
|
||||
"net";
|
||||
"once";
|
||||
"os";
|
||||
"strings";
|
||||
"testing";
|
||||
"http"
|
||||
"log"
|
||||
"net"
|
||||
"once"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var serverAddr string
|
||||
@ -21,31 +21,31 @@ const second = 1e9
|
||||
|
||||
|
||||
type Args struct {
|
||||
A, B int;
|
||||
A, B int
|
||||
}
|
||||
|
||||
type Reply struct {
|
||||
C int;
|
||||
C int
|
||||
}
|
||||
|
||||
type Arith int
|
||||
|
||||
func (t *Arith) Add(args *Args, reply *Reply) os.Error {
|
||||
reply.C = args.A + args.B;
|
||||
return nil;
|
||||
reply.C = args.A + args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Arith) Mul(args *Args, reply *Reply) os.Error {
|
||||
reply.C = args.A * args.B;
|
||||
return nil;
|
||||
reply.C = args.A * args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Arith) Div(args *Args, reply *Reply) os.Error {
|
||||
if args.B == 0 {
|
||||
return os.ErrorString("divide by zero")
|
||||
}
|
||||
reply.C = args.A / args.B;
|
||||
return nil;
|
||||
reply.C = args.A / args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Arith) Error(args *Args, reply *Reply) os.Error {
|
||||
@ -53,39 +53,39 @@ func (t *Arith) Error(args *Args, reply *Reply) os.Error {
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
Register(new(Arith));
|
||||
Register(new(Arith))
|
||||
|
||||
l, e := net.Listen("tcp", ":0"); // any available address
|
||||
l, e := net.Listen("tcp", ":0") // any available address
|
||||
if e != nil {
|
||||
log.Exitf("net.Listen tcp :0: %v", e)
|
||||
}
|
||||
serverAddr = l.Addr().String();
|
||||
log.Stderr("Test RPC server listening on ", serverAddr);
|
||||
go Accept(l);
|
||||
serverAddr = l.Addr().String()
|
||||
log.Stderr("Test RPC server listening on ", serverAddr)
|
||||
go Accept(l)
|
||||
|
||||
HandleHTTP();
|
||||
l, e = net.Listen("tcp", ":0"); // any available address
|
||||
HandleHTTP()
|
||||
l, e = net.Listen("tcp", ":0") // any available address
|
||||
if e != nil {
|
||||
log.Stderrf("net.Listen tcp :0: %v", e);
|
||||
os.Exit(1);
|
||||
log.Stderrf("net.Listen tcp :0: %v", e)
|
||||
os.Exit(1)
|
||||
}
|
||||
httpServerAddr = l.Addr().String();
|
||||
log.Stderr("Test HTTP RPC server listening on ", httpServerAddr);
|
||||
go http.Serve(l, nil);
|
||||
httpServerAddr = l.Addr().String()
|
||||
log.Stderr("Test HTTP RPC server listening on ", httpServerAddr)
|
||||
go http.Serve(l, nil)
|
||||
}
|
||||
|
||||
func TestRPC(t *testing.T) {
|
||||
once.Do(startServer);
|
||||
once.Do(startServer)
|
||||
|
||||
client, err := Dial("tcp", serverAddr);
|
||||
client, err := Dial("tcp", serverAddr)
|
||||
if err != nil {
|
||||
t.Fatal("dialing", err)
|
||||
}
|
||||
|
||||
// Synchronous calls
|
||||
args := &Args{7, 8};
|
||||
reply := new(Reply);
|
||||
err = client.Call("Arith.Add", args, reply);
|
||||
args := &Args{7, 8}
|
||||
reply := new(Reply)
|
||||
err = client.Call("Arith.Add", args, reply)
|
||||
if err != nil {
|
||||
t.Errorf("Add: expected no error but got string %q", err.String())
|
||||
}
|
||||
@ -93,9 +93,9 @@ func TestRPC(t *testing.T) {
|
||||
t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
|
||||
}
|
||||
|
||||
args = &Args{7, 8};
|
||||
reply = new(Reply);
|
||||
err = client.Call("Arith.Mul", args, reply);
|
||||
args = &Args{7, 8}
|
||||
reply = new(Reply)
|
||||
err = client.Call("Arith.Mul", args, reply)
|
||||
if err != nil {
|
||||
t.Errorf("Mul: expected no error but got string %q", err.String())
|
||||
}
|
||||
@ -104,13 +104,13 @@ func TestRPC(t *testing.T) {
|
||||
}
|
||||
|
||||
// Out of order.
|
||||
args = &Args{7, 8};
|
||||
mulReply := new(Reply);
|
||||
mulCall := client.Go("Arith.Mul", args, mulReply, nil);
|
||||
addReply := new(Reply);
|
||||
addCall := client.Go("Arith.Add", args, addReply, nil);
|
||||
args = &Args{7, 8}
|
||||
mulReply := new(Reply)
|
||||
mulCall := client.Go("Arith.Mul", args, mulReply, nil)
|
||||
addReply := new(Reply)
|
||||
addCall := client.Go("Arith.Add", args, addReply, nil)
|
||||
|
||||
addCall = <-addCall.Done;
|
||||
addCall = <-addCall.Done
|
||||
if addCall.Error != nil {
|
||||
t.Errorf("Add: expected no error but got string %q", addCall.Error.String())
|
||||
}
|
||||
@ -118,7 +118,7 @@ func TestRPC(t *testing.T) {
|
||||
t.Errorf("Add: expected %d got %d", addReply.C, args.A+args.B)
|
||||
}
|
||||
|
||||
mulCall = <-mulCall.Done;
|
||||
mulCall = <-mulCall.Done
|
||||
if mulCall.Error != nil {
|
||||
t.Errorf("Mul: expected no error but got string %q", mulCall.Error.String())
|
||||
}
|
||||
@ -127,9 +127,9 @@ func TestRPC(t *testing.T) {
|
||||
}
|
||||
|
||||
// Error test
|
||||
args = &Args{7, 0};
|
||||
reply = new(Reply);
|
||||
err = client.Call("Arith.Div", args, reply);
|
||||
args = &Args{7, 0}
|
||||
reply = new(Reply)
|
||||
err = client.Call("Arith.Div", args, reply)
|
||||
// expect an error: zero divide
|
||||
if err == nil {
|
||||
t.Error("Div: expected error")
|
||||
@ -139,17 +139,17 @@ func TestRPC(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHTTPRPC(t *testing.T) {
|
||||
once.Do(startServer);
|
||||
once.Do(startServer)
|
||||
|
||||
client, err := DialHTTP("tcp", httpServerAddr);
|
||||
client, err := DialHTTP("tcp", httpServerAddr)
|
||||
if err != nil {
|
||||
t.Fatal("dialing", err)
|
||||
}
|
||||
|
||||
// Synchronous calls
|
||||
args := &Args{7, 8};
|
||||
reply := new(Reply);
|
||||
err = client.Call("Arith.Add", args, reply);
|
||||
args := &Args{7, 8}
|
||||
reply := new(Reply)
|
||||
err = client.Call("Arith.Add", args, reply)
|
||||
if err != nil {
|
||||
t.Errorf("Add: expected no error but got string %q", err.String())
|
||||
}
|
||||
@ -159,18 +159,18 @@ func TestHTTPRPC(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCheckUnknownService(t *testing.T) {
|
||||
once.Do(startServer);
|
||||
once.Do(startServer)
|
||||
|
||||
conn, err := net.Dial("tcp", "", serverAddr);
|
||||
conn, err := net.Dial("tcp", "", serverAddr)
|
||||
if err != nil {
|
||||
t.Fatal("dialing:", err)
|
||||
}
|
||||
|
||||
client := NewClient(conn);
|
||||
client := NewClient(conn)
|
||||
|
||||
args := &Args{7, 8};
|
||||
reply := new(Reply);
|
||||
err = client.Call("Unknown.Add", args, reply);
|
||||
args := &Args{7, 8}
|
||||
reply := new(Reply)
|
||||
err = client.Call("Unknown.Add", args, reply)
|
||||
if err == nil {
|
||||
t.Error("expected error calling unknown service")
|
||||
} else if strings.Index(err.String(), "service") < 0 {
|
||||
@ -179,18 +179,18 @@ func TestCheckUnknownService(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCheckUnknownMethod(t *testing.T) {
|
||||
once.Do(startServer);
|
||||
once.Do(startServer)
|
||||
|
||||
conn, err := net.Dial("tcp", "", serverAddr);
|
||||
conn, err := net.Dial("tcp", "", serverAddr)
|
||||
if err != nil {
|
||||
t.Fatal("dialing:", err)
|
||||
}
|
||||
|
||||
client := NewClient(conn);
|
||||
client := NewClient(conn)
|
||||
|
||||
args := &Args{7, 8};
|
||||
reply := new(Reply);
|
||||
err = client.Call("Arith.Unknown", args, reply);
|
||||
args := &Args{7, 8}
|
||||
reply := new(Reply)
|
||||
err = client.Call("Arith.Unknown", args, reply)
|
||||
if err == nil {
|
||||
t.Error("expected error calling unknown service")
|
||||
} else if strings.Index(err.String(), "method") < 0 {
|
||||
@ -199,17 +199,17 @@ func TestCheckUnknownMethod(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCheckBadType(t *testing.T) {
|
||||
once.Do(startServer);
|
||||
once.Do(startServer)
|
||||
|
||||
conn, err := net.Dial("tcp", "", serverAddr);
|
||||
conn, err := net.Dial("tcp", "", serverAddr)
|
||||
if err != nil {
|
||||
t.Fatal("dialing:", err)
|
||||
}
|
||||
|
||||
client := NewClient(conn);
|
||||
client := NewClient(conn)
|
||||
|
||||
reply := new(Reply);
|
||||
err = client.Call("Arith.Add", reply, reply); // args, reply would be the correct thing to use
|
||||
reply := new(Reply)
|
||||
err = client.Call("Arith.Add", reply, reply) // args, reply would be the correct thing to use
|
||||
if err == nil {
|
||||
t.Error("expected error calling Arith.Add with wrong arg type")
|
||||
} else if strings.Index(err.String(), "type") < 0 {
|
||||
@ -246,7 +246,7 @@ func (t *Bad) ReplyNotPublic(args *Args, reply *local) os.Error {
|
||||
|
||||
// Check that registration handles lots of bad methods and a type with no suitable methods.
|
||||
func TestRegistrationError(t *testing.T) {
|
||||
err := Register(new(Bad));
|
||||
err := Register(new(Bad))
|
||||
if err == nil {
|
||||
t.Errorf("expected error registering bad type")
|
||||
}
|
||||
|
@ -26,56 +26,56 @@ type Type interface{}
|
||||
// All types begin with a few common fields needed for
|
||||
// the interface runtime.
|
||||
type commonType struct {
|
||||
size uintptr; // size in bytes
|
||||
hash uint32; // hash of type; avoids computation in hash tables
|
||||
alg uint8; // algorithm for copy+hash+cmp (../runtime/runtime.h:/AMEM)
|
||||
align uint8; // alignment of variable with this type
|
||||
fieldAlign uint8; // alignment of struct field with this type
|
||||
kind uint8; // enumeration for C
|
||||
string *string; // string form; unnecessary but undeniably useful
|
||||
*uncommonType; // (relatively) uncommon fields
|
||||
size uintptr // size in bytes
|
||||
hash uint32 // hash of type; avoids computation in hash tables
|
||||
alg uint8 // algorithm for copy+hash+cmp (../runtime/runtime.h:/AMEM)
|
||||
align uint8 // alignment of variable with this type
|
||||
fieldAlign uint8 // alignment of struct field with this type
|
||||
kind uint8 // enumeration for C
|
||||
string *string // string form; unnecessary but undeniably useful
|
||||
*uncommonType // (relatively) uncommon fields
|
||||
}
|
||||
|
||||
// Values for commonType.kind.
|
||||
const (
|
||||
kindBool = 1 + iota;
|
||||
kindInt;
|
||||
kindInt8;
|
||||
kindInt16;
|
||||
kindInt32;
|
||||
kindInt64;
|
||||
kindUint;
|
||||
kindUint8;
|
||||
kindUint16;
|
||||
kindUint32;
|
||||
kindUint64;
|
||||
kindUintptr;
|
||||
kindFloat;
|
||||
kindFloat32;
|
||||
kindFloat64;
|
||||
kindArray;
|
||||
kindChan;
|
||||
kindDotDotDot;
|
||||
kindFunc;
|
||||
kindInterface;
|
||||
kindMap;
|
||||
kindPtr;
|
||||
kindSlice;
|
||||
kindString;
|
||||
kindStruct;
|
||||
kindUnsafePointer;
|
||||
kindBool = 1 + iota
|
||||
kindInt
|
||||
kindInt8
|
||||
kindInt16
|
||||
kindInt32
|
||||
kindInt64
|
||||
kindUint
|
||||
kindUint8
|
||||
kindUint16
|
||||
kindUint32
|
||||
kindUint64
|
||||
kindUintptr
|
||||
kindFloat
|
||||
kindFloat32
|
||||
kindFloat64
|
||||
kindArray
|
||||
kindChan
|
||||
kindDotDotDot
|
||||
kindFunc
|
||||
kindInterface
|
||||
kindMap
|
||||
kindPtr
|
||||
kindSlice
|
||||
kindString
|
||||
kindStruct
|
||||
kindUnsafePointer
|
||||
|
||||
kindNoPointers = 1 << 7; // OR'ed into kind
|
||||
kindNoPointers = 1 << 7 // OR'ed into kind
|
||||
)
|
||||
|
||||
// Method on non-interface type
|
||||
type method struct {
|
||||
hash uint32; // hash of name + pkg + typ
|
||||
name *string; // name of method
|
||||
pkgPath *string; // nil for exported Names; otherwise import path
|
||||
typ *Type; // .(*FuncType) underneath
|
||||
ifn unsafe.Pointer; // fn used in interface call (one-word receiver)
|
||||
tfn unsafe.Pointer; // fn used for normal method call
|
||||
hash uint32 // hash of name + pkg + typ
|
||||
name *string // name of method
|
||||
pkgPath *string // nil for exported Names; otherwise import path
|
||||
typ *Type // .(*FuncType) underneath
|
||||
ifn unsafe.Pointer // fn used in interface call (one-word receiver)
|
||||
tfn unsafe.Pointer // fn used for normal method call
|
||||
}
|
||||
|
||||
// uncommonType is present only for types with names or methods
|
||||
@ -83,9 +83,9 @@ type method struct {
|
||||
// Using a pointer to this struct reduces the overall size required
|
||||
// to describe an unnamed type with no methods.
|
||||
type uncommonType struct {
|
||||
name *string; // name of type
|
||||
pkgPath *string; // import path; nil for built-in types like int, string
|
||||
methods []method; // methods associated with type
|
||||
name *string // name of type
|
||||
pkgPath *string // import path; nil for built-in types like int, string
|
||||
methods []method // methods associated with type
|
||||
}
|
||||
|
||||
// BoolType represents a boolean type.
|
||||
@ -145,91 +145,91 @@ type UnsafePointerType commonType
|
||||
|
||||
// ArrayType represents a fixed array type.
|
||||
type ArrayType struct {
|
||||
commonType;
|
||||
elem *Type; // array element type
|
||||
len uintptr;
|
||||
commonType
|
||||
elem *Type // array element type
|
||||
len uintptr
|
||||
}
|
||||
|
||||
// SliceType represents a slice type.
|
||||
type SliceType struct {
|
||||
commonType;
|
||||
elem *Type; // slice element type
|
||||
commonType
|
||||
elem *Type // slice element type
|
||||
}
|
||||
|
||||
// ChanDir represents a channel type's direction.
|
||||
type ChanDir int
|
||||
|
||||
const (
|
||||
RecvDir ChanDir = 1 << iota; // <-chan
|
||||
SendDir; // chan<-
|
||||
BothDir = RecvDir | SendDir; // chan
|
||||
RecvDir ChanDir = 1 << iota // <-chan
|
||||
SendDir // chan<-
|
||||
BothDir = RecvDir | SendDir // chan
|
||||
)
|
||||
|
||||
// ChanType represents a channel type.
|
||||
type ChanType struct {
|
||||
commonType;
|
||||
elem *Type; // channel element type
|
||||
dir uintptr; // channel direction (ChanDir)
|
||||
commonType
|
||||
elem *Type // channel element type
|
||||
dir uintptr // channel direction (ChanDir)
|
||||
}
|
||||
|
||||
// FuncType represents a function type.
|
||||
type FuncType struct {
|
||||
commonType;
|
||||
in []*Type; // input parameter types
|
||||
out []*Type; // output parameter types
|
||||
commonType
|
||||
in []*Type // input parameter types
|
||||
out []*Type // output parameter types
|
||||
}
|
||||
|
||||
// Method on interface type
|
||||
type imethod struct {
|
||||
hash uint32; // hash of name + pkg + typ; same hash as method
|
||||
perm uint32; // index of function pointer in interface map
|
||||
name *string; // name of method
|
||||
pkgPath *string; // nil for exported Names; otherwise import path
|
||||
typ *Type; // .(*FuncType) underneath
|
||||
hash uint32 // hash of name + pkg + typ; same hash as method
|
||||
perm uint32 // index of function pointer in interface map
|
||||
name *string // name of method
|
||||
pkgPath *string // nil for exported Names; otherwise import path
|
||||
typ *Type // .(*FuncType) underneath
|
||||
}
|
||||
|
||||
// InterfaceType represents an interface type.
|
||||
type InterfaceType struct {
|
||||
commonType;
|
||||
methods []imethod; // sorted by hash
|
||||
commonType
|
||||
methods []imethod // sorted by hash
|
||||
}
|
||||
|
||||
// MapType represents a map type.
|
||||
type MapType struct {
|
||||
commonType;
|
||||
key *Type; // map key type
|
||||
elem *Type; // map element (value) type
|
||||
commonType
|
||||
key *Type // map key type
|
||||
elem *Type // map element (value) type
|
||||
}
|
||||
|
||||
// PtrType represents a pointer type.
|
||||
type PtrType struct {
|
||||
commonType;
|
||||
elem *Type; // pointer element (pointed at) type
|
||||
commonType
|
||||
elem *Type // pointer element (pointed at) type
|
||||
}
|
||||
|
||||
// Struct field
|
||||
type structField struct {
|
||||
name *string; // nil for embedded fields
|
||||
pkgPath *string; // nil for exported Names; otherwise import path
|
||||
typ *Type; // type of field
|
||||
tag *string; // nil if no tag
|
||||
offset uintptr; // byte offset of field within struct
|
||||
name *string // nil for embedded fields
|
||||
pkgPath *string // nil for exported Names; otherwise import path
|
||||
typ *Type // type of field
|
||||
tag *string // nil if no tag
|
||||
offset uintptr // byte offset of field within struct
|
||||
}
|
||||
|
||||
// StructType represents a struct type.
|
||||
type StructType struct {
|
||||
commonType;
|
||||
fields []structField; // sorted by offset
|
||||
commonType
|
||||
fields []structField // sorted by offset
|
||||
}
|
||||
|
||||
/*
|
||||
* Must match iface.c:/Itab and compilers.
|
||||
*/
|
||||
type Itable struct {
|
||||
Itype *Type; // (*tab.inter).(*InterfaceType) is the interface type
|
||||
Type *Type;
|
||||
link *Itable;
|
||||
bad int32;
|
||||
unused int32;
|
||||
Fn [100000]uintptr; // bigger than we'll ever see
|
||||
Itype *Type // (*tab.inter).(*InterfaceType) is the interface type
|
||||
Type *Type
|
||||
link *Itable
|
||||
bad int32
|
||||
unused int32
|
||||
Fn [100000]uintptr // bigger than we'll ever see
|
||||
}
|
||||
|
@ -11,19 +11,19 @@ package sort
|
||||
// elements of the collection be enumerated by an integer index.
|
||||
type Interface interface {
|
||||
// Len is the number of elements in the collection.
|
||||
Len() int;
|
||||
Len() int
|
||||
// Less returns whether the element with index i is should sort
|
||||
// before the element with index j.
|
||||
Less(i, j int) bool;
|
||||
Less(i, j int) bool
|
||||
// Swap swaps the elements with indexes i and j.
|
||||
Swap(i, j int);
|
||||
Swap(i, j int)
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b;
|
||||
return b
|
||||
}
|
||||
|
||||
// Insertion sort
|
||||
@ -40,9 +40,9 @@ func insertionSort(data Interface, a, b int) {
|
||||
|
||||
// Move the median of the three values data[a], data[b], data[c] into data[a].
|
||||
func medianOfThree(data Interface, a, b, c int) {
|
||||
m0 := b;
|
||||
m1 := a;
|
||||
m2 := c;
|
||||
m0 := b
|
||||
m1 := a
|
||||
m2 := c
|
||||
// bubble sort on 3 elements
|
||||
if data.Less(m1, m0) {
|
||||
data.Swap(m1, m0)
|
||||
@ -63,15 +63,15 @@ func swapRange(data Interface, a, b, n int) {
|
||||
}
|
||||
|
||||
func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
|
||||
m := (lo + hi) / 2;
|
||||
m := (lo + hi) / 2
|
||||
if hi-lo > 40 {
|
||||
// Tukey's ``Ninther,'' median of three medians of three.
|
||||
s := (hi - lo) / 8;
|
||||
medianOfThree(data, lo, lo+s, lo+2*s);
|
||||
medianOfThree(data, m, m-s, m+s);
|
||||
medianOfThree(data, hi-1, hi-1-s, hi-1-2*s);
|
||||
s := (hi - lo) / 8
|
||||
medianOfThree(data, lo, lo+s, lo+2*s)
|
||||
medianOfThree(data, m, m-s, m+s)
|
||||
medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
|
||||
}
|
||||
medianOfThree(data, lo, m, hi-1);
|
||||
medianOfThree(data, lo, m, hi-1)
|
||||
|
||||
// Invariants are:
|
||||
// data[lo] = pivot (set up by ChoosePivot)
|
||||
@ -83,65 +83,65 @@ func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
|
||||
//
|
||||
// Once b meets c, can swap the "= pivot" sections
|
||||
// into the middle of the array.
|
||||
pivot := lo;
|
||||
a, b, c, d := lo+1, lo+1, hi, hi;
|
||||
pivot := lo
|
||||
a, b, c, d := lo+1, lo+1, hi, hi
|
||||
for b < c {
|
||||
if data.Less(b, pivot) { // data[b] < pivot
|
||||
b++;
|
||||
continue;
|
||||
if data.Less(b, pivot) { // data[b] < pivot
|
||||
b++
|
||||
continue
|
||||
}
|
||||
if !data.Less(pivot, b) { // data[b] = pivot
|
||||
data.Swap(a, b);
|
||||
a++;
|
||||
b++;
|
||||
continue;
|
||||
if !data.Less(pivot, b) { // data[b] = pivot
|
||||
data.Swap(a, b)
|
||||
a++
|
||||
b++
|
||||
continue
|
||||
}
|
||||
if data.Less(pivot, c-1) { // data[c-1] > pivot
|
||||
c--;
|
||||
continue;
|
||||
if data.Less(pivot, c-1) { // data[c-1] > pivot
|
||||
c--
|
||||
continue
|
||||
}
|
||||
if !data.Less(c-1, pivot) { // data[c-1] = pivot
|
||||
data.Swap(c-1, d-1);
|
||||
c--;
|
||||
d--;
|
||||
continue;
|
||||
if !data.Less(c-1, pivot) { // data[c-1] = pivot
|
||||
data.Swap(c-1, d-1)
|
||||
c--
|
||||
d--
|
||||
continue
|
||||
}
|
||||
// data[b] > pivot; data[c-1] < pivot
|
||||
data.Swap(b, c-1);
|
||||
b++;
|
||||
c--;
|
||||
data.Swap(b, c-1)
|
||||
b++
|
||||
c--
|
||||
}
|
||||
|
||||
n := min(b-a, a-lo);
|
||||
swapRange(data, lo, b-n, n);
|
||||
n := min(b-a, a-lo)
|
||||
swapRange(data, lo, b-n, n)
|
||||
|
||||
n = min(hi-d, d-c);
|
||||
swapRange(data, c, hi-n, n);
|
||||
n = min(hi-d, d-c)
|
||||
swapRange(data, c, hi-n, n)
|
||||
|
||||
return lo + b - a, hi - (d - c);
|
||||
return lo + b - a, hi - (d - c)
|
||||
}
|
||||
|
||||
func quickSort(data Interface, a, b int) {
|
||||
if b-a > 7 {
|
||||
mlo, mhi := doPivot(data, a, b);
|
||||
quickSort(data, a, mlo);
|
||||
quickSort(data, mhi, b);
|
||||
mlo, mhi := doPivot(data, a, b)
|
||||
quickSort(data, a, mlo)
|
||||
quickSort(data, mhi, b)
|
||||
} else if b-a > 1 {
|
||||
insertionSort(data, a, b)
|
||||
}
|
||||
}
|
||||
|
||||
func Sort(data Interface) { quickSort(data, 0, data.Len()) }
|
||||
func Sort(data Interface) { quickSort(data, 0, data.Len()) }
|
||||
|
||||
|
||||
func IsSorted(data Interface) bool {
|
||||
n := data.Len();
|
||||
n := data.Len()
|
||||
for i := n - 1; i > 0; i-- {
|
||||
if data.Less(i, i-1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@ -150,49 +150,49 @@ func IsSorted(data Interface) bool {
|
||||
// IntArray attaches the methods of Interface to []int, sorting in increasing order.
|
||||
type IntArray []int
|
||||
|
||||
func (p IntArray) Len() int { return len(p) }
|
||||
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
|
||||
func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p IntArray) Len() int { return len(p) }
|
||||
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
|
||||
func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// Sort is a convenience method.
|
||||
func (p IntArray) Sort() { Sort(p) }
|
||||
func (p IntArray) Sort() { Sort(p) }
|
||||
|
||||
|
||||
// FloatArray attaches the methods of Interface to []float, sorting in increasing order.
|
||||
type FloatArray []float
|
||||
|
||||
func (p FloatArray) Len() int { return len(p) }
|
||||
func (p FloatArray) Less(i, j int) bool { return p[i] < p[j] }
|
||||
func (p FloatArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p FloatArray) Len() int { return len(p) }
|
||||
func (p FloatArray) Less(i, j int) bool { return p[i] < p[j] }
|
||||
func (p FloatArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// Sort is a convenience method.
|
||||
func (p FloatArray) Sort() { Sort(p) }
|
||||
func (p FloatArray) Sort() { Sort(p) }
|
||||
|
||||
|
||||
// StringArray attaches the methods of Interface to []string, sorting in increasing order.
|
||||
type StringArray []string
|
||||
|
||||
func (p StringArray) Len() int { return len(p) }
|
||||
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }
|
||||
func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p StringArray) Len() int { return len(p) }
|
||||
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }
|
||||
func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// Sort is a convenience method.
|
||||
func (p StringArray) Sort() { Sort(p) }
|
||||
func (p StringArray) Sort() { Sort(p) }
|
||||
|
||||
|
||||
// Convenience wrappers for common cases
|
||||
|
||||
// SortInts sorts an array of ints in increasing order.
|
||||
func SortInts(a []int) { Sort(IntArray(a)) }
|
||||
func SortInts(a []int) { Sort(IntArray(a)) }
|
||||
// SortFloats sorts an array of floats in increasing order.
|
||||
func SortFloats(a []float) { Sort(FloatArray(a)) }
|
||||
func SortFloats(a []float) { Sort(FloatArray(a)) }
|
||||
// SortStrings sorts an array of strings in increasing order.
|
||||
func SortStrings(a []string) { Sort(StringArray(a)) }
|
||||
func SortStrings(a []string) { Sort(StringArray(a)) }
|
||||
|
||||
|
||||
// IntsAreSorted tests whether an array of ints is sorted in increasing order.
|
||||
func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) }
|
||||
func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) }
|
||||
// FloatsAreSorted tests whether an array of floats is sorted in increasing order.
|
||||
func FloatsAreSorted(a []float) bool { return IsSorted(FloatArray(a)) }
|
||||
func FloatsAreSorted(a []float) bool { return IsSorted(FloatArray(a)) }
|
||||
// StringsAreSorted tests whether an array of strings is sorted in increasing order.
|
||||
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) }
|
||||
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) }
|
||||
|
@ -5,10 +5,10 @@
|
||||
package sort
|
||||
|
||||
import (
|
||||
"fmt";
|
||||
"rand";
|
||||
"strconv";
|
||||
"testing";
|
||||
"fmt"
|
||||
"rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
||||
@ -17,173 +17,173 @@ var floats = [...]float{74.3, 59.0, 238.2, -784.0, 2.3, 9845.768, -959.7485, 905
|
||||
var strings = [...]string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
|
||||
|
||||
func TestSortIntArray(t *testing.T) {
|
||||
data := ints;
|
||||
a := IntArray(&data);
|
||||
Sort(a);
|
||||
data := ints
|
||||
a := IntArray(&data)
|
||||
Sort(a)
|
||||
if !IsSorted(a) {
|
||||
t.Errorf("sorted %v", ints);
|
||||
t.Errorf(" got %v", data);
|
||||
t.Errorf("sorted %v", ints)
|
||||
t.Errorf(" got %v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortFloatArray(t *testing.T) {
|
||||
data := floats;
|
||||
a := FloatArray(&data);
|
||||
Sort(a);
|
||||
data := floats
|
||||
a := FloatArray(&data)
|
||||
Sort(a)
|
||||
if !IsSorted(a) {
|
||||
t.Errorf("sorted %v", floats);
|
||||
t.Errorf(" got %v", data);
|
||||
t.Errorf("sorted %v", floats)
|
||||
t.Errorf(" got %v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortStringArray(t *testing.T) {
|
||||
data := strings;
|
||||
a := StringArray(&data);
|
||||
Sort(a);
|
||||
data := strings
|
||||
a := StringArray(&data)
|
||||
Sort(a)
|
||||
if !IsSorted(a) {
|
||||
t.Errorf("sorted %v", strings);
|
||||
t.Errorf(" got %v", data);
|
||||
t.Errorf("sorted %v", strings)
|
||||
t.Errorf(" got %v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortInts(t *testing.T) {
|
||||
data := ints;
|
||||
SortInts(&data);
|
||||
data := ints
|
||||
SortInts(&data)
|
||||
if !IntsAreSorted(&data) {
|
||||
t.Errorf("sorted %v", ints);
|
||||
t.Errorf(" got %v", data);
|
||||
t.Errorf("sorted %v", ints)
|
||||
t.Errorf(" got %v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortFloats(t *testing.T) {
|
||||
data := floats;
|
||||
SortFloats(&data);
|
||||
data := floats
|
||||
SortFloats(&data)
|
||||
if !FloatsAreSorted(&data) {
|
||||
t.Errorf("sorted %v", floats);
|
||||
t.Errorf(" got %v", data);
|
||||
t.Errorf("sorted %v", floats)
|
||||
t.Errorf(" got %v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortStrings(t *testing.T) {
|
||||
data := strings;
|
||||
SortStrings(&data);
|
||||
data := strings
|
||||
SortStrings(&data)
|
||||
if !StringsAreSorted(&data) {
|
||||
t.Errorf("sorted %v", strings);
|
||||
t.Errorf(" got %v", data);
|
||||
t.Errorf("sorted %v", strings)
|
||||
t.Errorf(" got %v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortLarge_Random(t *testing.T) {
|
||||
data := make([]int, 1000000);
|
||||
data := make([]int, 1000000)
|
||||
for i := 0; i < len(data); i++ {
|
||||
data[i] = rand.Intn(100)
|
||||
}
|
||||
if IntsAreSorted(data) {
|
||||
t.Fatalf("terrible rand.rand")
|
||||
}
|
||||
SortInts(data);
|
||||
SortInts(data)
|
||||
if !IntsAreSorted(data) {
|
||||
t.Errorf("sort didn't sort - 1M ints")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSortString1K(b *testing.B) {
|
||||
b.StopTimer();
|
||||
b.StopTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
data := make([]string, 1<<10);
|
||||
data := make([]string, 1<<10)
|
||||
for i := 0; i < len(data); i++ {
|
||||
data[i] = strconv.Itoa(i ^ 0x2cc)
|
||||
}
|
||||
b.StartTimer();
|
||||
SortStrings(data);
|
||||
b.StopTimer();
|
||||
b.StartTimer()
|
||||
SortStrings(data)
|
||||
b.StopTimer()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSortInt1K(b *testing.B) {
|
||||
b.StopTimer();
|
||||
b.StopTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
data := make([]int, 1<<10);
|
||||
data := make([]int, 1<<10)
|
||||
for i := 0; i < len(data); i++ {
|
||||
data[i] = i ^ 0x2cc
|
||||
}
|
||||
b.StartTimer();
|
||||
SortInts(data);
|
||||
b.StopTimer();
|
||||
b.StartTimer()
|
||||
SortInts(data)
|
||||
b.StopTimer()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSortInt64K(b *testing.B) {
|
||||
b.StopTimer();
|
||||
b.StopTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
data := make([]int, 1<<16);
|
||||
data := make([]int, 1<<16)
|
||||
for i := 0; i < len(data); i++ {
|
||||
data[i] = i ^ 0xcccc
|
||||
}
|
||||
b.StartTimer();
|
||||
SortInts(data);
|
||||
b.StopTimer();
|
||||
b.StartTimer()
|
||||
SortInts(data)
|
||||
b.StopTimer()
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
_Sawtooth = iota;
|
||||
_Rand;
|
||||
_Stagger;
|
||||
_Plateau;
|
||||
_Shuffle;
|
||||
_NDist;
|
||||
_Sawtooth = iota
|
||||
_Rand
|
||||
_Stagger
|
||||
_Plateau
|
||||
_Shuffle
|
||||
_NDist
|
||||
)
|
||||
|
||||
const (
|
||||
_Copy = iota;
|
||||
_Reverse;
|
||||
_ReverseFirstHalf;
|
||||
_ReverseSecondHalf;
|
||||
_Sorted;
|
||||
_Dither;
|
||||
_NMode;
|
||||
_Copy = iota
|
||||
_Reverse
|
||||
_ReverseFirstHalf
|
||||
_ReverseSecondHalf
|
||||
_Sorted
|
||||
_Dither
|
||||
_NMode
|
||||
)
|
||||
|
||||
type testingData struct {
|
||||
desc string;
|
||||
t *testing.T;
|
||||
data []int;
|
||||
maxswap int; // number of swaps allowed
|
||||
nswap int;
|
||||
desc string
|
||||
t *testing.T
|
||||
data []int
|
||||
maxswap int // number of swaps allowed
|
||||
nswap int
|
||||
}
|
||||
|
||||
func (d *testingData) Len() int { return len(d.data) }
|
||||
func (d *testingData) Less(i, j int) bool { return d.data[i] < d.data[j] }
|
||||
func (d *testingData) Len() int { return len(d.data) }
|
||||
func (d *testingData) Less(i, j int) bool { return d.data[i] < d.data[j] }
|
||||
func (d *testingData) Swap(i, j int) {
|
||||
if d.nswap >= d.maxswap {
|
||||
d.t.Errorf("%s: used %d swaps sorting array of %d", d.desc, d.nswap, len(d.data));
|
||||
d.t.FailNow();
|
||||
d.t.Errorf("%s: used %d swaps sorting array of %d", d.desc, d.nswap, len(d.data))
|
||||
d.t.FailNow()
|
||||
}
|
||||
d.nswap++;
|
||||
d.data[i], d.data[j] = d.data[j], d.data[i];
|
||||
d.nswap++
|
||||
d.data[i], d.data[j] = d.data[j], d.data[i]
|
||||
}
|
||||
|
||||
func lg(n int) int {
|
||||
i := 0;
|
||||
i := 0
|
||||
for 1<<uint(i) < n {
|
||||
i++
|
||||
}
|
||||
return i;
|
||||
return i
|
||||
}
|
||||
|
||||
func TestBentleyMcIlroy(t *testing.T) {
|
||||
sizes := []int{100, 1023, 1024, 1025};
|
||||
dists := []string{"sawtooth", "rand", "stagger", "plateau", "shuffle"};
|
||||
modes := []string{"copy", "reverse", "reverse1", "reverse2", "sort", "dither"};
|
||||
var tmp1, tmp2 [1025]int;
|
||||
sizes := []int{100, 1023, 1024, 1025}
|
||||
dists := []string{"sawtooth", "rand", "stagger", "plateau", "shuffle"}
|
||||
modes := []string{"copy", "reverse", "reverse1", "reverse2", "sort", "dither"}
|
||||
var tmp1, tmp2 [1025]int
|
||||
for ni := 0; ni < len(sizes); ni++ {
|
||||
n := sizes[ni];
|
||||
n := sizes[ni]
|
||||
for m := 1; m < 2*n; m *= 2 {
|
||||
for dist := 0; dist < _NDist; dist++ {
|
||||
j := 0;
|
||||
k := 1;
|
||||
data := tmp1[0:n];
|
||||
j := 0
|
||||
k := 1
|
||||
data := tmp1[0:n]
|
||||
for i := 0; i < n; i++ {
|
||||
switch dist {
|
||||
case _Sawtooth:
|
||||
@ -196,16 +196,16 @@ func TestBentleyMcIlroy(t *testing.T) {
|
||||
data[i] = min(i, m)
|
||||
case _Shuffle:
|
||||
if rand.Intn(m) != 0 {
|
||||
j += 2;
|
||||
data[i] = j;
|
||||
j += 2
|
||||
data[i] = j
|
||||
} else {
|
||||
k += 2;
|
||||
data[i] = k;
|
||||
k += 2
|
||||
data[i] = k
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mdata := tmp2[0:n];
|
||||
mdata := tmp2[0:n]
|
||||
for mode := 0; mode < _NMode; mode++ {
|
||||
switch mode {
|
||||
case _Copy:
|
||||
@ -236,16 +236,16 @@ func TestBentleyMcIlroy(t *testing.T) {
|
||||
}
|
||||
// SortInts is known to be correct
|
||||
// because mode Sort runs after mode _Copy.
|
||||
SortInts(mdata);
|
||||
SortInts(mdata)
|
||||
case _Dither:
|
||||
for i := 0; i < n; i++ {
|
||||
mdata[i] = data[i] + i%5
|
||||
}
|
||||
}
|
||||
|
||||
desc := fmt.Sprintf("n=%d m=%d dist=%s mode=%s", n, m, dists[dist], modes[mode]);
|
||||
d := &testingData{desc, t, mdata[0:n], n * lg(n) * 12 / 10, 0};
|
||||
Sort(d);
|
||||
desc := fmt.Sprintf("n=%d m=%d dist=%s mode=%s", n, m, dists[dist], modes[mode])
|
||||
d := &testingData{desc, t, mdata[0:n], n * lg(n) * 12 / 10, 0}
|
||||
Sort(d)
|
||||
|
||||
// If we were testing C qsort, we'd have to make a copy
|
||||
// of the array and sort it ourselves and then compare
|
||||
@ -256,9 +256,9 @@ func TestBentleyMcIlroy(t *testing.T) {
|
||||
// mutating method Sort can call is TestingData.swap,
|
||||
// it suffices here just to check that the final array is sorted.
|
||||
if !IntsAreSorted(mdata) {
|
||||
t.Errorf("%s: ints not sorted", desc);
|
||||
t.Errorf("\t%v", mdata);
|
||||
t.FailNow();
|
||||
t.Errorf("%s: ints not sorted", desc)
|
||||
t.Errorf("\t%v", mdata)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,15 @@
|
||||
package strconv
|
||||
|
||||
import (
|
||||
"math";
|
||||
"os";
|
||||
"math"
|
||||
"os"
|
||||
)
|
||||
|
||||
var optimize = true // can change for testing
|
||||
var optimize = true // can change for testing
|
||||
|
||||
// TODO(rsc): Better truncation handling.
|
||||
func stringToDecimal(s string) (neg bool, d *decimal, trunc bool, ok bool) {
|
||||
i := 0;
|
||||
i := 0
|
||||
|
||||
// optional sign
|
||||
if i >= len(s) {
|
||||
@ -31,35 +31,35 @@ func stringToDecimal(s string) (neg bool, d *decimal, trunc bool, ok bool) {
|
||||
case s[i] == '+':
|
||||
i++
|
||||
case s[i] == '-':
|
||||
neg = true;
|
||||
i++;
|
||||
neg = true
|
||||
i++
|
||||
}
|
||||
|
||||
// digits
|
||||
b := new(decimal);
|
||||
sawdot := false;
|
||||
sawdigits := false;
|
||||
b := new(decimal)
|
||||
sawdot := false
|
||||
sawdigits := false
|
||||
for ; i < len(s); i++ {
|
||||
switch {
|
||||
case s[i] == '.':
|
||||
if sawdot {
|
||||
return
|
||||
}
|
||||
sawdot = true;
|
||||
b.dp = b.nd;
|
||||
continue;
|
||||
sawdot = true
|
||||
b.dp = b.nd
|
||||
continue
|
||||
|
||||
case '0' <= s[i] && s[i] <= '9':
|
||||
sawdigits = true;
|
||||
if s[i] == '0' && b.nd == 0 { // ignore leading zeros
|
||||
b.dp--;
|
||||
continue;
|
||||
sawdigits = true
|
||||
if s[i] == '0' && b.nd == 0 { // ignore leading zeros
|
||||
b.dp--
|
||||
continue
|
||||
}
|
||||
b.d[b.nd] = s[i];
|
||||
b.nd++;
|
||||
continue;
|
||||
b.d[b.nd] = s[i]
|
||||
b.nd++
|
||||
continue
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
if !sawdigits {
|
||||
return
|
||||
@ -74,50 +74,50 @@ func stringToDecimal(s string) (neg bool, d *decimal, trunc bool, ok bool) {
|
||||
// a lot (say, 100000). it doesn't matter if it's
|
||||
// not the exact number.
|
||||
if i < len(s) && s[i] == 'e' {
|
||||
i++;
|
||||
i++
|
||||
if i >= len(s) {
|
||||
return
|
||||
}
|
||||
esign := 1;
|
||||
esign := 1
|
||||
if s[i] == '+' {
|
||||
i++
|
||||
} else if s[i] == '-' {
|
||||
i++;
|
||||
esign = -1;
|
||||
i++
|
||||
esign = -1
|
||||
}
|
||||
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
||||
return
|
||||
}
|
||||
e := 0;
|
||||
e := 0
|
||||
for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
|
||||
if e < 10000 {
|
||||
e = e*10 + int(s[i]) - '0'
|
||||
}
|
||||
}
|
||||
b.dp += e * esign;
|
||||
b.dp += e * esign
|
||||
}
|
||||
|
||||
if i != len(s) {
|
||||
return
|
||||
}
|
||||
|
||||
d = b;
|
||||
ok = true;
|
||||
return;
|
||||
d = b
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// decimal power of ten to binary power of two.
|
||||
var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26}
|
||||
|
||||
func decimalToFloatBits(neg bool, d *decimal, trunc bool, flt *floatInfo) (b uint64, overflow bool) {
|
||||
var exp int;
|
||||
var mant uint64;
|
||||
var exp int
|
||||
var mant uint64
|
||||
|
||||
// Zero is always a special case.
|
||||
if d.nd == 0 {
|
||||
mant = 0;
|
||||
exp = flt.bias;
|
||||
goto out;
|
||||
mant = 0
|
||||
exp = flt.bias
|
||||
goto out
|
||||
}
|
||||
|
||||
// Obvious overflow/underflow.
|
||||
@ -128,44 +128,44 @@ func decimalToFloatBits(neg bool, d *decimal, trunc bool, flt *floatInfo) (b uin
|
||||
}
|
||||
if d.dp < -330 {
|
||||
// zero
|
||||
mant = 0;
|
||||
exp = flt.bias;
|
||||
goto out;
|
||||
mant = 0
|
||||
exp = flt.bias
|
||||
goto out
|
||||
}
|
||||
|
||||
// Scale by powers of two until in range [0.5, 1.0)
|
||||
exp = 0;
|
||||
exp = 0
|
||||
for d.dp > 0 {
|
||||
var n int;
|
||||
var n int
|
||||
if d.dp >= len(powtab) {
|
||||
n = 27
|
||||
} else {
|
||||
n = powtab[d.dp]
|
||||
}
|
||||
d.Shift(-n);
|
||||
exp += n;
|
||||
d.Shift(-n)
|
||||
exp += n
|
||||
}
|
||||
for d.dp < 0 || d.dp == 0 && d.d[0] < '5' {
|
||||
var n int;
|
||||
var n int
|
||||
if -d.dp >= len(powtab) {
|
||||
n = 27
|
||||
} else {
|
||||
n = powtab[-d.dp]
|
||||
}
|
||||
d.Shift(n);
|
||||
exp -= n;
|
||||
d.Shift(n)
|
||||
exp -= n
|
||||
}
|
||||
|
||||
// Our range is [0.5,1) but floating point range is [1,2).
|
||||
exp--;
|
||||
exp--
|
||||
|
||||
// Minimum representable exponent is flt.bias+1.
|
||||
// If the exponent is smaller, move it up and
|
||||
// adjust d accordingly.
|
||||
if exp < flt.bias+1 {
|
||||
n := flt.bias + 1 - exp;
|
||||
d.Shift(-n);
|
||||
exp += n;
|
||||
n := flt.bias + 1 - exp
|
||||
d.Shift(-n)
|
||||
exp += n
|
||||
}
|
||||
|
||||
if exp-flt.bias >= 1<<flt.expbits-1 {
|
||||
@ -173,12 +173,12 @@ func decimalToFloatBits(neg bool, d *decimal, trunc bool, flt *floatInfo) (b uin
|
||||
}
|
||||
|
||||
// Extract 1+flt.mantbits bits.
|
||||
mant = d.Shift(int(1 + flt.mantbits)).RoundedInteger();
|
||||
mant = d.Shift(int(1 + flt.mantbits)).RoundedInteger()
|
||||
|
||||
// Rounding might have added a bit; shift down.
|
||||
if mant == 2<<flt.mantbits {
|
||||
mant >>= 1;
|
||||
exp++;
|
||||
mant >>= 1
|
||||
exp++
|
||||
if exp-flt.bias >= 1<<flt.expbits-1 {
|
||||
goto overflow
|
||||
}
|
||||
@ -188,46 +188,46 @@ func decimalToFloatBits(neg bool, d *decimal, trunc bool, flt *floatInfo) (b uin
|
||||
if mant&(1<<flt.mantbits) == 0 {
|
||||
exp = flt.bias
|
||||
}
|
||||
goto out;
|
||||
goto out
|
||||
|
||||
overflow:
|
||||
// ±Inf
|
||||
mant = 0;
|
||||
exp = 1<<flt.expbits - 1 + flt.bias;
|
||||
overflow = true;
|
||||
mant = 0
|
||||
exp = 1<<flt.expbits - 1 + flt.bias
|
||||
overflow = true
|
||||
|
||||
out:
|
||||
// Assemble bits.
|
||||
bits := mant & (uint64(1)<<flt.mantbits - 1);
|
||||
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits;
|
||||
bits := mant & (uint64(1)<<flt.mantbits - 1)
|
||||
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
|
||||
if neg {
|
||||
bits |= 1 << flt.mantbits << flt.expbits
|
||||
}
|
||||
return bits, overflow;
|
||||
return bits, overflow
|
||||
}
|
||||
|
||||
// Compute exact floating-point integer from d's digits.
|
||||
// Caller is responsible for avoiding overflow.
|
||||
func decimalAtof64Int(neg bool, d *decimal) float64 {
|
||||
f := float64(0);
|
||||
f := float64(0)
|
||||
for i := 0; i < d.nd; i++ {
|
||||
f = f*10 + float64(d.d[i]-'0')
|
||||
}
|
||||
if neg {
|
||||
f *= -1 // BUG work around 6g f = -f.
|
||||
f *= -1 // BUG work around 6g f = -f.
|
||||
}
|
||||
return f;
|
||||
return f
|
||||
}
|
||||
|
||||
func decimalAtof32Int(neg bool, d *decimal) float32 {
|
||||
f := float32(0);
|
||||
f := float32(0)
|
||||
for i := 0; i < d.nd; i++ {
|
||||
f = f*10 + float32(d.d[i]-'0')
|
||||
}
|
||||
if neg {
|
||||
f *= -1 // BUG work around 6g f = -f.
|
||||
f *= -1 // BUG work around 6g f = -f.
|
||||
}
|
||||
return f;
|
||||
return f
|
||||
}
|
||||
|
||||
// Exact powers of 10.
|
||||
@ -252,26 +252,26 @@ func decimalAtof64(neg bool, d *decimal, trunc bool) (f float64, ok bool) {
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case d.dp == d.nd: // int
|
||||
f := decimalAtof64Int(neg, d);
|
||||
return f, true;
|
||||
case d.dp == d.nd: // int
|
||||
f := decimalAtof64Int(neg, d)
|
||||
return f, true
|
||||
|
||||
case d.dp > d.nd && d.dp <= 15+22: // int * 10^k
|
||||
f := decimalAtof64Int(neg, d);
|
||||
k := d.dp - d.nd;
|
||||
case d.dp > d.nd && d.dp <= 15+22: // int * 10^k
|
||||
f := decimalAtof64Int(neg, d)
|
||||
k := d.dp - d.nd
|
||||
// If exponent is big but number of digits is not,
|
||||
// can move a few zeros into the integer part.
|
||||
if k > 22 {
|
||||
f *= float64pow10[k-22];
|
||||
k = 22;
|
||||
f *= float64pow10[k-22]
|
||||
k = 22
|
||||
}
|
||||
return f * float64pow10[k], true;
|
||||
return f * float64pow10[k], true
|
||||
|
||||
case d.dp < d.nd && d.nd-d.dp <= 22: // int / 10^k
|
||||
f := decimalAtof64Int(neg, d);
|
||||
return f / float64pow10[d.nd-d.dp], true;
|
||||
case d.dp < d.nd && d.nd-d.dp <= 22: // int / 10^k
|
||||
f := decimalAtof64Int(neg, d)
|
||||
return f / float64pow10[d.nd-d.dp], true
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// If possible to convert decimal d to 32-bit float f exactly,
|
||||
@ -283,26 +283,26 @@ func decimalAtof32(neg bool, d *decimal, trunc bool) (f float32, ok bool) {
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case d.dp == d.nd: // int
|
||||
f := decimalAtof32Int(neg, d);
|
||||
return f, true;
|
||||
case d.dp == d.nd: // int
|
||||
f := decimalAtof32Int(neg, d)
|
||||
return f, true
|
||||
|
||||
case d.dp > d.nd && d.dp <= 7+10: // int * 10^k
|
||||
f := decimalAtof32Int(neg, d);
|
||||
k := d.dp - d.nd;
|
||||
case d.dp > d.nd && d.dp <= 7+10: // int * 10^k
|
||||
f := decimalAtof32Int(neg, d)
|
||||
k := d.dp - d.nd
|
||||
// If exponent is big but number of digits is not,
|
||||
// can move a few zeros into the integer part.
|
||||
if k > 10 {
|
||||
f *= float32pow10[k-10];
|
||||
k = 10;
|
||||
f *= float32pow10[k-10]
|
||||
k = 10
|
||||
}
|
||||
return f * float32pow10[k], true;
|
||||
return f * float32pow10[k], true
|
||||
|
||||
case d.dp < d.nd && d.nd-d.dp <= 10: // int / 10^k
|
||||
f := decimalAtof32Int(neg, d);
|
||||
return f / float32pow10[d.nd-d.dp], true;
|
||||
case d.dp < d.nd && d.nd-d.dp <= 10: // int / 10^k
|
||||
f := decimalAtof32Int(neg, d)
|
||||
return f / float32pow10[d.nd-d.dp], true
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Atof32 converts the string s to a 32-bit floating-point number.
|
||||
@ -320,7 +320,7 @@ func decimalAtof32(neg bool, d *decimal, trunc bool) (f float32, ok bool) {
|
||||
// away from the largest floating point number of the given size,
|
||||
// Atof32 returns f = ±Inf, err.Error = os.ERANGE.
|
||||
func Atof32(s string) (f float32, err os.Error) {
|
||||
neg, d, trunc, ok := stringToDecimal(s);
|
||||
neg, d, trunc, ok := stringToDecimal(s)
|
||||
if !ok {
|
||||
return 0, &NumError{s, os.EINVAL}
|
||||
}
|
||||
@ -329,19 +329,19 @@ func Atof32(s string) (f float32, err os.Error) {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
b, ovf := decimalToFloatBits(neg, d, trunc, &float32info);
|
||||
f = math.Float32frombits(uint32(b));
|
||||
b, ovf := decimalToFloatBits(neg, d, trunc, &float32info)
|
||||
f = math.Float32frombits(uint32(b))
|
||||
if ovf {
|
||||
err = &NumError{s, os.ERANGE}
|
||||
}
|
||||
return f, err;
|
||||
return f, err
|
||||
}
|
||||
|
||||
// Atof64 converts the string s to a 64-bit floating-point number.
|
||||
// Except for the type of its result, its definition is the same as that
|
||||
// of Atof32.
|
||||
func Atof64(s string) (f float64, err os.Error) {
|
||||
neg, d, trunc, ok := stringToDecimal(s);
|
||||
neg, d, trunc, ok := stringToDecimal(s)
|
||||
if !ok {
|
||||
return 0, &NumError{s, os.EINVAL}
|
||||
}
|
||||
@ -350,20 +350,20 @@ func Atof64(s string) (f float64, err os.Error) {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
b, ovf := decimalToFloatBits(neg, d, trunc, &float64info);
|
||||
f = math.Float64frombits(b);
|
||||
b, ovf := decimalToFloatBits(neg, d, trunc, &float64info)
|
||||
f = math.Float64frombits(b)
|
||||
if ovf {
|
||||
err = &NumError{s, os.ERANGE}
|
||||
}
|
||||
return f, err;
|
||||
return f, err
|
||||
}
|
||||
|
||||
// Atof is like Atof32 or Atof64, depending on the size of float.
|
||||
func Atof(s string) (f float, err os.Error) {
|
||||
if FloatSize == 32 {
|
||||
f1, err1 := Atof32(s);
|
||||
return float(f1), err1;
|
||||
f1, err1 := Atof32(s)
|
||||
return float(f1), err1
|
||||
}
|
||||
f1, err1 := Atof64(s);
|
||||
return float(f1), err1;
|
||||
f1, err1 := Atof64(s)
|
||||
return float(f1), err1
|
||||
}
|
||||
|
@ -5,16 +5,16 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
"os";
|
||||
"reflect";
|
||||
. "strconv";
|
||||
"testing";
|
||||
"os"
|
||||
"reflect"
|
||||
. "strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type atofTest struct {
|
||||
in string;
|
||||
out string;
|
||||
err os.Error;
|
||||
in string
|
||||
out string
|
||||
err os.Error
|
||||
}
|
||||
|
||||
var atoftests = []atofTest{
|
||||
@ -96,7 +96,7 @@ func init() {
|
||||
// The atof routines return NumErrors wrapping
|
||||
// the error and the string. Convert the table above.
|
||||
for i := range atoftests {
|
||||
test := &atoftests[i];
|
||||
test := &atoftests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
@ -104,19 +104,19 @@ func init() {
|
||||
}
|
||||
|
||||
func testAtof(t *testing.T, opt bool) {
|
||||
oldopt := SetOptimize(opt);
|
||||
oldopt := SetOptimize(opt)
|
||||
for i := 0; i < len(atoftests); i++ {
|
||||
test := &atoftests[i];
|
||||
out, err := Atof64(test.in);
|
||||
outs := Ftoa64(out, 'g', -1);
|
||||
test := &atoftests[i]
|
||||
out, err := Atof64(test.in)
|
||||
outs := Ftoa64(out, 'g', -1)
|
||||
if outs != test.out || !reflect.DeepEqual(err, test.err) {
|
||||
t.Errorf("Atof64(%v) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
}
|
||||
|
||||
if float64(float32(out)) == out {
|
||||
out32, err := Atof32(test.in);
|
||||
outs := Ftoa32(out32, 'g', -1);
|
||||
out32, err := Atof32(test.in)
|
||||
outs := Ftoa32(out32, 'g', -1)
|
||||
if outs != test.out || !reflect.DeepEqual(err, test.err) {
|
||||
t.Errorf("Atof32(%v) = %v, %v want %v, %v # %v\n",
|
||||
test.in, out32, err, test.out, test.err, out)
|
||||
@ -124,20 +124,20 @@ func testAtof(t *testing.T, opt bool) {
|
||||
}
|
||||
|
||||
if FloatSize == 64 || float64(float32(out)) == out {
|
||||
outf, err := Atof(test.in);
|
||||
outs := Ftoa(outf, 'g', -1);
|
||||
outf, err := Atof(test.in)
|
||||
outs := Ftoa(outf, 'g', -1)
|
||||
if outs != test.out || !reflect.DeepEqual(err, test.err) {
|
||||
t.Errorf("Ftoa(%v) = %v, %v want %v, %v # %v\n",
|
||||
test.in, outf, err, test.out, test.err, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
SetOptimize(oldopt);
|
||||
SetOptimize(oldopt)
|
||||
}
|
||||
|
||||
func TestAtof(t *testing.T) { testAtof(t, true) }
|
||||
func TestAtof(t *testing.T) { testAtof(t, true) }
|
||||
|
||||
func TestAtofSlow(t *testing.T) { testAtof(t, false) }
|
||||
func TestAtofSlow(t *testing.T) { testAtof(t, false) }
|
||||
|
||||
func BenchmarkAtofDecimal(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
@ -7,19 +7,19 @@ package strconv
|
||||
import "os"
|
||||
|
||||
type NumError struct {
|
||||
Num string;
|
||||
Error os.Error;
|
||||
Num string
|
||||
Error os.Error
|
||||
}
|
||||
|
||||
func (e *NumError) String() string { return "parsing " + e.Num + ": " + e.Error.String() }
|
||||
func (e *NumError) String() string { return "parsing " + e.Num + ": " + e.Error.String() }
|
||||
|
||||
|
||||
func computeIntsize() uint {
|
||||
siz := uint(8);
|
||||
siz := uint(8)
|
||||
for 1<<siz != 0 {
|
||||
siz *= 2
|
||||
}
|
||||
return siz;
|
||||
return siz
|
||||
}
|
||||
|
||||
var IntSize = computeIntsize()
|
||||
@ -29,7 +29,7 @@ func cutoff64(base int) uint64 {
|
||||
if base < 2 {
|
||||
return 0
|
||||
}
|
||||
return (1<<64-1)/uint64(base) + 1;
|
||||
return (1<<64-1)/uint64(base) + 1
|
||||
}
|
||||
|
||||
// Btoui64 interprets a string s in an arbitrary base b (2 to 36)
|
||||
@ -42,11 +42,11 @@ func cutoff64(base int) uint64 {
|
||||
// digits, err.Error = os.EINVAL; if the value corresponding
|
||||
// to s cannot be represented by a uint64, err.Error = os.ERANGE.
|
||||
func Btoui64(s string, b int) (n uint64, err os.Error) {
|
||||
s0 := s;
|
||||
s0 := s
|
||||
switch {
|
||||
case len(s) < 1:
|
||||
err = os.EINVAL;
|
||||
goto Error;
|
||||
err = os.EINVAL
|
||||
goto Error
|
||||
|
||||
case 2 <= b && b <= 36:
|
||||
// valid base; nothing to do
|
||||
@ -55,11 +55,11 @@ func Btoui64(s string, b int) (n uint64, err os.Error) {
|
||||
// Look for octal, hex prefix.
|
||||
switch {
|
||||
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
|
||||
b = 16;
|
||||
s = s[2:];
|
||||
b = 16
|
||||
s = s[2:]
|
||||
if len(s) < 1 {
|
||||
err = os.EINVAL;
|
||||
goto Error;
|
||||
err = os.EINVAL
|
||||
goto Error
|
||||
}
|
||||
case s[0] == '0':
|
||||
b = 8
|
||||
@ -68,15 +68,15 @@ func Btoui64(s string, b int) (n uint64, err os.Error) {
|
||||
}
|
||||
|
||||
default:
|
||||
err = os.ErrorString("invalid base " + Itoa(b));
|
||||
goto Error;
|
||||
err = os.ErrorString("invalid base " + Itoa(b))
|
||||
goto Error
|
||||
}
|
||||
|
||||
n = 0;
|
||||
cutoff := cutoff64(b);
|
||||
n = 0
|
||||
cutoff := cutoff64(b)
|
||||
|
||||
for i := 0; i < len(s); i++ {
|
||||
var v byte;
|
||||
var v byte
|
||||
switch {
|
||||
case '0' <= s[i] && s[i] <= '9':
|
||||
v = s[i] - '0'
|
||||
@ -85,38 +85,38 @@ func Btoui64(s string, b int) (n uint64, err os.Error) {
|
||||
case 'A' <= s[i] && s[i] <= 'Z':
|
||||
v = s[i] - 'A' + 10
|
||||
default:
|
||||
n = 0;
|
||||
err = os.EINVAL;
|
||||
goto Error;
|
||||
n = 0
|
||||
err = os.EINVAL
|
||||
goto Error
|
||||
}
|
||||
if int(v) >= b {
|
||||
n = 0;
|
||||
err = os.EINVAL;
|
||||
goto Error;
|
||||
n = 0
|
||||
err = os.EINVAL
|
||||
goto Error
|
||||
}
|
||||
|
||||
if n >= cutoff {
|
||||
// n*b overflows
|
||||
n = 1<<64 - 1;
|
||||
err = os.ERANGE;
|
||||
goto Error;
|
||||
n = 1<<64 - 1
|
||||
err = os.ERANGE
|
||||
goto Error
|
||||
}
|
||||
n *= uint64(b);
|
||||
n *= uint64(b)
|
||||
|
||||
n1 := n + uint64(v);
|
||||
n1 := n + uint64(v)
|
||||
if n1 < n {
|
||||
// n+v overflows
|
||||
n = 1<<64 - 1;
|
||||
err = os.ERANGE;
|
||||
goto Error;
|
||||
n = 1<<64 - 1
|
||||
err = os.ERANGE
|
||||
goto Error
|
||||
}
|
||||
n = n1;
|
||||
n = n1
|
||||
}
|
||||
|
||||
return n, nil;
|
||||
return n, nil
|
||||
|
||||
Error:
|
||||
return n, &NumError{s0, err};
|
||||
return n, &NumError{s0, err}
|
||||
}
|
||||
|
||||
// Atoui64 interprets a string s as a decimal number and
|
||||
@ -137,21 +137,21 @@ func Btoi64(s string, base int) (i int64, err os.Error) {
|
||||
}
|
||||
|
||||
// Pick off leading sign.
|
||||
s0 := s;
|
||||
neg := false;
|
||||
s0 := s
|
||||
neg := false
|
||||
if s[0] == '+' {
|
||||
s = s[1:]
|
||||
} else if s[0] == '-' {
|
||||
neg = true;
|
||||
s = s[1:];
|
||||
neg = true
|
||||
s = s[1:]
|
||||
}
|
||||
|
||||
// Convert unsigned and check range.
|
||||
var un uint64;
|
||||
un, err = Btoui64(s, base);
|
||||
var un uint64
|
||||
un, err = Btoui64(s, base)
|
||||
if err != nil && err.(*NumError).Error != os.ERANGE {
|
||||
err.(*NumError).Num = s0;
|
||||
return 0, err;
|
||||
err.(*NumError).Num = s0
|
||||
return 0, err
|
||||
}
|
||||
if !neg && un >= 1<<63 {
|
||||
return 1<<63 - 1, &NumError{s0, os.ERANGE}
|
||||
@ -159,43 +159,43 @@ func Btoi64(s string, base int) (i int64, err os.Error) {
|
||||
if neg && un > 1<<63 {
|
||||
return -1 << 63, &NumError{s0, os.ERANGE}
|
||||
}
|
||||
n := int64(un);
|
||||
n := int64(un)
|
||||
if neg {
|
||||
n = -n
|
||||
}
|
||||
return n, nil;
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Atoi64 is like Atoui64 but allows signed numbers and
|
||||
// returns its result in an int64.
|
||||
func Atoi64(s string) (i int64, err os.Error) { return Btoi64(s, 10) }
|
||||
func Atoi64(s string) (i int64, err os.Error) { return Btoi64(s, 10) }
|
||||
|
||||
|
||||
// Atoui is like Atoui64 but returns its result as a uint.
|
||||
func Atoui(s string) (i uint, err os.Error) {
|
||||
i1, e1 := Atoui64(s);
|
||||
i1, e1 := Atoui64(s)
|
||||
if e1 != nil && e1.(*NumError).Error != os.ERANGE {
|
||||
return 0, e1
|
||||
}
|
||||
i = uint(i1);
|
||||
i = uint(i1)
|
||||
if uint64(i) != i1 {
|
||||
return ^uint(0), &NumError{s, os.ERANGE}
|
||||
}
|
||||
return i, nil;
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// Atoi is like Atoi64 but returns its result as an int.
|
||||
func Atoi(s string) (i int, err os.Error) {
|
||||
i1, e1 := Atoi64(s);
|
||||
i1, e1 := Atoi64(s)
|
||||
if e1 != nil && e1.(*NumError).Error != os.ERANGE {
|
||||
return 0, e1
|
||||
}
|
||||
i = int(i1);
|
||||
i = int(i1)
|
||||
if int64(i) != i1 {
|
||||
if i1 < 0 {
|
||||
return -1 << (IntSize - 1), &NumError{s, os.ERANGE}
|
||||
}
|
||||
return 1<<(IntSize-1) - 1, &NumError{s, os.ERANGE};
|
||||
return 1<<(IntSize-1) - 1, &NumError{s, os.ERANGE}
|
||||
}
|
||||
return i, nil;
|
||||
return i, nil
|
||||
}
|
||||
|
@ -5,16 +5,16 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
"os";
|
||||
"reflect";
|
||||
. "strconv";
|
||||
"testing";
|
||||
"os"
|
||||
"reflect"
|
||||
. "strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type atoui64Test struct {
|
||||
in string;
|
||||
out uint64;
|
||||
err os.Error;
|
||||
in string
|
||||
out uint64
|
||||
err os.Error
|
||||
}
|
||||
|
||||
var atoui64tests = []atoui64Test{
|
||||
@ -52,9 +52,9 @@ var btoui64tests = []atoui64Test{
|
||||
}
|
||||
|
||||
type atoi64Test struct {
|
||||
in string;
|
||||
out int64;
|
||||
err os.Error;
|
||||
in string
|
||||
out int64
|
||||
err os.Error
|
||||
}
|
||||
|
||||
var atoi64tests = []atoi64Test{
|
||||
@ -102,9 +102,9 @@ var btoi64tests = []atoi64Test{
|
||||
}
|
||||
|
||||
type atoui32Test struct {
|
||||
in string;
|
||||
out uint32;
|
||||
err os.Error;
|
||||
in string
|
||||
out uint32
|
||||
err os.Error
|
||||
}
|
||||
|
||||
var atoui32tests = []atoui32Test{
|
||||
@ -120,9 +120,9 @@ var atoui32tests = []atoui32Test{
|
||||
}
|
||||
|
||||
type atoi32Test struct {
|
||||
in string;
|
||||
out int32;
|
||||
err os.Error;
|
||||
in string
|
||||
out int32
|
||||
err os.Error
|
||||
}
|
||||
|
||||
var atoi32tests = []atoi32Test{
|
||||
@ -151,37 +151,37 @@ func init() {
|
||||
// The atoi routines return NumErrors wrapping
|
||||
// the error and the string. Convert the tables above.
|
||||
for i := range atoui64tests {
|
||||
test := &atoui64tests[i];
|
||||
test := &atoui64tests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
}
|
||||
for i := range btoui64tests {
|
||||
test := &btoui64tests[i];
|
||||
test := &btoui64tests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
}
|
||||
for i := range atoi64tests {
|
||||
test := &atoi64tests[i];
|
||||
test := &atoi64tests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
}
|
||||
for i := range btoi64tests {
|
||||
test := &btoi64tests[i];
|
||||
test := &btoi64tests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
}
|
||||
for i := range atoui32tests {
|
||||
test := &atoui32tests[i];
|
||||
test := &atoui32tests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
}
|
||||
for i := range atoi32tests {
|
||||
test := &atoi32tests[i];
|
||||
test := &atoi32tests[i]
|
||||
if test.err != nil {
|
||||
test.err = &NumError{test.in, test.err}
|
||||
}
|
||||
@ -190,8 +190,8 @@ func init() {
|
||||
|
||||
func TestAtoui64(t *testing.T) {
|
||||
for i := range atoui64tests {
|
||||
test := &atoui64tests[i];
|
||||
out, err := Atoui64(test.in);
|
||||
test := &atoui64tests[i]
|
||||
out, err := Atoui64(test.in)
|
||||
if test.out != out || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Atoui64(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -201,8 +201,8 @@ func TestAtoui64(t *testing.T) {
|
||||
|
||||
func TestBtoui64(t *testing.T) {
|
||||
for i := range btoui64tests {
|
||||
test := &btoui64tests[i];
|
||||
out, err := Btoui64(test.in, 0);
|
||||
test := &btoui64tests[i]
|
||||
out, err := Btoui64(test.in, 0)
|
||||
if test.out != out || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Btoui64(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -212,8 +212,8 @@ func TestBtoui64(t *testing.T) {
|
||||
|
||||
func TestAtoi64(t *testing.T) {
|
||||
for i := range atoi64tests {
|
||||
test := &atoi64tests[i];
|
||||
out, err := Atoi64(test.in);
|
||||
test := &atoi64tests[i]
|
||||
out, err := Atoi64(test.in)
|
||||
if test.out != out || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Atoi64(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -223,8 +223,8 @@ func TestAtoi64(t *testing.T) {
|
||||
|
||||
func TestBtoi64(t *testing.T) {
|
||||
for i := range btoi64tests {
|
||||
test := &btoi64tests[i];
|
||||
out, err := Btoi64(test.in, 0);
|
||||
test := &btoi64tests[i]
|
||||
out, err := Btoi64(test.in, 0)
|
||||
if test.out != out || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Btoi64(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -236,8 +236,8 @@ func TestAtoui(t *testing.T) {
|
||||
switch IntSize {
|
||||
case 32:
|
||||
for i := range atoui32tests {
|
||||
test := &atoui32tests[i];
|
||||
out, err := Atoui(test.in);
|
||||
test := &atoui32tests[i]
|
||||
out, err := Atoui(test.in)
|
||||
if test.out != uint32(out) || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Atoui(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -245,8 +245,8 @@ func TestAtoui(t *testing.T) {
|
||||
}
|
||||
case 64:
|
||||
for i := range atoui64tests {
|
||||
test := &atoui64tests[i];
|
||||
out, err := Atoui(test.in);
|
||||
test := &atoui64tests[i]
|
||||
out, err := Atoui(test.in)
|
||||
if test.out != uint64(out) || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Atoui(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -259,8 +259,8 @@ func TestAtoi(t *testing.T) {
|
||||
switch IntSize {
|
||||
case 32:
|
||||
for i := range atoi32tests {
|
||||
test := &atoi32tests[i];
|
||||
out, err := Atoi(test.in);
|
||||
test := &atoi32tests[i]
|
||||
out, err := Atoi(test.in)
|
||||
if test.out != int32(out) || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Atoi(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
@ -268,8 +268,8 @@ func TestAtoi(t *testing.T) {
|
||||
}
|
||||
case 64:
|
||||
for i := range atoi64tests {
|
||||
test := &atoi64tests[i];
|
||||
out, err := Atoi(test.in);
|
||||
test := &atoi64tests[i]
|
||||
out, err := Atoi(test.in)
|
||||
if test.out != int64(out) || !reflect.DeepEqual(test.err, err) {
|
||||
t.Errorf("Atoi(%q) = %v, %v want %v, %v\n",
|
||||
test.in, out, err, test.out, test.err)
|
||||
|
@ -14,13 +14,13 @@ package strconv
|
||||
type decimal struct {
|
||||
// TODO(rsc): Can make d[] a bit smaller and add
|
||||
// truncated bool;
|
||||
d [2000]byte; // digits
|
||||
nd int; // number of digits used
|
||||
dp int; // decimal point
|
||||
d [2000]byte // digits
|
||||
nd int // number of digits used
|
||||
dp int // decimal point
|
||||
}
|
||||
|
||||
func (a *decimal) String() string {
|
||||
n := 10 + a.nd;
|
||||
n := 10 + a.nd
|
||||
if a.dp > 0 {
|
||||
n += a.dp
|
||||
}
|
||||
@ -28,48 +28,48 @@ func (a *decimal) String() string {
|
||||
n += -a.dp
|
||||
}
|
||||
|
||||
buf := make([]byte, n);
|
||||
w := 0;
|
||||
buf := make([]byte, n)
|
||||
w := 0
|
||||
switch {
|
||||
case a.nd == 0:
|
||||
return "0"
|
||||
|
||||
case a.dp <= 0:
|
||||
// zeros fill space between decimal point and digits
|
||||
buf[w] = '0';
|
||||
w++;
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
w += digitZero(buf[w : w+-a.dp]);
|
||||
w += copy(buf[w:w+a.nd], a.d[0:a.nd]);
|
||||
buf[w] = '0'
|
||||
w++
|
||||
buf[w] = '.'
|
||||
w++
|
||||
w += digitZero(buf[w : w+-a.dp])
|
||||
w += copy(buf[w:w+a.nd], a.d[0:a.nd])
|
||||
|
||||
case a.dp < a.nd:
|
||||
// decimal point in middle of digits
|
||||
w += copy(buf[w:w+a.dp], a.d[0:a.dp]);
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
w += copy(buf[w:w+a.nd-a.dp], a.d[a.dp:a.nd]);
|
||||
w += copy(buf[w:w+a.dp], a.d[0:a.dp])
|
||||
buf[w] = '.'
|
||||
w++
|
||||
w += copy(buf[w:w+a.nd-a.dp], a.d[a.dp:a.nd])
|
||||
|
||||
default:
|
||||
// zeros fill space between digits and decimal point
|
||||
w += copy(buf[w:w+a.nd], a.d[0:a.nd]);
|
||||
w += digitZero(buf[w : w+a.dp-a.nd]);
|
||||
w += copy(buf[w:w+a.nd], a.d[0:a.nd])
|
||||
w += digitZero(buf[w : w+a.dp-a.nd])
|
||||
}
|
||||
return string(buf[0:w]);
|
||||
return string(buf[0:w])
|
||||
}
|
||||
|
||||
func copy(dst []byte, src []byte) int {
|
||||
for i := 0; i < len(dst); i++ {
|
||||
dst[i] = src[i]
|
||||
}
|
||||
return len(dst);
|
||||
return len(dst)
|
||||
}
|
||||
|
||||
func digitZero(dst []byte) int {
|
||||
for i := 0; i < len(dst); i++ {
|
||||
dst[i] = '0'
|
||||
}
|
||||
return len(dst);
|
||||
return len(dst)
|
||||
}
|
||||
|
||||
// trim trailing zeros from number.
|
||||
@ -86,32 +86,32 @@ func trim(a *decimal) {
|
||||
|
||||
// Assign v to a.
|
||||
func (a *decimal) Assign(v uint64) {
|
||||
var buf [50]byte;
|
||||
var buf [50]byte
|
||||
|
||||
// Write reversed decimal in buf.
|
||||
n := 0;
|
||||
n := 0
|
||||
for v > 0 {
|
||||
v1 := v / 10;
|
||||
v -= 10 * v1;
|
||||
buf[n] = byte(v + '0');
|
||||
n++;
|
||||
v = v1;
|
||||
v1 := v / 10
|
||||
v -= 10 * v1
|
||||
buf[n] = byte(v + '0')
|
||||
n++
|
||||
v = v1
|
||||
}
|
||||
|
||||
// Reverse again to produce forward decimal in a.d.
|
||||
a.nd = 0;
|
||||
a.nd = 0
|
||||
for n--; n >= 0; n-- {
|
||||
a.d[a.nd] = buf[n];
|
||||
a.nd++;
|
||||
a.d[a.nd] = buf[n]
|
||||
a.nd++
|
||||
}
|
||||
a.dp = a.nd;
|
||||
trim(a);
|
||||
a.dp = a.nd
|
||||
trim(a)
|
||||
}
|
||||
|
||||
func newDecimal(i uint64) *decimal {
|
||||
a := new(decimal);
|
||||
a.Assign(i);
|
||||
return a;
|
||||
a := new(decimal)
|
||||
a.Assign(i)
|
||||
return a
|
||||
}
|
||||
|
||||
// Maximum shift that we can do in one pass without overflow.
|
||||
@ -120,50 +120,50 @@ const maxShift = 27
|
||||
|
||||
// Binary shift right (* 2) by k bits. k <= maxShift to avoid overflow.
|
||||
func rightShift(a *decimal, k uint) {
|
||||
r := 0; // read pointer
|
||||
w := 0; // write pointer
|
||||
r := 0 // read pointer
|
||||
w := 0 // write pointer
|
||||
|
||||
// Pick up enough leading digits to cover first shift.
|
||||
n := 0;
|
||||
n := 0
|
||||
for ; n>>k == 0; r++ {
|
||||
if r >= a.nd {
|
||||
if n == 0 {
|
||||
// a == 0; shouldn't get here, but handle anyway.
|
||||
a.nd = 0;
|
||||
return;
|
||||
a.nd = 0
|
||||
return
|
||||
}
|
||||
for n>>k == 0 {
|
||||
n = n * 10;
|
||||
r++;
|
||||
n = n * 10
|
||||
r++
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
c := int(a.d[r]);
|
||||
n = n*10 + c - '0';
|
||||
c := int(a.d[r])
|
||||
n = n*10 + c - '0'
|
||||
}
|
||||
a.dp -= r - 1;
|
||||
a.dp -= r - 1
|
||||
|
||||
// Pick up a digit, put down a digit.
|
||||
for ; r < a.nd; r++ {
|
||||
c := int(a.d[r]);
|
||||
dig := n >> k;
|
||||
n -= dig << k;
|
||||
a.d[w] = byte(dig + '0');
|
||||
w++;
|
||||
n = n*10 + c - '0';
|
||||
c := int(a.d[r])
|
||||
dig := n >> k
|
||||
n -= dig << k
|
||||
a.d[w] = byte(dig + '0')
|
||||
w++
|
||||
n = n*10 + c - '0'
|
||||
}
|
||||
|
||||
// Put down extra digits.
|
||||
for n > 0 {
|
||||
dig := n >> k;
|
||||
n -= dig << k;
|
||||
a.d[w] = byte(dig + '0');
|
||||
w++;
|
||||
n = n * 10;
|
||||
dig := n >> k
|
||||
n -= dig << k
|
||||
a.d[w] = byte(dig + '0')
|
||||
w++
|
||||
n = n * 10
|
||||
}
|
||||
|
||||
a.nd = w;
|
||||
trim(a);
|
||||
a.nd = w
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Cheat sheet for left shift: table indexed by shift count giving
|
||||
@ -177,8 +177,8 @@ func rightShift(a *decimal, k uint) {
|
||||
// Credit for this trick goes to Ken.
|
||||
|
||||
type leftCheat struct {
|
||||
delta int; // number of new digits
|
||||
cutoff string; // minus one digit if original < a.
|
||||
delta int // number of new digits
|
||||
cutoff string // minus one digit if original < a.
|
||||
}
|
||||
|
||||
var leftcheats = []leftCheat{
|
||||
@ -195,33 +195,33 @@ var leftcheats = []leftCheat{
|
||||
}'
|
||||
*/
|
||||
leftCheat{0, ""},
|
||||
leftCheat{1, "5"}, // * 2
|
||||
leftCheat{1, "25"}, // * 4
|
||||
leftCheat{1, "125"}, // * 8
|
||||
leftCheat{2, "625"}, // * 16
|
||||
leftCheat{2, "3125"}, // * 32
|
||||
leftCheat{2, "15625"}, // * 64
|
||||
leftCheat{3, "78125"}, // * 128
|
||||
leftCheat{3, "390625"}, // * 256
|
||||
leftCheat{3, "1953125"}, // * 512
|
||||
leftCheat{4, "9765625"}, // * 1024
|
||||
leftCheat{4, "48828125"}, // * 2048
|
||||
leftCheat{4, "244140625"}, // * 4096
|
||||
leftCheat{4, "1220703125"}, // * 8192
|
||||
leftCheat{5, "6103515625"}, // * 16384
|
||||
leftCheat{5, "30517578125"}, // * 32768
|
||||
leftCheat{5, "152587890625"}, // * 65536
|
||||
leftCheat{6, "762939453125"}, // * 131072
|
||||
leftCheat{6, "3814697265625"}, // * 262144
|
||||
leftCheat{6, "19073486328125"}, // * 524288
|
||||
leftCheat{7, "95367431640625"}, // * 1048576
|
||||
leftCheat{7, "476837158203125"}, // * 2097152
|
||||
leftCheat{7, "2384185791015625"}, // * 4194304
|
||||
leftCheat{7, "11920928955078125"}, // * 8388608
|
||||
leftCheat{8, "59604644775390625"}, // * 16777216
|
||||
leftCheat{8, "298023223876953125"}, // * 33554432
|
||||
leftCheat{8, "1490116119384765625"}, // * 67108864
|
||||
leftCheat{9, "7450580596923828125"}, // * 134217728
|
||||
leftCheat{1, "5"}, // * 2
|
||||
leftCheat{1, "25"}, // * 4
|
||||
leftCheat{1, "125"}, // * 8
|
||||
leftCheat{2, "625"}, // * 16
|
||||
leftCheat{2, "3125"}, // * 32
|
||||
leftCheat{2, "15625"}, // * 64
|
||||
leftCheat{3, "78125"}, // * 128
|
||||
leftCheat{3, "390625"}, // * 256
|
||||
leftCheat{3, "1953125"}, // * 512
|
||||
leftCheat{4, "9765625"}, // * 1024
|
||||
leftCheat{4, "48828125"}, // * 2048
|
||||
leftCheat{4, "244140625"}, // * 4096
|
||||
leftCheat{4, "1220703125"}, // * 8192
|
||||
leftCheat{5, "6103515625"}, // * 16384
|
||||
leftCheat{5, "30517578125"}, // * 32768
|
||||
leftCheat{5, "152587890625"}, // * 65536
|
||||
leftCheat{6, "762939453125"}, // * 131072
|
||||
leftCheat{6, "3814697265625"}, // * 262144
|
||||
leftCheat{6, "19073486328125"}, // * 524288
|
||||
leftCheat{7, "95367431640625"}, // * 1048576
|
||||
leftCheat{7, "476837158203125"}, // * 2097152
|
||||
leftCheat{7, "2384185791015625"}, // * 4194304
|
||||
leftCheat{7, "11920928955078125"}, // * 8388608
|
||||
leftCheat{8, "59604644775390625"}, // * 16777216
|
||||
leftCheat{8, "298023223876953125"}, // * 33554432
|
||||
leftCheat{8, "1490116119384765625"}, // * 67108864
|
||||
leftCheat{9, "7450580596923828125"}, // * 134217728
|
||||
}
|
||||
|
||||
// Is the leading prefix of b lexicographically less than s?
|
||||
@ -234,42 +234,42 @@ func prefixIsLessThan(b []byte, s string) bool {
|
||||
return b[i] < s[i]
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
// Binary shift left (/ 2) by k bits. k <= maxShift to avoid overflow.
|
||||
func leftShift(a *decimal, k uint) {
|
||||
delta := leftcheats[k].delta;
|
||||
delta := leftcheats[k].delta
|
||||
if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
|
||||
delta--
|
||||
}
|
||||
|
||||
r := a.nd; // read index
|
||||
w := a.nd + delta; // write index
|
||||
n := 0;
|
||||
r := a.nd // read index
|
||||
w := a.nd + delta // write index
|
||||
n := 0
|
||||
|
||||
// Pick up a digit, put down a digit.
|
||||
for r--; r >= 0; r-- {
|
||||
n += (int(a.d[r]) - '0') << k;
|
||||
quo := n / 10;
|
||||
rem := n - 10*quo;
|
||||
w--;
|
||||
a.d[w] = byte(rem + '0');
|
||||
n = quo;
|
||||
n += (int(a.d[r]) - '0') << k
|
||||
quo := n / 10
|
||||
rem := n - 10*quo
|
||||
w--
|
||||
a.d[w] = byte(rem + '0')
|
||||
n = quo
|
||||
}
|
||||
|
||||
// Put down extra digits.
|
||||
for n > 0 {
|
||||
quo := n / 10;
|
||||
rem := n - 10*quo;
|
||||
w--;
|
||||
a.d[w] = byte(rem + '0');
|
||||
n = quo;
|
||||
quo := n / 10
|
||||
rem := n - 10*quo
|
||||
w--
|
||||
a.d[w] = byte(rem + '0')
|
||||
n = quo
|
||||
}
|
||||
|
||||
a.nd += delta;
|
||||
a.dp += delta;
|
||||
trim(a);
|
||||
a.nd += delta
|
||||
a.dp += delta
|
||||
trim(a)
|
||||
}
|
||||
|
||||
// Binary shift left (k > 0) or right (k < 0).
|
||||
@ -280,18 +280,18 @@ func (a *decimal) Shift(k int) *decimal {
|
||||
// nothing to do: a == 0
|
||||
case k > 0:
|
||||
for k > maxShift {
|
||||
leftShift(a, maxShift);
|
||||
k -= maxShift;
|
||||
leftShift(a, maxShift)
|
||||
k -= maxShift
|
||||
}
|
||||
leftShift(a, uint(k));
|
||||
leftShift(a, uint(k))
|
||||
case k < 0:
|
||||
for k < -maxShift {
|
||||
rightShift(a, maxShift);
|
||||
k += maxShift;
|
||||
rightShift(a, maxShift)
|
||||
k += maxShift
|
||||
}
|
||||
rightShift(a, uint(-k));
|
||||
rightShift(a, uint(-k))
|
||||
}
|
||||
return a;
|
||||
return a
|
||||
}
|
||||
|
||||
// If we chop a at nd digits, should we round up?
|
||||
@ -299,11 +299,11 @@ func shouldRoundUp(a *decimal, nd int) bool {
|
||||
if nd <= 0 || nd >= a.nd {
|
||||
return false
|
||||
}
|
||||
if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
|
||||
if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
|
||||
return (a.d[nd-1]-'0')%2 != 0
|
||||
}
|
||||
// not halfway - digit tells all
|
||||
return a.d[nd] >= '5';
|
||||
return a.d[nd] >= '5'
|
||||
}
|
||||
|
||||
// Round a to nd digits (or fewer).
|
||||
@ -315,7 +315,7 @@ func (a *decimal) Round(nd int) *decimal {
|
||||
if shouldRoundUp(a, nd) {
|
||||
return a.RoundUp(nd)
|
||||
}
|
||||
return a.RoundDown(nd);
|
||||
return a.RoundDown(nd)
|
||||
}
|
||||
|
||||
// Round a down to nd digits (or fewer).
|
||||
@ -324,9 +324,9 @@ func (a *decimal) RoundDown(nd int) *decimal {
|
||||
if nd <= 0 || nd >= a.nd {
|
||||
return a
|
||||
}
|
||||
a.nd = nd;
|
||||
trim(a);
|
||||
return a;
|
||||
a.nd = nd
|
||||
trim(a)
|
||||
return a
|
||||
}
|
||||
|
||||
// Round a up to nd digits (or fewer).
|
||||
@ -338,20 +338,20 @@ func (a *decimal) RoundUp(nd int) *decimal {
|
||||
|
||||
// round up
|
||||
for i := nd - 1; i >= 0; i-- {
|
||||
c := a.d[i];
|
||||
if c < '9' { // can stop after this digit
|
||||
a.d[i]++;
|
||||
a.nd = i + 1;
|
||||
return a;
|
||||
c := a.d[i]
|
||||
if c < '9' { // can stop after this digit
|
||||
a.d[i]++
|
||||
a.nd = i + 1
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
// Number is all 9s.
|
||||
// Change to single 1 with adjusted decimal point.
|
||||
a.d[0] = '1';
|
||||
a.nd = 1;
|
||||
a.dp++;
|
||||
return a;
|
||||
a.d[0] = '1'
|
||||
a.nd = 1
|
||||
a.dp++
|
||||
return a
|
||||
}
|
||||
|
||||
// Extract integer part, rounded appropriately.
|
||||
@ -360,8 +360,8 @@ func (a *decimal) RoundedInteger() uint64 {
|
||||
if a.dp > 20 {
|
||||
return 0xFFFFFFFFFFFFFFFF
|
||||
}
|
||||
var i int;
|
||||
n := uint64(0);
|
||||
var i int
|
||||
n := uint64(0)
|
||||
for i = 0; i < a.dp && i < a.nd; i++ {
|
||||
n = n*10 + uint64(a.d[i]-'0')
|
||||
}
|
||||
@ -371,5 +371,5 @@ func (a *decimal) RoundedInteger() uint64 {
|
||||
if shouldRoundUp(a, a.dp) {
|
||||
n++
|
||||
}
|
||||
return n;
|
||||
return n
|
||||
}
|
||||
|
@ -5,14 +5,14 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
. "strconv";
|
||||
"testing";
|
||||
. "strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type shiftTest struct {
|
||||
i uint64;
|
||||
shift int;
|
||||
out string;
|
||||
i uint64
|
||||
shift int
|
||||
out string
|
||||
}
|
||||
|
||||
var shifttests = []shiftTest{
|
||||
@ -31,8 +31,8 @@ var shifttests = []shiftTest{
|
||||
|
||||
func TestDecimalShift(t *testing.T) {
|
||||
for i := 0; i < len(shifttests); i++ {
|
||||
test := &shifttests[i];
|
||||
s := NewDecimal(test.i).Shift(test.shift).String();
|
||||
test := &shifttests[i]
|
||||
s := NewDecimal(test.i).Shift(test.shift).String()
|
||||
if s != test.out {
|
||||
t.Errorf("Decimal %v << %v = %v, want %v\n",
|
||||
test.i, test.shift, s, test.out)
|
||||
@ -41,10 +41,10 @@ func TestDecimalShift(t *testing.T) {
|
||||
}
|
||||
|
||||
type roundTest struct {
|
||||
i uint64;
|
||||
nd int;
|
||||
down, round, up string;
|
||||
int uint64;
|
||||
i uint64
|
||||
nd int
|
||||
down, round, up string
|
||||
int uint64
|
||||
}
|
||||
|
||||
var roundtests = []roundTest{
|
||||
@ -67,18 +67,18 @@ var roundtests = []roundTest{
|
||||
|
||||
func TestDecimalRound(t *testing.T) {
|
||||
for i := 0; i < len(roundtests); i++ {
|
||||
test := &roundtests[i];
|
||||
s := NewDecimal(test.i).RoundDown(test.nd).String();
|
||||
test := &roundtests[i]
|
||||
s := NewDecimal(test.i).RoundDown(test.nd).String()
|
||||
if s != test.down {
|
||||
t.Errorf("Decimal %v RoundDown %d = %v, want %v\n",
|
||||
test.i, test.nd, s, test.down)
|
||||
}
|
||||
s = NewDecimal(test.i).Round(test.nd).String();
|
||||
s = NewDecimal(test.i).Round(test.nd).String()
|
||||
if s != test.round {
|
||||
t.Errorf("Decimal %v Round %d = %v, want %v\n",
|
||||
test.i, test.nd, s, test.down)
|
||||
}
|
||||
s = NewDecimal(test.i).RoundUp(test.nd).String();
|
||||
s = NewDecimal(test.i).RoundUp(test.nd).String()
|
||||
if s != test.up {
|
||||
t.Errorf("Decimal %v RoundUp %d = %v, want %v\n",
|
||||
test.i, test.nd, s, test.up)
|
||||
@ -87,9 +87,9 @@ func TestDecimalRound(t *testing.T) {
|
||||
}
|
||||
|
||||
type roundIntTest struct {
|
||||
i uint64;
|
||||
shift int;
|
||||
int uint64;
|
||||
i uint64
|
||||
shift int
|
||||
int uint64
|
||||
}
|
||||
|
||||
var roundinttests = []roundIntTest{
|
||||
@ -107,8 +107,8 @@ var roundinttests = []roundIntTest{
|
||||
|
||||
func TestDecimalRoundedInteger(t *testing.T) {
|
||||
for i := 0; i < len(roundinttests); i++ {
|
||||
test := roundinttests[i];
|
||||
int := NewDecimal(test.i).Shift(test.shift).RoundedInteger();
|
||||
test := roundinttests[i]
|
||||
int := NewDecimal(test.i).Shift(test.shift).RoundedInteger()
|
||||
if int != test.int {
|
||||
t.Errorf("Decimal %v >> %v RoundedInteger = %v, want %v\n",
|
||||
test.i, test.shift, int, test.int)
|
||||
|
@ -5,12 +5,12 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
"bufio";
|
||||
"fmt";
|
||||
"os";
|
||||
"strconv";
|
||||
"strings";
|
||||
"testing";
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func pow2(i int) float64 {
|
||||
@ -22,124 +22,124 @@ func pow2(i int) float64 {
|
||||
case i == 1:
|
||||
return 2
|
||||
}
|
||||
return pow2(i/2) * pow2(i-i/2);
|
||||
return pow2(i/2) * pow2(i-i/2)
|
||||
}
|
||||
|
||||
// Wrapper around strconv.Atof64. Handles dddddp+ddd (binary exponent)
|
||||
// itself, passes the rest on to strconv.Atof64.
|
||||
func myatof64(s string) (f float64, ok bool) {
|
||||
a := strings.Split(s, "p", 2);
|
||||
a := strings.Split(s, "p", 2)
|
||||
if len(a) == 2 {
|
||||
n, err := strconv.Atoi64(a[0]);
|
||||
n, err := strconv.Atoi64(a[0])
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
e, err1 := strconv.Atoi(a[1]);
|
||||
e, err1 := strconv.Atoi(a[1])
|
||||
if err1 != nil {
|
||||
println("bad e", a[1]);
|
||||
return 0, false;
|
||||
println("bad e", a[1])
|
||||
return 0, false
|
||||
}
|
||||
v := float64(n);
|
||||
v := float64(n)
|
||||
// We expect that v*pow2(e) fits in a float64,
|
||||
// but pow2(e) by itself may not. Be careful.
|
||||
if e <= -1000 {
|
||||
v *= pow2(-1000);
|
||||
e += 1000;
|
||||
v *= pow2(-1000)
|
||||
e += 1000
|
||||
for e < 0 {
|
||||
v /= 2;
|
||||
e++;
|
||||
v /= 2
|
||||
e++
|
||||
}
|
||||
return v, true;
|
||||
return v, true
|
||||
}
|
||||
if e >= 1000 {
|
||||
v *= pow2(1000);
|
||||
e -= 1000;
|
||||
v *= pow2(1000)
|
||||
e -= 1000
|
||||
for e > 0 {
|
||||
v *= 2;
|
||||
e--;
|
||||
v *= 2
|
||||
e--
|
||||
}
|
||||
return v, true;
|
||||
return v, true
|
||||
}
|
||||
return v * pow2(e), true;
|
||||
return v * pow2(e), true
|
||||
}
|
||||
f1, err := strconv.Atof64(s);
|
||||
f1, err := strconv.Atof64(s)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return f1, true;
|
||||
return f1, true
|
||||
}
|
||||
|
||||
// Wrapper around strconv.Atof32. Handles dddddp+ddd (binary exponent)
|
||||
// itself, passes the rest on to strconv.Atof32.
|
||||
func myatof32(s string) (f float32, ok bool) {
|
||||
a := strings.Split(s, "p", 2);
|
||||
a := strings.Split(s, "p", 2)
|
||||
if len(a) == 2 {
|
||||
n, err := strconv.Atoi(a[0]);
|
||||
n, err := strconv.Atoi(a[0])
|
||||
if err != nil {
|
||||
println("bad n", a[0]);
|
||||
return 0, false;
|
||||
println("bad n", a[0])
|
||||
return 0, false
|
||||
}
|
||||
e, err1 := strconv.Atoi(a[1]);
|
||||
e, err1 := strconv.Atoi(a[1])
|
||||
if err1 != nil {
|
||||
println("bad p", a[1]);
|
||||
return 0, false;
|
||||
println("bad p", a[1])
|
||||
return 0, false
|
||||
}
|
||||
return float32(float64(n) * pow2(e)), true;
|
||||
return float32(float64(n) * pow2(e)), true
|
||||
}
|
||||
f1, err1 := strconv.Atof32(s);
|
||||
f1, err1 := strconv.Atof32(s)
|
||||
if err1 != nil {
|
||||
return 0, false
|
||||
}
|
||||
return f1, true;
|
||||
return f1, true
|
||||
}
|
||||
|
||||
func TestFp(t *testing.T) {
|
||||
f, err := os.Open("testfp.txt", os.O_RDONLY, 0);
|
||||
f, err := os.Open("testfp.txt", os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
panicln("testfp: open testfp.txt:", err.String())
|
||||
}
|
||||
defer f.Close();
|
||||
defer f.Close()
|
||||
|
||||
b := bufio.NewReader(f);
|
||||
b := bufio.NewReader(f)
|
||||
|
||||
lineno := 0;
|
||||
lineno := 0
|
||||
for {
|
||||
line, err2 := b.ReadString('\n');
|
||||
line, err2 := b.ReadString('\n')
|
||||
if err2 == os.EOF {
|
||||
break
|
||||
}
|
||||
if err2 != nil {
|
||||
panicln("testfp: read testfp.txt:", err2.String())
|
||||
}
|
||||
line = line[0 : len(line)-1];
|
||||
lineno++;
|
||||
line = line[0 : len(line)-1]
|
||||
lineno++
|
||||
if len(line) == 0 || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
a := strings.Split(line, " ", 0);
|
||||
a := strings.Split(line, " ", 0)
|
||||
if len(a) != 4 {
|
||||
t.Error("testfp.txt:", lineno, ": wrong field count\n");
|
||||
continue;
|
||||
t.Error("testfp.txt:", lineno, ": wrong field count\n")
|
||||
continue
|
||||
}
|
||||
var s string;
|
||||
var v float64;
|
||||
var s string
|
||||
var v float64
|
||||
switch a[0] {
|
||||
case "float64":
|
||||
var ok bool;
|
||||
v, ok = myatof64(a[2]);
|
||||
var ok bool
|
||||
v, ok = myatof64(a[2])
|
||||
if !ok {
|
||||
t.Error("testfp.txt:", lineno, ": cannot atof64 ", a[2]);
|
||||
continue;
|
||||
t.Error("testfp.txt:", lineno, ": cannot atof64 ", a[2])
|
||||
continue
|
||||
}
|
||||
s = fmt.Sprintf(a[1], v);
|
||||
s = fmt.Sprintf(a[1], v)
|
||||
case "float32":
|
||||
v1, ok := myatof32(a[2]);
|
||||
v1, ok := myatof32(a[2])
|
||||
if !ok {
|
||||
t.Error("testfp.txt:", lineno, ": cannot atof32 ", a[2]);
|
||||
continue;
|
||||
t.Error("testfp.txt:", lineno, ": cannot atof32 ", a[2])
|
||||
continue
|
||||
}
|
||||
s = fmt.Sprintf(a[1], v1);
|
||||
v = float64(v1);
|
||||
s = fmt.Sprintf(a[1], v1)
|
||||
v = float64(v1)
|
||||
}
|
||||
if s != a[3] {
|
||||
t.Error("testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
|
||||
|
@ -14,9 +14,9 @@ import "math"
|
||||
|
||||
// TODO: move elsewhere?
|
||||
type floatInfo struct {
|
||||
mantbits uint;
|
||||
expbits uint;
|
||||
bias int;
|
||||
mantbits uint
|
||||
expbits uint
|
||||
bias int
|
||||
}
|
||||
|
||||
var float32info = floatInfo{23, 8, -127}
|
||||
@ -26,11 +26,11 @@ func floatsize() int {
|
||||
// Figure out whether float is float32 or float64.
|
||||
// 1e-35 is representable in both, but 1e-70
|
||||
// is too small for a float32.
|
||||
var f float = 1e-35;
|
||||
var f float = 1e-35
|
||||
if f*f == 0 {
|
||||
return 32
|
||||
}
|
||||
return 64;
|
||||
return 64
|
||||
}
|
||||
|
||||
// Floatsize gives the size of the float type, either 32 or 64.
|
||||
@ -69,13 +69,13 @@ func Ftoa(f float, fmt byte, prec int) string {
|
||||
if FloatSize == 32 {
|
||||
return Ftoa32(float32(f), fmt, prec)
|
||||
}
|
||||
return Ftoa64(float64(f), fmt, prec);
|
||||
return Ftoa64(float64(f), fmt, prec)
|
||||
}
|
||||
|
||||
func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
neg := bits>>flt.expbits>>flt.mantbits != 0;
|
||||
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1);
|
||||
mant := bits & (uint64(1)<<flt.mantbits - 1);
|
||||
neg := bits>>flt.expbits>>flt.mantbits != 0
|
||||
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
|
||||
mant := bits & (uint64(1)<<flt.mantbits - 1)
|
||||
|
||||
switch exp {
|
||||
case 1<<flt.expbits - 1:
|
||||
@ -86,7 +86,7 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
if neg {
|
||||
return "-Inf"
|
||||
}
|
||||
return "+Inf";
|
||||
return "+Inf"
|
||||
|
||||
case 0:
|
||||
// denormalized
|
||||
@ -96,7 +96,7 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
// add implicit top bit
|
||||
mant |= uint64(1) << flt.mantbits
|
||||
}
|
||||
exp += flt.bias;
|
||||
exp += flt.bias
|
||||
|
||||
// Pick off easy binary format.
|
||||
if fmt == 'b' {
|
||||
@ -107,14 +107,14 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
// The shift is exp - flt.mantbits because mant is a 1-bit integer
|
||||
// followed by a flt.mantbits fraction, and we are treating it as
|
||||
// a 1+flt.mantbits-bit integer.
|
||||
d := newDecimal(mant).Shift(exp - int(flt.mantbits));
|
||||
d := newDecimal(mant).Shift(exp - int(flt.mantbits))
|
||||
|
||||
// Round appropriately.
|
||||
// Negative precision means "only as much as needed to be exact."
|
||||
shortest := false;
|
||||
shortest := false
|
||||
if prec < 0 {
|
||||
shortest = true;
|
||||
roundShortest(d, mant, exp, flt);
|
||||
shortest = true
|
||||
roundShortest(d, mant, exp, flt)
|
||||
switch fmt {
|
||||
case 'e', 'E':
|
||||
prec = d.nd - 1
|
||||
@ -133,7 +133,7 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
if prec == 0 {
|
||||
prec = 1
|
||||
}
|
||||
d.Round(prec);
|
||||
d.Round(prec)
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,18 +150,18 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
// %e is used if the exponent from the conversion
|
||||
// is less than -4 or greater than or equal to the precision.
|
||||
// if precision was the shortest possible, use precision 6 for this decision.
|
||||
eprec := prec;
|
||||
eprec := prec
|
||||
if shortest {
|
||||
eprec = 6
|
||||
}
|
||||
exp := d.dp - 1;
|
||||
exp := d.dp - 1
|
||||
if exp < -4 || exp >= eprec {
|
||||
return fmtE(neg, d, prec-1, fmt+'e'-'g')
|
||||
}
|
||||
return fmtF(neg, d, max(prec-d.dp, 0));
|
||||
return fmtF(neg, d, max(prec-d.dp, 0))
|
||||
}
|
||||
|
||||
return "%" + string(fmt);
|
||||
return "%" + string(fmt)
|
||||
}
|
||||
|
||||
// Round d (= mant * 2^exp) to the shortest number of digits
|
||||
@ -170,8 +170,8 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string {
|
||||
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
||||
// If mantissa is zero, the number is zero; stop now.
|
||||
if mant == 0 {
|
||||
d.nd = 0;
|
||||
return;
|
||||
d.nd = 0
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(rsc): Unless exp == minexp, if the number of digits in d
|
||||
@ -186,7 +186,7 @@ func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
||||
// d = mant << (exp - mantbits)
|
||||
// Next highest floating point number is mant+1 << exp-mantbits.
|
||||
// Our upper bound is halfway inbetween, mant*2+1 << exp-mantbits-1.
|
||||
upper := newDecimal(mant*2 + 1).Shift(exp - int(flt.mantbits) - 1);
|
||||
upper := newDecimal(mant*2 + 1).Shift(exp - int(flt.mantbits) - 1)
|
||||
|
||||
// d = mant << (exp - mantbits)
|
||||
// Next lowest floating point number is mant-1 << exp-mantbits,
|
||||
@ -194,33 +194,33 @@ func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
||||
// in which case the next lowest is mant*2-1 << exp-mantbits-1.
|
||||
// Either way, call it mantlo << explo-mantbits.
|
||||
// Our lower bound is halfway inbetween, mantlo*2+1 << explo-mantbits-1.
|
||||
minexp := flt.bias + 1; // minimum possible exponent
|
||||
var mantlo uint64;
|
||||
var explo int;
|
||||
minexp := flt.bias + 1 // minimum possible exponent
|
||||
var mantlo uint64
|
||||
var explo int
|
||||
if mant > 1<<flt.mantbits || exp == minexp {
|
||||
mantlo = mant - 1;
|
||||
explo = exp;
|
||||
mantlo = mant - 1
|
||||
explo = exp
|
||||
} else {
|
||||
mantlo = mant*2 - 1;
|
||||
explo = exp - 1;
|
||||
mantlo = mant*2 - 1
|
||||
explo = exp - 1
|
||||
}
|
||||
lower := newDecimal(mantlo*2 + 1).Shift(explo - int(flt.mantbits) - 1);
|
||||
lower := newDecimal(mantlo*2 + 1).Shift(explo - int(flt.mantbits) - 1)
|
||||
|
||||
// The upper and lower bounds are possible outputs only if
|
||||
// the original mantissa is even, so that IEEE round-to-even
|
||||
// would round to the original mantissa and not the neighbors.
|
||||
inclusive := mant%2 == 0;
|
||||
inclusive := mant%2 == 0
|
||||
|
||||
// Now we can figure out the minimum number of digits required.
|
||||
// Walk along until d has distinguished itself from upper and lower.
|
||||
for i := 0; i < d.nd; i++ {
|
||||
var l, m, u byte; // lower, middle, upper digits
|
||||
var l, m, u byte // lower, middle, upper digits
|
||||
if i < lower.nd {
|
||||
l = lower.d[i]
|
||||
} else {
|
||||
l = '0'
|
||||
}
|
||||
m = d.d[i];
|
||||
m = d.d[i]
|
||||
if i < upper.nd {
|
||||
u = upper.d[i]
|
||||
} else {
|
||||
@ -229,37 +229,37 @@ func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
||||
|
||||
// Okay to round down (truncate) if lower has a different digit
|
||||
// or if lower is inclusive and is exactly the result of rounding down.
|
||||
okdown := l != m || (inclusive && l == m && i+1 == lower.nd);
|
||||
okdown := l != m || (inclusive && l == m && i+1 == lower.nd)
|
||||
|
||||
// Okay to round up if upper has a different digit and
|
||||
// either upper is inclusive or upper is bigger than the result of rounding up.
|
||||
okup := m != u && (inclusive || i+1 < upper.nd);
|
||||
okup := m != u && (inclusive || i+1 < upper.nd)
|
||||
|
||||
// If it's okay to do either, then round to the nearest one.
|
||||
// If it's okay to do only one, do it.
|
||||
switch {
|
||||
case okdown && okup:
|
||||
d.Round(i + 1);
|
||||
return;
|
||||
d.Round(i + 1)
|
||||
return
|
||||
case okdown:
|
||||
d.RoundDown(i + 1);
|
||||
return;
|
||||
d.RoundDown(i + 1)
|
||||
return
|
||||
case okup:
|
||||
d.RoundUp(i + 1);
|
||||
return;
|
||||
d.RoundUp(i + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// %e: -d.ddddde±dd
|
||||
func fmtE(neg bool, d *decimal, prec int, fmt byte) string {
|
||||
buf := make([]byte, 3+max(prec, 0)+30); // "-0." + prec digits + exp
|
||||
w := 0; // write index
|
||||
buf := make([]byte, 3+max(prec, 0)+30) // "-0." + prec digits + exp
|
||||
w := 0 // write index
|
||||
|
||||
// sign
|
||||
if neg {
|
||||
buf[w] = '-';
|
||||
w++;
|
||||
buf[w] = '-'
|
||||
w++
|
||||
}
|
||||
|
||||
// first digit
|
||||
@ -268,141 +268,141 @@ func fmtE(neg bool, d *decimal, prec int, fmt byte) string {
|
||||
} else {
|
||||
buf[w] = d.d[0]
|
||||
}
|
||||
w++;
|
||||
w++
|
||||
|
||||
// .moredigits
|
||||
if prec > 0 {
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
buf[w] = '.'
|
||||
w++
|
||||
for i := 0; i < prec; i++ {
|
||||
if 1+i < d.nd {
|
||||
buf[w] = d.d[1+i]
|
||||
} else {
|
||||
buf[w] = '0'
|
||||
}
|
||||
w++;
|
||||
w++
|
||||
}
|
||||
}
|
||||
|
||||
// e±
|
||||
buf[w] = fmt;
|
||||
w++;
|
||||
exp := d.dp - 1;
|
||||
if d.nd == 0 { // special case: 0 has exponent 0
|
||||
buf[w] = fmt
|
||||
w++
|
||||
exp := d.dp - 1
|
||||
if d.nd == 0 { // special case: 0 has exponent 0
|
||||
exp = 0
|
||||
}
|
||||
if exp < 0 {
|
||||
buf[w] = '-';
|
||||
exp = -exp;
|
||||
buf[w] = '-'
|
||||
exp = -exp
|
||||
} else {
|
||||
buf[w] = '+'
|
||||
}
|
||||
w++;
|
||||
w++
|
||||
|
||||
// dddd
|
||||
// count digits
|
||||
n := 0;
|
||||
n := 0
|
||||
for e := exp; e > 0; e /= 10 {
|
||||
n++
|
||||
}
|
||||
// leading zeros
|
||||
for i := n; i < 2; i++ {
|
||||
buf[w] = '0';
|
||||
w++;
|
||||
buf[w] = '0'
|
||||
w++
|
||||
}
|
||||
// digits
|
||||
w += n;
|
||||
n = 0;
|
||||
w += n
|
||||
n = 0
|
||||
for e := exp; e > 0; e /= 10 {
|
||||
n++;
|
||||
buf[w-n] = byte(e%10 + '0');
|
||||
n++
|
||||
buf[w-n] = byte(e%10 + '0')
|
||||
}
|
||||
|
||||
return string(buf[0:w]);
|
||||
return string(buf[0:w])
|
||||
}
|
||||
|
||||
// %f: -ddddddd.ddddd
|
||||
func fmtF(neg bool, d *decimal, prec int) string {
|
||||
buf := make([]byte, 1+max(d.dp, 1)+1+max(prec, 0));
|
||||
w := 0;
|
||||
buf := make([]byte, 1+max(d.dp, 1)+1+max(prec, 0))
|
||||
w := 0
|
||||
|
||||
// sign
|
||||
if neg {
|
||||
buf[w] = '-';
|
||||
w++;
|
||||
buf[w] = '-'
|
||||
w++
|
||||
}
|
||||
|
||||
// integer, padded with zeros as needed.
|
||||
if d.dp > 0 {
|
||||
var i int;
|
||||
var i int
|
||||
for i = 0; i < d.dp && i < d.nd; i++ {
|
||||
buf[w] = d.d[i];
|
||||
w++;
|
||||
buf[w] = d.d[i]
|
||||
w++
|
||||
}
|
||||
for ; i < d.dp; i++ {
|
||||
buf[w] = '0';
|
||||
w++;
|
||||
buf[w] = '0'
|
||||
w++
|
||||
}
|
||||
} else {
|
||||
buf[w] = '0';
|
||||
w++;
|
||||
buf[w] = '0'
|
||||
w++
|
||||
}
|
||||
|
||||
// fraction
|
||||
if prec > 0 {
|
||||
buf[w] = '.';
|
||||
w++;
|
||||
buf[w] = '.'
|
||||
w++
|
||||
for i := 0; i < prec; i++ {
|
||||
if d.dp+i < 0 || d.dp+i >= d.nd {
|
||||
buf[w] = '0'
|
||||
} else {
|
||||
buf[w] = d.d[d.dp+i]
|
||||
}
|
||||
w++;
|
||||
w++
|
||||
}
|
||||
}
|
||||
|
||||
return string(buf[0:w]);
|
||||
return string(buf[0:w])
|
||||
}
|
||||
|
||||
// %b: -ddddddddp+ddd
|
||||
func fmtB(neg bool, mant uint64, exp int, flt *floatInfo) string {
|
||||
var buf [50]byte;
|
||||
w := len(buf);
|
||||
exp -= int(flt.mantbits);
|
||||
esign := byte('+');
|
||||
var buf [50]byte
|
||||
w := len(buf)
|
||||
exp -= int(flt.mantbits)
|
||||
esign := byte('+')
|
||||
if exp < 0 {
|
||||
esign = '-';
|
||||
exp = -exp;
|
||||
esign = '-'
|
||||
exp = -exp
|
||||
}
|
||||
n := 0;
|
||||
n := 0
|
||||
for exp > 0 || n < 1 {
|
||||
n++;
|
||||
w--;
|
||||
buf[w] = byte(exp%10 + '0');
|
||||
exp /= 10;
|
||||
n++
|
||||
w--
|
||||
buf[w] = byte(exp%10 + '0')
|
||||
exp /= 10
|
||||
}
|
||||
w--;
|
||||
buf[w] = esign;
|
||||
w--;
|
||||
buf[w] = 'p';
|
||||
n = 0;
|
||||
w--
|
||||
buf[w] = esign
|
||||
w--
|
||||
buf[w] = 'p'
|
||||
n = 0
|
||||
for mant > 0 || n < 1 {
|
||||
n++;
|
||||
w--;
|
||||
buf[w] = byte(mant%10 + '0');
|
||||
mant /= 10;
|
||||
n++
|
||||
w--
|
||||
buf[w] = byte(mant%10 + '0')
|
||||
mant /= 10
|
||||
}
|
||||
if neg {
|
||||
w--;
|
||||
buf[w] = '-';
|
||||
w--
|
||||
buf[w] = '-'
|
||||
}
|
||||
return string(buf[w:]);
|
||||
return string(buf[w:])
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b;
|
||||
return b
|
||||
}
|
||||
|
@ -5,23 +5,23 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
"math";
|
||||
. "strconv";
|
||||
"testing";
|
||||
"math"
|
||||
. "strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type ftoaTest struct {
|
||||
f float64;
|
||||
fmt byte;
|
||||
prec int;
|
||||
s string;
|
||||
f float64
|
||||
fmt byte
|
||||
prec int
|
||||
s string
|
||||
}
|
||||
|
||||
func fdiv(a, b float64) float64 { return a / b } // keep compiler in the dark
|
||||
func fdiv(a, b float64) float64 { return a / b } // keep compiler in the dark
|
||||
|
||||
const (
|
||||
below1e23 = 99999999999999974834176;
|
||||
above1e23 = 100000000000000008388608;
|
||||
below1e23 = 99999999999999974834176
|
||||
above1e23 = 100000000000000008388608
|
||||
)
|
||||
|
||||
var ftoatests = []ftoaTest{
|
||||
@ -104,13 +104,13 @@ func TestFtoa(t *testing.T) {
|
||||
panic("floatsize: ", FloatSize)
|
||||
}
|
||||
for i := 0; i < len(ftoatests); i++ {
|
||||
test := &ftoatests[i];
|
||||
s := Ftoa64(test.f, test.fmt, test.prec);
|
||||
test := &ftoatests[i]
|
||||
s := Ftoa64(test.f, test.fmt, test.prec)
|
||||
if s != test.s {
|
||||
t.Error("test", test.f, string(test.fmt), test.prec, "want", test.s, "got", s)
|
||||
}
|
||||
if float64(float32(test.f)) == test.f && test.fmt != 'b' {
|
||||
s := Ftoa32(float32(test.f), test.fmt, test.prec);
|
||||
s := Ftoa32(float32(test.f), test.fmt, test.prec)
|
||||
if s != test.s {
|
||||
t.Error("test32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s)
|
||||
}
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
package strconv
|
||||
|
||||
func NewDecimal(i uint64) *decimal { return newDecimal(i) }
|
||||
func NewDecimal(i uint64) *decimal { return newDecimal(i) }
|
||||
|
||||
func SetOptimize(b bool) bool {
|
||||
old := optimize;
|
||||
optimize = b;
|
||||
return old;
|
||||
old := optimize
|
||||
optimize = b
|
||||
return old
|
||||
}
|
||||
|
@ -11,16 +11,16 @@ func Uitob64(u uint64, base uint) string {
|
||||
}
|
||||
|
||||
// Assemble decimal in reverse order.
|
||||
var buf [32]byte;
|
||||
j := len(buf);
|
||||
b := uint64(base);
|
||||
var buf [32]byte
|
||||
j := len(buf)
|
||||
b := uint64(base)
|
||||
for u > 0 {
|
||||
j--;
|
||||
buf[j] = "0123456789abcdefghijklmnopqrstuvwxyz"[u%b];
|
||||
u /= b;
|
||||
j--
|
||||
buf[j] = "0123456789abcdefghijklmnopqrstuvwxyz"[u%b]
|
||||
u /= b
|
||||
}
|
||||
|
||||
return string(buf[j:]);
|
||||
return string(buf[j:])
|
||||
}
|
||||
|
||||
// Itob64 returns the string representation of i in the given base.
|
||||
@ -32,23 +32,23 @@ func Itob64(i int64, base uint) string {
|
||||
if i < 0 {
|
||||
return "-" + Uitob64(-uint64(i), base)
|
||||
}
|
||||
return Uitob64(uint64(i), base);
|
||||
return Uitob64(uint64(i), base)
|
||||
}
|
||||
|
||||
// Itoa64 returns the decimal string representation of i.
|
||||
func Itoa64(i int64) string { return Itob64(i, 10) }
|
||||
func Itoa64(i int64) string { return Itob64(i, 10) }
|
||||
|
||||
// Uitoa64 returns the decimal string representation of i.
|
||||
func Uitoa64(i uint64) string { return Uitob64(i, 10) }
|
||||
func Uitoa64(i uint64) string { return Uitob64(i, 10) }
|
||||
|
||||
// Uitob returns the string representation of i in the given base.
|
||||
func Uitob(i uint, base uint) string { return Uitob64(uint64(i), base) }
|
||||
func Uitob(i uint, base uint) string { return Uitob64(uint64(i), base) }
|
||||
|
||||
// Itob returns the string representation of i in the given base.
|
||||
func Itob(i int, base uint) string { return Itob64(int64(i), base) }
|
||||
func Itob(i int, base uint) string { return Itob64(int64(i), base) }
|
||||
|
||||
// Itoa returns the decimal string representation of i.
|
||||
func Itoa(i int) string { return Itob64(int64(i), 10) }
|
||||
func Itoa(i int) string { return Itob64(int64(i), 10) }
|
||||
|
||||
// Uitoa returns the decimal string representation of i.
|
||||
func Uitoa(i uint) string { return Uitob64(uint64(i), 10) }
|
||||
func Uitoa(i uint) string { return Uitob64(uint64(i), 10) }
|
||||
|
@ -5,14 +5,14 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
. "strconv";
|
||||
"testing";
|
||||
. "strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type itob64Test struct {
|
||||
in int64;
|
||||
base uint;
|
||||
out string;
|
||||
in int64
|
||||
base uint
|
||||
out string
|
||||
}
|
||||
|
||||
var itob64tests = []itob64Test{
|
||||
@ -59,14 +59,14 @@ var itob64tests = []itob64Test{
|
||||
|
||||
func TestItoa(t *testing.T) {
|
||||
for _, test := range itob64tests {
|
||||
s := Itob64(test.in, test.base);
|
||||
s := Itob64(test.in, test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Itob64(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
}
|
||||
|
||||
if test.in >= 0 {
|
||||
s := Uitob64(uint64(test.in), test.base);
|
||||
s := Uitob64(uint64(test.in), test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Uitob64(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
@ -74,14 +74,14 @@ func TestItoa(t *testing.T) {
|
||||
}
|
||||
|
||||
if int64(int(test.in)) == test.in {
|
||||
s := Itob(int(test.in), test.base);
|
||||
s := Itob(int(test.in), test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Itob(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
}
|
||||
|
||||
if test.in >= 0 {
|
||||
s := Uitob(uint(test.in), test.base);
|
||||
s := Uitob(uint(test.in), test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Uitob(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
@ -90,14 +90,14 @@ func TestItoa(t *testing.T) {
|
||||
}
|
||||
|
||||
if test.base == 10 {
|
||||
s := Itoa64(test.in);
|
||||
s := Itoa64(test.in)
|
||||
if s != test.out {
|
||||
t.Errorf("Itoa64(%v) = %v want %v\n",
|
||||
test.in, s, test.out)
|
||||
}
|
||||
|
||||
if test.in >= 0 {
|
||||
s := Uitob64(uint64(test.in), test.base);
|
||||
s := Uitob64(uint64(test.in), test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Uitob64(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
@ -105,14 +105,14 @@ func TestItoa(t *testing.T) {
|
||||
}
|
||||
|
||||
if int64(int(test.in)) == test.in {
|
||||
s := Itoa(int(test.in));
|
||||
s := Itoa(int(test.in))
|
||||
if s != test.out {
|
||||
t.Errorf("Itoa(%v) = %v want %v\n",
|
||||
test.in, s, test.out)
|
||||
}
|
||||
|
||||
if test.in >= 0 {
|
||||
s := Uitoa(uint(test.in));
|
||||
s := Uitoa(uint(test.in))
|
||||
if s != test.out {
|
||||
t.Errorf("Uitoa(%v) = %v want %v\n",
|
||||
test.in, s, test.out)
|
||||
@ -124,9 +124,9 @@ func TestItoa(t *testing.T) {
|
||||
}
|
||||
|
||||
type uitob64Test struct {
|
||||
in uint64;
|
||||
base uint;
|
||||
out string;
|
||||
in uint64
|
||||
base uint
|
||||
out string
|
||||
}
|
||||
|
||||
var uitob64tests = []uitob64Test{
|
||||
@ -139,14 +139,14 @@ var uitob64tests = []uitob64Test{
|
||||
|
||||
func TestUitoa(t *testing.T) {
|
||||
for _, test := range uitob64tests {
|
||||
s := Uitob64(test.in, test.base);
|
||||
s := Uitob64(test.in, test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Uitob64(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
}
|
||||
|
||||
if uint64(uint(test.in)) == test.in {
|
||||
s := Uitob(uint(test.in), test.base);
|
||||
s := Uitob(uint(test.in), test.base)
|
||||
if s != test.out {
|
||||
t.Errorf("Uitob(%v, %v) = %v want %v\n",
|
||||
test.in, test.base, s, test.out)
|
||||
@ -154,14 +154,14 @@ func TestUitoa(t *testing.T) {
|
||||
}
|
||||
|
||||
if test.base == 10 {
|
||||
s := Uitoa64(test.in);
|
||||
s := Uitoa64(test.in)
|
||||
if s != test.out {
|
||||
t.Errorf("Uitoa64(%v) = %v want %v\n",
|
||||
test.in, s, test.out)
|
||||
}
|
||||
|
||||
if uint64(uint(test.in)) == test.in {
|
||||
s := Uitoa(uint(test.in));
|
||||
s := Uitoa(uint(test.in))
|
||||
if s != test.out {
|
||||
t.Errorf("Uitoa(%v) = %v want %v\n",
|
||||
test.in, s, test.out)
|
||||
|
@ -5,11 +5,11 @@
|
||||
package strconv
|
||||
|
||||
import (
|
||||
"bytes";
|
||||
"os";
|
||||
"strings";
|
||||
"unicode";
|
||||
"utf8";
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
"utf8"
|
||||
)
|
||||
|
||||
const lowerhex = "0123456789abcdef"
|
||||
@ -19,8 +19,8 @@ const lowerhex = "0123456789abcdef"
|
||||
// sequences (\t, \n, \xFF, \u0100) for control characters
|
||||
// and non-ASCII characters.
|
||||
func Quote(s string) string {
|
||||
var buf bytes.Buffer;
|
||||
buf.WriteByte('"');
|
||||
var buf bytes.Buffer
|
||||
buf.WriteByte('"')
|
||||
for ; len(s) > 0; s = s[1:] {
|
||||
switch c := s[0]; {
|
||||
case c == '"':
|
||||
@ -45,18 +45,18 @@ func Quote(s string) string {
|
||||
buf.WriteString(`\v`)
|
||||
|
||||
case c >= utf8.RuneSelf && utf8.FullRuneInString(s):
|
||||
r, size := utf8.DecodeRuneInString(s);
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
if r == utf8.RuneError && size == 1 {
|
||||
goto EscX
|
||||
}
|
||||
s = s[size-1:]; // next iteration will slice off 1 more
|
||||
s = s[size-1:] // next iteration will slice off 1 more
|
||||
if r < 0x10000 {
|
||||
buf.WriteString(`\u`);
|
||||
buf.WriteString(`\u`)
|
||||
for j := uint(0); j < 4; j++ {
|
||||
buf.WriteByte(lowerhex[(r>>(12-4*j))&0xF])
|
||||
}
|
||||
} else {
|
||||
buf.WriteString(`\U`);
|
||||
buf.WriteString(`\U`)
|
||||
for j := uint(0); j < 8; j++ {
|
||||
buf.WriteByte(lowerhex[(r>>(28-4*j))&0xF])
|
||||
}
|
||||
@ -64,13 +64,13 @@ func Quote(s string) string {
|
||||
|
||||
default:
|
||||
EscX:
|
||||
buf.WriteString(`\x`);
|
||||
buf.WriteByte(lowerhex[c>>4]);
|
||||
buf.WriteByte(lowerhex[c&0xF]);
|
||||
buf.WriteString(`\x`)
|
||||
buf.WriteByte(lowerhex[c>>4])
|
||||
buf.WriteByte(lowerhex[c&0xF])
|
||||
}
|
||||
}
|
||||
buf.WriteByte('"');
|
||||
return buf.String();
|
||||
buf.WriteByte('"')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// CanBackquote returns whether the string s would be
|
||||
@ -81,11 +81,11 @@ func CanBackquote(s string) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
func unhex(b byte) (v int, ok bool) {
|
||||
c := int(b);
|
||||
c := int(b)
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
return c - '0', true
|
||||
@ -94,7 +94,7 @@ func unhex(b byte) (v int, ok bool) {
|
||||
case 'A' <= c && c <= 'F':
|
||||
return c - 'A' + 10, true
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// UnquoteChar decodes the first character or byte in the escaped string
|
||||
@ -114,22 +114,22 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
|
||||
// easy cases
|
||||
switch c := s[0]; {
|
||||
case c == quote && (quote == '\'' || quote == '"'):
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
case c >= utf8.RuneSelf:
|
||||
r, size := utf8.DecodeRuneInString(s);
|
||||
return r, true, s[size:], nil;
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
return r, true, s[size:], nil
|
||||
case c != '\\':
|
||||
return int(s[0]), false, s[1:], nil
|
||||
}
|
||||
|
||||
// hard case: c is backslash
|
||||
if len(s) <= 1 {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
c := s[1];
|
||||
s = s[2:];
|
||||
c := s[1]
|
||||
s = s[2:]
|
||||
|
||||
switch c {
|
||||
case 'a':
|
||||
@ -147,7 +147,7 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
|
||||
case 'v':
|
||||
value = '\v'
|
||||
case 'x', 'u', 'U':
|
||||
n := 0;
|
||||
n := 0
|
||||
switch c {
|
||||
case 'x':
|
||||
n = 2
|
||||
@ -156,64 +156,64 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
|
||||
case 'U':
|
||||
n = 8
|
||||
}
|
||||
v := 0;
|
||||
v := 0
|
||||
if len(s) < n {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
for j := 0; j < n; j++ {
|
||||
x, ok := unhex(s[j]);
|
||||
x, ok := unhex(s[j])
|
||||
if !ok {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
v = v<<4 | x;
|
||||
v = v<<4 | x
|
||||
}
|
||||
s = s[n:];
|
||||
s = s[n:]
|
||||
if c == 'x' {
|
||||
// single-byte string, possibly not UTF-8
|
||||
value = v;
|
||||
break;
|
||||
value = v
|
||||
break
|
||||
}
|
||||
if v > unicode.MaxRune {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
value = v;
|
||||
multibyte = true;
|
||||
value = v
|
||||
multibyte = true
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
v := int(c) - '0';
|
||||
v := int(c) - '0'
|
||||
if len(s) < 2 {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
for j := 0; j < 2; j++ { // one digit already; two more
|
||||
x := int(s[j]) - '0';
|
||||
for j := 0; j < 2; j++ { // one digit already; two more
|
||||
x := int(s[j]) - '0'
|
||||
if x < 0 || x > 7 {
|
||||
return
|
||||
}
|
||||
v = (v << 3) | x;
|
||||
v = (v << 3) | x
|
||||
}
|
||||
s = s[2:];
|
||||
s = s[2:]
|
||||
if v > 255 {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
value = v;
|
||||
value = v
|
||||
case '\\':
|
||||
value = '\\'
|
||||
case '\'', '"':
|
||||
if c != quote {
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
value = int(c);
|
||||
value = int(c)
|
||||
default:
|
||||
err = os.EINVAL;
|
||||
return;
|
||||
err = os.EINVAL
|
||||
return
|
||||
}
|
||||
tail = s;
|
||||
return;
|
||||
tail = s
|
||||
return
|
||||
}
|
||||
|
||||
// Unquote interprets s as a single-quoted, double-quoted,
|
||||
@ -222,33 +222,33 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
|
||||
// character literal; Unquote returns the corresponding
|
||||
// one-character string.)
|
||||
func Unquote(s string) (t string, err os.Error) {
|
||||
n := len(s);
|
||||
n := len(s)
|
||||
if n < 2 {
|
||||
return "", os.EINVAL
|
||||
}
|
||||
quote := s[0];
|
||||
quote := s[0]
|
||||
if quote != s[n-1] {
|
||||
return "", os.EINVAL
|
||||
}
|
||||
s = s[1 : n-1];
|
||||
s = s[1 : n-1]
|
||||
|
||||
if quote == '`' {
|
||||
if strings.Index(s, "`") >= 0 {
|
||||
return "", os.EINVAL
|
||||
}
|
||||
return s, nil;
|
||||
return s, nil
|
||||
}
|
||||
if quote != '"' && quote != '\'' {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer;
|
||||
var buf bytes.Buffer
|
||||
for len(s) > 0 {
|
||||
c, multibyte, ss, err := UnquoteChar(s, quote);
|
||||
c, multibyte, ss, err := UnquoteChar(s, quote)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s = ss;
|
||||
s = ss
|
||||
if c < utf8.RuneSelf || !multibyte {
|
||||
buf.WriteByte(byte(c))
|
||||
} else {
|
||||
@ -259,5 +259,5 @@ func Unquote(s string) (t string, err os.Error) {
|
||||
return "", os.EINVAL
|
||||
}
|
||||
}
|
||||
return buf.String(), nil;
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
@ -5,14 +5,14 @@
|
||||
package strconv_test
|
||||
|
||||
import (
|
||||
"os";
|
||||
. "strconv";
|
||||
"testing";
|
||||
"os"
|
||||
. "strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type quoteTest struct {
|
||||
in string;
|
||||
out string;
|
||||
in string
|
||||
out string
|
||||
}
|
||||
|
||||
var quotetests = []quoteTest{
|
||||
@ -26,7 +26,7 @@ var quotetests = []quoteTest{
|
||||
|
||||
func TestQuote(t *testing.T) {
|
||||
for i := 0; i < len(quotetests); i++ {
|
||||
tt := quotetests[i];
|
||||
tt := quotetests[i]
|
||||
if out := Quote(tt.in); out != tt.out {
|
||||
t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
|
||||
}
|
||||
@ -34,8 +34,8 @@ func TestQuote(t *testing.T) {
|
||||
}
|
||||
|
||||
type canBackquoteTest struct {
|
||||
in string;
|
||||
out bool;
|
||||
in string
|
||||
out bool
|
||||
}
|
||||
|
||||
var canbackquotetests = []canBackquoteTest{
|
||||
@ -49,7 +49,7 @@ var canbackquotetests = []canBackquoteTest{
|
||||
canBackquoteTest{string(6), false},
|
||||
canBackquoteTest{string(7), false},
|
||||
canBackquoteTest{string(8), false},
|
||||
canBackquoteTest{string(9), true}, // \t
|
||||
canBackquoteTest{string(9), true}, // \t
|
||||
canBackquoteTest{string(10), false},
|
||||
canBackquoteTest{string(11), false},
|
||||
canBackquoteTest{string(12), false},
|
||||
@ -81,7 +81,7 @@ var canbackquotetests = []canBackquoteTest{
|
||||
|
||||
func TestCanBackquote(t *testing.T) {
|
||||
for i := 0; i < len(canbackquotetests); i++ {
|
||||
tt := canbackquotetests[i];
|
||||
tt := canbackquotetests[i]
|
||||
if out := CanBackquote(tt.in); out != tt.out {
|
||||
t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
|
||||
}
|
||||
@ -147,7 +147,7 @@ var misquoted = []string{
|
||||
|
||||
func TestUnquote(t *testing.T) {
|
||||
for i := 0; i < len(unquotetests); i++ {
|
||||
tt := unquotetests[i];
|
||||
tt := unquotetests[i]
|
||||
if out, err := Unquote(tt.in); err != nil && out != tt.out {
|
||||
t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
|
||||
}
|
||||
@ -155,14 +155,14 @@ func TestUnquote(t *testing.T) {
|
||||
|
||||
// run the quote tests too, backward
|
||||
for i := 0; i < len(quotetests); i++ {
|
||||
tt := quotetests[i];
|
||||
tt := quotetests[i]
|
||||
if in, err := Unquote(tt.out); in != tt.in {
|
||||
t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(misquoted); i++ {
|
||||
s := misquoted[i];
|
||||
s := misquoted[i]
|
||||
if out, err := Unquote(s); out != "" || err != os.EINVAL {
|
||||
t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", os.EINVAL)
|
||||
}
|
||||
|
@ -11,28 +11,28 @@ import "os"
|
||||
type Reader string
|
||||
|
||||
func (r *Reader) Read(b []byte) (n int, err os.Error) {
|
||||
s := *r;
|
||||
s := *r
|
||||
if len(s) == 0 {
|
||||
return 0, os.EOF
|
||||
}
|
||||
for n < len(s) && n < len(b) {
|
||||
b[n] = s[n];
|
||||
n++;
|
||||
b[n] = s[n]
|
||||
n++
|
||||
}
|
||||
*r = s[n:];
|
||||
return;
|
||||
*r = s[n:]
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Reader) ReadByte() (b byte, err os.Error) {
|
||||
s := *r;
|
||||
s := *r
|
||||
if len(s) == 0 {
|
||||
return 0, os.EOF
|
||||
}
|
||||
b = s[0];
|
||||
*r = s[1:];
|
||||
return;
|
||||
b = s[0]
|
||||
*r = s[1:]
|
||||
return
|
||||
}
|
||||
|
||||
// NewReader returns a new Reader reading from s.
|
||||
// It is similar to bytes.NewBufferString but more efficient and read-only.
|
||||
func NewReader(s string) *Reader { return (*Reader)(&s) }
|
||||
func NewReader(s string) *Reader { return (*Reader)(&s) }
|
||||
|
@ -6,8 +6,8 @@
|
||||
package strings
|
||||
|
||||
import (
|
||||
"unicode";
|
||||
"utf8";
|
||||
"unicode"
|
||||
"utf8"
|
||||
)
|
||||
|
||||
// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n <= 0 means no limit).
|
||||
@ -16,21 +16,21 @@ func explode(s string, n int) []string {
|
||||
if n <= 0 {
|
||||
n = len(s)
|
||||
}
|
||||
a := make([]string, n);
|
||||
var size, rune int;
|
||||
na := 0;
|
||||
a := make([]string, n)
|
||||
var size, rune int
|
||||
na := 0
|
||||
for len(s) > 0 {
|
||||
if na+1 >= n {
|
||||
a[na] = s;
|
||||
na++;
|
||||
break;
|
||||
a[na] = s
|
||||
na++
|
||||
break
|
||||
}
|
||||
rune, size = utf8.DecodeRuneInString(s);
|
||||
s = s[size:];
|
||||
a[na] = string(rune);
|
||||
na++;
|
||||
rune, size = utf8.DecodeRuneInString(s)
|
||||
s = s[size:]
|
||||
a[na] = string(rune)
|
||||
na++
|
||||
}
|
||||
return a[0:na];
|
||||
return a[0:na]
|
||||
}
|
||||
|
||||
// Count counts the number of non-overlapping instances of sep in s.
|
||||
@ -38,24 +38,24 @@ func Count(s, sep string) int {
|
||||
if sep == "" {
|
||||
return utf8.RuneCountInString(s) + 1
|
||||
}
|
||||
c := sep[0];
|
||||
n := 0;
|
||||
c := sep[0]
|
||||
n := 0
|
||||
for i := 0; i+len(sep) <= len(s); i++ {
|
||||
if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) {
|
||||
n++;
|
||||
i += len(sep) - 1;
|
||||
n++
|
||||
i += len(sep) - 1
|
||||
}
|
||||
}
|
||||
return n;
|
||||
return n
|
||||
}
|
||||
|
||||
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
|
||||
func Index(s, sep string) int {
|
||||
n := len(sep);
|
||||
n := len(sep)
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
c := sep[0];
|
||||
c := sep[0]
|
||||
if n == 1 {
|
||||
// special case worth making fast
|
||||
for i := 0; i < len(s); i++ {
|
||||
@ -63,23 +63,23 @@ func Index(s, sep string) int {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
for i := 0; i+n <= len(s); i++ {
|
||||
if s[i] == c && (n == 1 || s[i:i+n] == sep) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
|
||||
// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
|
||||
func LastIndex(s, sep string) int {
|
||||
n := len(sep);
|
||||
n := len(sep)
|
||||
if n == 0 {
|
||||
return len(s)
|
||||
}
|
||||
c := sep[0];
|
||||
c := sep[0]
|
||||
if n == 1 {
|
||||
// special case worth making fast
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
@ -87,14 +87,14 @@ func LastIndex(s, sep string) int {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
for i := len(s) - n; i >= 0; i-- {
|
||||
if s[i] == c && (n == 1 || s[i:i+n] == sep) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1
|
||||
}
|
||||
|
||||
// Generic split: splits after each instance of sep,
|
||||
@ -106,26 +106,26 @@ func genSplit(s, sep string, sepSave, n int) []string {
|
||||
if n <= 0 {
|
||||
n = Count(s, sep) + 1
|
||||
}
|
||||
c := sep[0];
|
||||
start := 0;
|
||||
a := make([]string, n);
|
||||
na := 0;
|
||||
c := sep[0]
|
||||
start := 0
|
||||
a := make([]string, n)
|
||||
na := 0
|
||||
for i := 0; i+len(sep) <= len(s) && na+1 < n; i++ {
|
||||
if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) {
|
||||
a[na] = s[start : i+sepSave];
|
||||
na++;
|
||||
start = i + len(sep);
|
||||
i += len(sep) - 1;
|
||||
a[na] = s[start : i+sepSave]
|
||||
na++
|
||||
start = i + len(sep)
|
||||
i += len(sep) - 1
|
||||
}
|
||||
}
|
||||
a[na] = s[start:];
|
||||
return a[0 : na+1];
|
||||
a[na] = s[start:]
|
||||
return a[0 : na+1]
|
||||
}
|
||||
|
||||
// Split splits the string s around each instance of sep, returning an array of substrings of s.
|
||||
// If sep is empty, Split splits s after each UTF-8 sequence.
|
||||
// If n > 0, Split splits s into at most n substrings; the last substring will be the unsplit remainder.
|
||||
func Split(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
|
||||
func Split(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
|
||||
|
||||
// SplitAfter splits the string s after each instance of sep, returning an array of substrings of s.
|
||||
// If sep is empty, SplitAfter splits s after each UTF-8 sequence.
|
||||
@ -143,28 +143,28 @@ func Join(a []string, sep string) string {
|
||||
if len(a) == 1 {
|
||||
return a[0]
|
||||
}
|
||||
n := len(sep) * (len(a) - 1);
|
||||
n := len(sep) * (len(a) - 1)
|
||||
for i := 0; i < len(a); i++ {
|
||||
n += len(a[i])
|
||||
}
|
||||
|
||||
b := make([]byte, n);
|
||||
bp := 0;
|
||||
b := make([]byte, n)
|
||||
bp := 0
|
||||
for i := 0; i < len(a); i++ {
|
||||
s := a[i];
|
||||
s := a[i]
|
||||
for j := 0; j < len(s); j++ {
|
||||
b[bp] = s[j];
|
||||
bp++;
|
||||
b[bp] = s[j]
|
||||
bp++
|
||||
}
|
||||
if i+1 < len(a) {
|
||||
s = sep;
|
||||
s = sep
|
||||
for j := 0; j < len(s); j++ {
|
||||
b[bp] = s[j];
|
||||
bp++;
|
||||
b[bp] = s[j]
|
||||
bp++
|
||||
}
|
||||
}
|
||||
}
|
||||
return string(b);
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// HasPrefix tests whether the string s begins with prefix.
|
||||
@ -184,105 +184,105 @@ func Map(mapping func(rune int) int, s string) string {
|
||||
// In the worst case, the string can grow when mapped, making
|
||||
// things unpleasant. But it's so rare we barge in assuming it's
|
||||
// fine. It could also shrink but that falls out naturally.
|
||||
maxbytes := len(s); // length of b
|
||||
nbytes := 0; // number of bytes encoded in b
|
||||
b := make([]byte, maxbytes);
|
||||
maxbytes := len(s) // length of b
|
||||
nbytes := 0 // number of bytes encoded in b
|
||||
b := make([]byte, maxbytes)
|
||||
for _, c := range s {
|
||||
rune := mapping(c);
|
||||
rune := mapping(c)
|
||||
if rune >= 0 {
|
||||
wid := 1;
|
||||
wid := 1
|
||||
if rune >= utf8.RuneSelf {
|
||||
wid = utf8.RuneLen(rune)
|
||||
}
|
||||
if nbytes+wid > maxbytes {
|
||||
// Grow the buffer.
|
||||
maxbytes = maxbytes*2 + utf8.UTFMax;
|
||||
nb := make([]byte, maxbytes);
|
||||
maxbytes = maxbytes*2 + utf8.UTFMax
|
||||
nb := make([]byte, maxbytes)
|
||||
for i, c := range b[0:nbytes] {
|
||||
nb[i] = c
|
||||
}
|
||||
b = nb;
|
||||
b = nb
|
||||
}
|
||||
nbytes += utf8.EncodeRune(rune, b[nbytes:maxbytes]);
|
||||
nbytes += utf8.EncodeRune(rune, b[nbytes:maxbytes])
|
||||
}
|
||||
}
|
||||
return string(b[0:nbytes]);
|
||||
return string(b[0:nbytes])
|
||||
}
|
||||
|
||||
// Repeat returns a new string consisting of count copies of the string s.
|
||||
func Repeat(s string, count int) string {
|
||||
b := make([]byte, len(s)*count);
|
||||
bp := 0;
|
||||
b := make([]byte, len(s)*count)
|
||||
bp := 0
|
||||
for i := 0; i < count; i++ {
|
||||
for j := 0; j < len(s); j++ {
|
||||
b[bp] = s[j];
|
||||
bp++;
|
||||
b[bp] = s[j]
|
||||
bp++
|
||||
}
|
||||
}
|
||||
return string(b);
|
||||
return string(b)
|
||||
}
|
||||
|
||||
|
||||
// ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case.
|
||||
func ToUpper(s string) string { return Map(unicode.ToUpper, s) }
|
||||
func ToUpper(s string) string { return Map(unicode.ToUpper, s) }
|
||||
|
||||
// ToLower returns a copy of the string s with all Unicode letters mapped to their lower case.
|
||||
func ToLower(s string) string { return Map(unicode.ToLower, s) }
|
||||
func ToLower(s string) string { return Map(unicode.ToLower, s) }
|
||||
|
||||
// ToTitle returns a copy of the string s with all Unicode letters mapped to their title case.
|
||||
func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
|
||||
func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
|
||||
|
||||
// Trim returns a slice of the string s, with all leading and trailing white space
|
||||
// removed, as defined by Unicode.
|
||||
func TrimSpace(s string) string {
|
||||
start, end := 0, len(s);
|
||||
start, end := 0, len(s)
|
||||
for start < end {
|
||||
wid := 1;
|
||||
rune := int(s[start]);
|
||||
wid := 1
|
||||
rune := int(s[start])
|
||||
if rune >= utf8.RuneSelf {
|
||||
rune, wid = utf8.DecodeRuneInString(s[start:end])
|
||||
}
|
||||
if !unicode.IsSpace(rune) {
|
||||
break
|
||||
}
|
||||
start += wid;
|
||||
start += wid
|
||||
}
|
||||
for start < end {
|
||||
wid := 1;
|
||||
rune := int(s[end-1]);
|
||||
wid := 1
|
||||
rune := int(s[end-1])
|
||||
if rune >= utf8.RuneSelf {
|
||||
// Back up carefully looking for beginning of rune. Mustn't pass start.
|
||||
for wid = 2; start <= end-wid && !utf8.RuneStart(s[end-wid]); wid++ {
|
||||
}
|
||||
if start > end-wid { // invalid UTF-8 sequence; stop processing
|
||||
if start > end-wid { // invalid UTF-8 sequence; stop processing
|
||||
return s[start:end]
|
||||
}
|
||||
rune, wid = utf8.DecodeRuneInString(s[end-wid : end]);
|
||||
rune, wid = utf8.DecodeRuneInString(s[end-wid : end])
|
||||
}
|
||||
if !unicode.IsSpace(rune) {
|
||||
break
|
||||
}
|
||||
end -= wid;
|
||||
end -= wid
|
||||
}
|
||||
return s[start:end];
|
||||
return s[start:end]
|
||||
}
|
||||
|
||||
// Bytes returns a new slice containing the bytes in s.
|
||||
func Bytes(s string) []byte {
|
||||
b := make([]byte, len(s));
|
||||
b := make([]byte, len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
b[i] = s[i]
|
||||
}
|
||||
return b;
|
||||
return b
|
||||
}
|
||||
|
||||
// Runes returns a slice of runes (Unicode code points) equivalent to the string s.
|
||||
func Runes(s string) []int {
|
||||
t := make([]int, utf8.RuneCountInString(s));
|
||||
i := 0;
|
||||
t := make([]int, utf8.RuneCountInString(s))
|
||||
i := 0
|
||||
for _, r := range s {
|
||||
t[i] = r;
|
||||
i++;
|
||||
t[i] = r
|
||||
i++
|
||||
}
|
||||
return t;
|
||||
return t
|
||||
}
|
||||
|
@ -5,10 +5,10 @@
|
||||
package strings_test
|
||||
|
||||
import (
|
||||
. "strings";
|
||||
"testing";
|
||||
"unicode";
|
||||
"utf8";
|
||||
. "strings"
|
||||
"testing"
|
||||
"unicode"
|
||||
"utf8"
|
||||
)
|
||||
|
||||
func eq(a, b []string) bool {
|
||||
@ -20,7 +20,7 @@ func eq(a, b []string) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
var abcd = "abcd"
|
||||
@ -29,9 +29,9 @@ var commas = "1,2,3,4"
|
||||
var dots = "1....2....3....4"
|
||||
|
||||
type IndexTest struct {
|
||||
s string;
|
||||
sep string;
|
||||
out int;
|
||||
s string
|
||||
sep string
|
||||
out int
|
||||
}
|
||||
|
||||
var indexTests = []IndexTest{
|
||||
@ -76,22 +76,22 @@ var lastIndexTests = []IndexTest{
|
||||
// in failure reports.
|
||||
func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, testCases []IndexTest) {
|
||||
for _, test := range testCases {
|
||||
actual := f(test.s, test.sep);
|
||||
actual := f(test.s, test.sep)
|
||||
if actual != test.out {
|
||||
t.Errorf("%s(%q,%q) = %v; want %v", funcName, test.s, test.sep, actual, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
||||
func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }
|
||||
|
||||
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
||||
func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
|
||||
|
||||
|
||||
type ExplodeTest struct {
|
||||
s string;
|
||||
n int;
|
||||
a []string;
|
||||
s string
|
||||
n int
|
||||
a []string
|
||||
}
|
||||
|
||||
var explodetests = []ExplodeTest{
|
||||
@ -102,12 +102,12 @@ var explodetests = []ExplodeTest{
|
||||
|
||||
func TestExplode(t *testing.T) {
|
||||
for _, tt := range explodetests {
|
||||
a := Split(tt.s, "", tt.n);
|
||||
a := Split(tt.s, "", tt.n)
|
||||
if !eq(a, tt.a) {
|
||||
t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a);
|
||||
continue;
|
||||
t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a)
|
||||
continue
|
||||
}
|
||||
s := Join(a, "");
|
||||
s := Join(a, "")
|
||||
if s != tt.s {
|
||||
t.Errorf(`Join(explode(%q, %d), "") = %q`, tt.s, tt.n, s)
|
||||
}
|
||||
@ -115,10 +115,10 @@ func TestExplode(t *testing.T) {
|
||||
}
|
||||
|
||||
type SplitTest struct {
|
||||
s string;
|
||||
sep string;
|
||||
n int;
|
||||
a []string;
|
||||
s string
|
||||
sep string
|
||||
n int
|
||||
a []string
|
||||
}
|
||||
|
||||
var splittests = []SplitTest{
|
||||
@ -138,12 +138,12 @@ var splittests = []SplitTest{
|
||||
|
||||
func TestSplit(t *testing.T) {
|
||||
for _, tt := range splittests {
|
||||
a := Split(tt.s, tt.sep, tt.n);
|
||||
a := Split(tt.s, tt.sep, tt.n)
|
||||
if !eq(a, tt.a) {
|
||||
t.Errorf("Split(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, a, tt.a);
|
||||
continue;
|
||||
t.Errorf("Split(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, a, tt.a)
|
||||
continue
|
||||
}
|
||||
s := Join(a, tt.sep);
|
||||
s := Join(a, tt.sep)
|
||||
if s != tt.s {
|
||||
t.Errorf("Join(Split(%q, %q, %d), %q) = %q", tt.s, tt.sep, tt.n, tt.sep, s)
|
||||
}
|
||||
@ -168,12 +168,12 @@ var splitaftertests = []SplitTest{
|
||||
|
||||
func TestSplitAfter(t *testing.T) {
|
||||
for _, tt := range splitaftertests {
|
||||
a := SplitAfter(tt.s, tt.sep, tt.n);
|
||||
a := SplitAfter(tt.s, tt.sep, tt.n)
|
||||
if !eq(a, tt.a) {
|
||||
t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, a, tt.a);
|
||||
continue;
|
||||
t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, a, tt.a)
|
||||
continue
|
||||
}
|
||||
s := Join(a, "");
|
||||
s := Join(a, "")
|
||||
if s != tt.s {
|
||||
t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
|
||||
}
|
||||
@ -182,14 +182,14 @@ func TestSplitAfter(t *testing.T) {
|
||||
|
||||
// Test case for any function which accepts and returns a single string.
|
||||
type StringTest struct {
|
||||
in, out string;
|
||||
in, out string
|
||||
}
|
||||
|
||||
// Execute f on each test case. funcName should be the name of f; it's used
|
||||
// in failure reports.
|
||||
func runStringTests(t *testing.T, f func(string) string, funcName string, testCases []StringTest) {
|
||||
for _, tc := range testCases {
|
||||
actual := f(tc.in);
|
||||
actual := f(tc.in)
|
||||
if actual != tc.out {
|
||||
t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
|
||||
}
|
||||
@ -201,7 +201,7 @@ var upperTests = []StringTest{
|
||||
StringTest{"abc", "ABC"},
|
||||
StringTest{"AbC123", "ABC123"},
|
||||
StringTest{"azAZ09_", "AZAZ09_"},
|
||||
StringTest{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
|
||||
StringTest{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
|
||||
}
|
||||
|
||||
var lowerTests = []StringTest{
|
||||
@ -209,7 +209,7 @@ var lowerTests = []StringTest{
|
||||
StringTest{"abc", "abc"},
|
||||
StringTest{"AbC123", "abc123"},
|
||||
StringTest{"azAZ09_", "azaz09_"},
|
||||
StringTest{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
|
||||
StringTest{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
|
||||
}
|
||||
|
||||
const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
|
||||
@ -223,59 +223,59 @@ var trimSpaceTests = []StringTest{
|
||||
StringTest{" \t\r\n x\t\t\r\r\n\n ", "x"},
|
||||
StringTest{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", "x\t\t\r\r\ny"},
|
||||
StringTest{"1 \t\r\n2", "1 \t\r\n2"},
|
||||
StringTest{" x\x80", "x\x80"}, // invalid UTF-8 on end
|
||||
StringTest{" x\xc0", "x\xc0"}, // invalid UTF-8 on end
|
||||
StringTest{" x\x80", "x\x80"}, // invalid UTF-8 on end
|
||||
StringTest{" x\xc0", "x\xc0"}, // invalid UTF-8 on end
|
||||
}
|
||||
|
||||
func tenRunes(rune int) string {
|
||||
r := make([]int, 10);
|
||||
r := make([]int, 10)
|
||||
for i := range r {
|
||||
r[i] = rune
|
||||
}
|
||||
return string(r);
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// User-defined self-inverse mapping function
|
||||
func rot13(rune int) int {
|
||||
step := 13;
|
||||
step := 13
|
||||
if rune >= 'a' && rune <= 'z' {
|
||||
return ((rune - 'a' + step) % 26) + 'a'
|
||||
}
|
||||
if rune >= 'A' && rune <= 'Z' {
|
||||
return ((rune - 'A' + step) % 26) + 'A'
|
||||
}
|
||||
return rune;
|
||||
return rune
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
// Run a couple of awful growth/shrinkage tests
|
||||
a := tenRunes('a');
|
||||
a := tenRunes('a')
|
||||
// 1. Grow. This triggers two reallocations in Map.
|
||||
maxRune := func(rune int) int { return unicode.MaxRune };
|
||||
m := Map(maxRune, a);
|
||||
expect := tenRunes(unicode.MaxRune);
|
||||
maxRune := func(rune int) int { return unicode.MaxRune }
|
||||
m := Map(maxRune, a)
|
||||
expect := tenRunes(unicode.MaxRune)
|
||||
if m != expect {
|
||||
t.Errorf("growing: expected %q got %q", expect, m)
|
||||
}
|
||||
|
||||
// 2. Shrink
|
||||
minRune := func(rune int) int { return 'a' };
|
||||
m = Map(minRune, tenRunes(unicode.MaxRune));
|
||||
expect = a;
|
||||
minRune := func(rune int) int { return 'a' }
|
||||
m = Map(minRune, tenRunes(unicode.MaxRune))
|
||||
expect = a
|
||||
if m != expect {
|
||||
t.Errorf("shrinking: expected %q got %q", expect, m)
|
||||
}
|
||||
|
||||
// 3. Rot13
|
||||
m = Map(rot13, "a to zed");
|
||||
expect = "n gb mrq";
|
||||
m = Map(rot13, "a to zed")
|
||||
expect = "n gb mrq"
|
||||
if m != expect {
|
||||
t.Errorf("rot13: expected %q got %q", expect, m)
|
||||
}
|
||||
|
||||
// 4. Rot13^2
|
||||
m = Map(rot13, Map(rot13, "a to zed"));
|
||||
expect = "a to zed";
|
||||
m = Map(rot13, Map(rot13, "a to zed"))
|
||||
expect = "a to zed"
|
||||
if m != expect {
|
||||
t.Errorf("rot13: expected %q got %q", expect, m)
|
||||
}
|
||||
@ -285,50 +285,50 @@ func TestMap(t *testing.T) {
|
||||
if unicode.Is(unicode.Latin, rune) {
|
||||
return rune
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
m = Map(dropNotLatin, "Hello, 세계");
|
||||
expect = "Hello";
|
||||
return -1
|
||||
}
|
||||
m = Map(dropNotLatin, "Hello, 세계")
|
||||
expect = "Hello"
|
||||
if m != expect {
|
||||
t.Errorf("drop: expected %q got %q", expect, m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
||||
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
|
||||
|
||||
func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
|
||||
func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
|
||||
|
||||
func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
|
||||
func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
|
||||
|
||||
func equal(m string, s1, s2 string, t *testing.T) bool {
|
||||
if s1 == s2 {
|
||||
return true
|
||||
}
|
||||
e1 := Split(s1, "", 0);
|
||||
e2 := Split(s2, "", 0);
|
||||
e1 := Split(s1, "", 0)
|
||||
e2 := Split(s2, "", 0)
|
||||
for i, c1 := range e1 {
|
||||
if i > len(e2) {
|
||||
break
|
||||
}
|
||||
r1, _ := utf8.DecodeRuneInString(c1);
|
||||
r2, _ := utf8.DecodeRuneInString(e2[i]);
|
||||
r1, _ := utf8.DecodeRuneInString(c1)
|
||||
r2, _ := utf8.DecodeRuneInString(e2[i])
|
||||
if r1 != r2 {
|
||||
t.Errorf("%s diff at %d: U+%04X U+%04X", m, i, r1, r2)
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
func TestCaseConsistency(t *testing.T) {
|
||||
// Make a string of all the runes.
|
||||
a := make([]int, unicode.MaxRune+1);
|
||||
a := make([]int, unicode.MaxRune+1)
|
||||
for i := range a {
|
||||
a[i] = i
|
||||
}
|
||||
s := string(a);
|
||||
s := string(a)
|
||||
// convert the cases.
|
||||
upper := ToUpper(s);
|
||||
lower := ToLower(s);
|
||||
upper := ToUpper(s)
|
||||
lower := ToLower(s)
|
||||
|
||||
// Consistency checks
|
||||
if n := utf8.RuneCountInString(upper); n != unicode.MaxRune+1 {
|
||||
@ -360,8 +360,8 @@ func TestCaseConsistency(t *testing.T) {
|
||||
}
|
||||
|
||||
type RepeatTest struct {
|
||||
in, out string;
|
||||
count int;
|
||||
in, out string
|
||||
count int
|
||||
}
|
||||
|
||||
var RepeatTests = []RepeatTest{
|
||||
@ -376,10 +376,10 @@ var RepeatTests = []RepeatTest{
|
||||
|
||||
func TestRepeat(t *testing.T) {
|
||||
for _, tt := range RepeatTests {
|
||||
a := Repeat(tt.in, tt.count);
|
||||
a := Repeat(tt.in, tt.count)
|
||||
if !equal("Repeat(s)", a, tt.out, t) {
|
||||
t.Errorf("Repeat(%v, %d) = %v; want %v", tt.in, tt.count, a, tt.out);
|
||||
continue;
|
||||
t.Errorf("Repeat(%v, %d) = %v; want %v", tt.in, tt.count, a, tt.out)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -393,13 +393,13 @@ func runesEqual(a, b []int) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
type RunesTest struct {
|
||||
in string;
|
||||
out []int;
|
||||
lossy bool;
|
||||
in string
|
||||
out []int
|
||||
lossy bool
|
||||
}
|
||||
|
||||
var RunesTests = []RunesTest{
|
||||
@ -414,14 +414,14 @@ var RunesTests = []RunesTest{
|
||||
|
||||
func TestRunes(t *testing.T) {
|
||||
for _, tt := range RunesTests {
|
||||
a := Runes(tt.in);
|
||||
a := Runes(tt.in)
|
||||
if !runesEqual(a, tt.out) {
|
||||
t.Errorf("Runes(%q) = %v; want %v", tt.in, a, tt.out);
|
||||
continue;
|
||||
t.Errorf("Runes(%q) = %v; want %v", tt.in, a, tt.out)
|
||||
continue
|
||||
}
|
||||
if !tt.lossy {
|
||||
// can only test reassembly if we didn't lose information
|
||||
s := string(a);
|
||||
s := string(a)
|
||||
if s != tt.in {
|
||||
t.Errorf("string(Runes(%q)) = %x; want %x", tt.in, s, tt.in)
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ func cas(val *uint32, old, new uint32) bool
|
||||
// Mutexes can be created as part of other structures;
|
||||
// the zero value for a Mutex is an unlocked mutex.
|
||||
type Mutex struct {
|
||||
key uint32;
|
||||
sema uint32;
|
||||
key uint32
|
||||
sema uint32
|
||||
}
|
||||
|
||||
// Add delta to *val, and return the new *val in a thread-safe way. If multiple
|
||||
@ -25,13 +25,13 @@ type Mutex struct {
|
||||
// serialized, and all the deltas will be added in an undefined order.
|
||||
func xadd(val *uint32, delta int32) (new uint32) {
|
||||
for {
|
||||
v := *val;
|
||||
nv := v + uint32(delta);
|
||||
v := *val
|
||||
nv := v + uint32(delta)
|
||||
if cas(val, v, nv) {
|
||||
return nv
|
||||
}
|
||||
}
|
||||
panic("unreached");
|
||||
panic("unreached")
|
||||
}
|
||||
|
||||
// Lock locks m.
|
||||
@ -42,7 +42,7 @@ func (m *Mutex) Lock() {
|
||||
// changed from 0 to 1; we hold lock
|
||||
return
|
||||
}
|
||||
runtime.Semacquire(&m.sema);
|
||||
runtime.Semacquire(&m.sema)
|
||||
}
|
||||
|
||||
// Unlock unlocks m.
|
||||
@ -56,5 +56,5 @@ func (m *Mutex) Unlock() {
|
||||
// changed from 1 to 0; no contention
|
||||
return
|
||||
}
|
||||
runtime.Semrelease(&m.sema);
|
||||
runtime.Semrelease(&m.sema)
|
||||
}
|
||||
|
@ -7,23 +7,23 @@
|
||||
package sync_test
|
||||
|
||||
import (
|
||||
"runtime";
|
||||
. "sync";
|
||||
"testing";
|
||||
"runtime"
|
||||
. "sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func HammerSemaphore(s *uint32, loops int, cdone chan bool) {
|
||||
for i := 0; i < loops; i++ {
|
||||
runtime.Semacquire(s);
|
||||
runtime.Semrelease(s);
|
||||
runtime.Semacquire(s)
|
||||
runtime.Semrelease(s)
|
||||
}
|
||||
cdone <- true;
|
||||
cdone <- true
|
||||
}
|
||||
|
||||
func TestSemaphore(t *testing.T) {
|
||||
s := new(uint32);
|
||||
*s = 1;
|
||||
c := make(chan bool);
|
||||
s := new(uint32)
|
||||
*s = 1
|
||||
c := make(chan bool)
|
||||
for i := 0; i < 10; i++ {
|
||||
go HammerSemaphore(s, 1000, c)
|
||||
}
|
||||
@ -33,37 +33,37 @@ func TestSemaphore(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkUncontendedSemaphore(b *testing.B) {
|
||||
s := new(uint32);
|
||||
*s = 1;
|
||||
HammerSemaphore(s, b.N, make(chan bool, 2));
|
||||
s := new(uint32)
|
||||
*s = 1
|
||||
HammerSemaphore(s, b.N, make(chan bool, 2))
|
||||
}
|
||||
|
||||
func BenchmarkContendedSemaphore(b *testing.B) {
|
||||
b.StopTimer();
|
||||
s := new(uint32);
|
||||
*s = 1;
|
||||
c := make(chan bool);
|
||||
runtime.GOMAXPROCS(2);
|
||||
b.StartTimer();
|
||||
b.StopTimer()
|
||||
s := new(uint32)
|
||||
*s = 1
|
||||
c := make(chan bool)
|
||||
runtime.GOMAXPROCS(2)
|
||||
b.StartTimer()
|
||||
|
||||
go HammerSemaphore(s, b.N/2, c);
|
||||
go HammerSemaphore(s, b.N/2, c);
|
||||
<-c;
|
||||
<-c;
|
||||
go HammerSemaphore(s, b.N/2, c)
|
||||
go HammerSemaphore(s, b.N/2, c)
|
||||
<-c
|
||||
<-c
|
||||
}
|
||||
|
||||
|
||||
func HammerMutex(m *Mutex, loops int, cdone chan bool) {
|
||||
for i := 0; i < loops; i++ {
|
||||
m.Lock();
|
||||
m.Unlock();
|
||||
m.Lock()
|
||||
m.Unlock()
|
||||
}
|
||||
cdone <- true;
|
||||
cdone <- true
|
||||
}
|
||||
|
||||
func TestMutex(t *testing.T) {
|
||||
m := new(Mutex);
|
||||
c := make(chan bool);
|
||||
m := new(Mutex)
|
||||
c := make(chan bool)
|
||||
for i := 0; i < 10; i++ {
|
||||
go HammerMutex(m, 1000, c)
|
||||
}
|
||||
@ -73,19 +73,19 @@ func TestMutex(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkUncontendedMutex(b *testing.B) {
|
||||
m := new(Mutex);
|
||||
HammerMutex(m, b.N, make(chan bool, 2));
|
||||
m := new(Mutex)
|
||||
HammerMutex(m, b.N, make(chan bool, 2))
|
||||
}
|
||||
|
||||
func BenchmarkContendedMutex(b *testing.B) {
|
||||
b.StopTimer();
|
||||
m := new(Mutex);
|
||||
c := make(chan bool);
|
||||
runtime.GOMAXPROCS(2);
|
||||
b.StartTimer();
|
||||
b.StopTimer()
|
||||
m := new(Mutex)
|
||||
c := make(chan bool)
|
||||
runtime.GOMAXPROCS(2)
|
||||
b.StartTimer()
|
||||
|
||||
go HammerMutex(m, b.N/2, c);
|
||||
go HammerMutex(m, b.N/2, c);
|
||||
<-c;
|
||||
<-c;
|
||||
go HammerMutex(m, b.N/2, c)
|
||||
go HammerMutex(m, b.N/2, c)
|
||||
<-c
|
||||
<-c
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ package sync
|
||||
// Writers take priority over Readers: no new RLocks
|
||||
// are granted while a blocked Lock call is waiting.
|
||||
type RWMutex struct {
|
||||
w Mutex; // held if there are pending readers or writers
|
||||
r Mutex; // held if the w is being rd
|
||||
readerCount uint32; // number of pending readers
|
||||
w Mutex // held if there are pending readers or writers
|
||||
r Mutex // held if the w is being rd
|
||||
readerCount uint32 // number of pending readers
|
||||
}
|
||||
|
||||
// RLock locks rw for reading.
|
||||
@ -32,13 +32,13 @@ func (rw *RWMutex) RLock() {
|
||||
// C: rw.RLock() // granted
|
||||
// B: rw.RUnlock()
|
||||
// ... (new readers come and go indefinitely, W is starving)
|
||||
rw.r.Lock();
|
||||
rw.r.Lock()
|
||||
if xadd(&rw.readerCount, 1) == 1 {
|
||||
// The first reader locks rw.w, so writers will be blocked
|
||||
// while the readers have the RLock.
|
||||
rw.w.Lock()
|
||||
}
|
||||
rw.r.Unlock();
|
||||
rw.r.Unlock()
|
||||
}
|
||||
|
||||
// RUnlock undoes a single RLock call;
|
||||
@ -59,9 +59,9 @@ func (rw *RWMutex) RUnlock() {
|
||||
// a blocked Lock call excludes new readers from acquiring
|
||||
// the lock.
|
||||
func (rw *RWMutex) Lock() {
|
||||
rw.r.Lock();
|
||||
rw.w.Lock();
|
||||
rw.r.Unlock();
|
||||
rw.r.Lock()
|
||||
rw.w.Lock()
|
||||
rw.r.Unlock()
|
||||
}
|
||||
|
||||
// Unlock unlocks rw for writing.
|
||||
@ -72,4 +72,4 @@ func (rw *RWMutex) Lock() {
|
||||
// a locked RWMutex is not associated with a particular goroutine.
|
||||
// It is allowed for one goroutine to RLock (Lock) an RWMutex and then
|
||||
// arrange for another goroutine to RUnlock (Unlock) it.
|
||||
func (rw *RWMutex) Unlock() { rw.w.Unlock() }
|
||||
func (rw *RWMutex) Unlock() { rw.w.Unlock() }
|
||||
|
@ -7,26 +7,26 @@
|
||||
package sync_test
|
||||
|
||||
import (
|
||||
"fmt";
|
||||
"runtime";
|
||||
. "sync";
|
||||
"testing";
|
||||
"fmt"
|
||||
"runtime"
|
||||
. "sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
|
||||
m.RLock();
|
||||
clocked <- true;
|
||||
<-cunlock;
|
||||
m.RUnlock();
|
||||
cdone <- true;
|
||||
m.RLock()
|
||||
clocked <- true
|
||||
<-cunlock
|
||||
m.RUnlock()
|
||||
cdone <- true
|
||||
}
|
||||
|
||||
func doTestParallelReaders(numReaders, gomaxprocs int) {
|
||||
runtime.GOMAXPROCS(gomaxprocs);
|
||||
var m RWMutex;
|
||||
clocked := make(chan bool);
|
||||
cunlock := make(chan bool);
|
||||
cdone := make(chan bool);
|
||||
runtime.GOMAXPROCS(gomaxprocs)
|
||||
var m RWMutex
|
||||
clocked := make(chan bool)
|
||||
cunlock := make(chan bool)
|
||||
cdone := make(chan bool)
|
||||
for i := 0; i < numReaders; i++ {
|
||||
go parallelReader(&m, clocked, cunlock, cdone)
|
||||
}
|
||||
@ -44,53 +44,53 @@ func doTestParallelReaders(numReaders, gomaxprocs int) {
|
||||
}
|
||||
|
||||
func TestParallelReaders(t *testing.T) {
|
||||
doTestParallelReaders(1, 4);
|
||||
doTestParallelReaders(3, 4);
|
||||
doTestParallelReaders(4, 2);
|
||||
doTestParallelReaders(1, 4)
|
||||
doTestParallelReaders(3, 4)
|
||||
doTestParallelReaders(4, 2)
|
||||
}
|
||||
|
||||
func reader(rwm *RWMutex, num_iterations int, activity *uint32, cdone chan bool) {
|
||||
for i := 0; i < num_iterations; i++ {
|
||||
rwm.RLock();
|
||||
n := Xadd(activity, 1);
|
||||
rwm.RLock()
|
||||
n := Xadd(activity, 1)
|
||||
if n < 1 || n >= 10000 {
|
||||
panic(fmt.Sprintf("wlock(%d)\n", n))
|
||||
}
|
||||
for i := 0; i < 100; i++ {
|
||||
}
|
||||
Xadd(activity, -1);
|
||||
rwm.RUnlock();
|
||||
Xadd(activity, -1)
|
||||
rwm.RUnlock()
|
||||
}
|
||||
cdone <- true;
|
||||
cdone <- true
|
||||
}
|
||||
|
||||
func writer(rwm *RWMutex, num_iterations int, activity *uint32, cdone chan bool) {
|
||||
for i := 0; i < num_iterations; i++ {
|
||||
rwm.Lock();
|
||||
n := Xadd(activity, 10000);
|
||||
rwm.Lock()
|
||||
n := Xadd(activity, 10000)
|
||||
if n != 10000 {
|
||||
panic(fmt.Sprintf("wlock(%d)\n", n))
|
||||
}
|
||||
for i := 0; i < 100; i++ {
|
||||
}
|
||||
Xadd(activity, -10000);
|
||||
rwm.Unlock();
|
||||
Xadd(activity, -10000)
|
||||
rwm.Unlock()
|
||||
}
|
||||
cdone <- true;
|
||||
cdone <- true
|
||||
}
|
||||
|
||||
func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
|
||||
runtime.GOMAXPROCS(gomaxprocs);
|
||||
runtime.GOMAXPROCS(gomaxprocs)
|
||||
// Number of active readers + 10000 * number of active writers.
|
||||
var activity uint32;
|
||||
var rwm RWMutex;
|
||||
cdone := make(chan bool);
|
||||
go writer(&rwm, num_iterations, &activity, cdone);
|
||||
var i int;
|
||||
var activity uint32
|
||||
var rwm RWMutex
|
||||
cdone := make(chan bool)
|
||||
go writer(&rwm, num_iterations, &activity, cdone)
|
||||
var i int
|
||||
for i = 0; i < numReaders/2; i++ {
|
||||
go reader(&rwm, num_iterations, &activity, cdone)
|
||||
}
|
||||
go writer(&rwm, num_iterations, &activity, cdone);
|
||||
go writer(&rwm, num_iterations, &activity, cdone)
|
||||
for ; i < numReaders; i++ {
|
||||
go reader(&rwm, num_iterations, &activity, cdone)
|
||||
}
|
||||
@ -101,14 +101,14 @@ func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
|
||||
}
|
||||
|
||||
func TestRWMutex(t *testing.T) {
|
||||
HammerRWMutex(1, 1, 1000);
|
||||
HammerRWMutex(1, 3, 1000);
|
||||
HammerRWMutex(1, 10, 1000);
|
||||
HammerRWMutex(4, 1, 1000);
|
||||
HammerRWMutex(4, 3, 1000);
|
||||
HammerRWMutex(4, 10, 1000);
|
||||
HammerRWMutex(10, 1, 1000);
|
||||
HammerRWMutex(10, 3, 1000);
|
||||
HammerRWMutex(10, 10, 1000);
|
||||
HammerRWMutex(10, 5, 10000);
|
||||
HammerRWMutex(1, 1, 1000)
|
||||
HammerRWMutex(1, 3, 1000)
|
||||
HammerRWMutex(1, 10, 1000)
|
||||
HammerRWMutex(4, 1, 1000)
|
||||
HammerRWMutex(4, 3, 1000)
|
||||
HammerRWMutex(4, 10, 1000)
|
||||
HammerRWMutex(10, 1, 1000)
|
||||
HammerRWMutex(10, 3, 1000)
|
||||
HammerRWMutex(10, 10, 1000)
|
||||
HammerRWMutex(10, 5, 10000)
|
||||
}
|
||||
|
@ -5,24 +5,24 @@
|
||||
package syscall
|
||||
|
||||
|
||||
func str(val int) string { // do it here rather than with fmt to avoid dependency
|
||||
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;
|
||||
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%10 + '0')
|
||||
i--
|
||||
val /= 10
|
||||
}
|
||||
buf[i] = byte(val + '0');
|
||||
return string(buf[i:]);
|
||||
buf[i] = byte(val + '0')
|
||||
return string(buf[i:])
|
||||
}
|
||||
|
||||
func Errstr(errno int) string {
|
||||
if errno < 0 || errno >= int(len(errors)) {
|
||||
return "error " + str(errno)
|
||||
}
|
||||
return errors[errno];
|
||||
return errors[errno]
|
||||
}
|
||||
|
@ -7,8 +7,8 @@
|
||||
package syscall
|
||||
|
||||
import (
|
||||
"sync";
|
||||
"unsafe";
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Lock synchronizing creation of new file descriptors with fork.
|
||||
@ -63,18 +63,18 @@ var ForkLock sync.RWMutex
|
||||
// Convert array of string to array
|
||||
// of NUL-terminated byte pointer.
|
||||
func StringArrayPtr(ss []string) []*byte {
|
||||
bb := make([]*byte, len(ss)+1);
|
||||
bb := make([]*byte, len(ss)+1)
|
||||
for i := 0; i < len(ss); i++ {
|
||||
bb[i] = StringBytePtr(ss[i])
|
||||
}
|
||||
bb[len(ss)] = nil;
|
||||
return bb;
|
||||
bb[len(ss)] = nil
|
||||
return bb
|
||||
}
|
||||
|
||||
func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
|
||||
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);
|
||||
flag, err := fcntl(fd, F_GETFL, 0)
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
@ -83,8 +83,8 @@ func SetNonblock(fd int, nonblocking bool) (errno int) {
|
||||
} else {
|
||||
flag &= ^O_NONBLOCK
|
||||
}
|
||||
_, err = fcntl(fd, F_SETFL, flag);
|
||||
return err;
|
||||
_, err = fcntl(fd, F_SETFL, flag)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -99,15 +99,15 @@ func SetNonblock(fd int, nonblocking bool) (errno int) {
|
||||
func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, 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 uintptr;
|
||||
var nextfd int;
|
||||
var i int;
|
||||
var r1, r2, err1 uintptr
|
||||
var nextfd int
|
||||
var i int
|
||||
|
||||
darwin := OS == "darwin";
|
||||
darwin := OS == "darwin"
|
||||
|
||||
// About to call fork.
|
||||
// No more allocation or calls of non-assembly functions.
|
||||
r1, r2, err1 = RawSyscall(SYS_FORK, 0, 0, 0);
|
||||
r1, r2, err1 = RawSyscall(SYS_FORK, 0, 0, 0)
|
||||
if err1 != 0 {
|
||||
return 0, int(err1)
|
||||
}
|
||||
@ -129,7 +129,7 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, d
|
||||
|
||||
// Enable tracing if requested.
|
||||
if traceme {
|
||||
_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0);
|
||||
_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -137,7 +137,7 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, d
|
||||
|
||||
// Chdir
|
||||
if dir != nil {
|
||||
_, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0);
|
||||
_, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -145,26 +145,26 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, d
|
||||
|
||||
// Pass 1: look for fd[i] < i and move those up above len(fd)
|
||||
// so that pass 2 won't stomp on an fd it needs later.
|
||||
nextfd = int(len(fd));
|
||||
nextfd = int(len(fd))
|
||||
if pipe < nextfd {
|
||||
_, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0);
|
||||
_, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC);
|
||||
pipe = nextfd;
|
||||
nextfd++;
|
||||
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] < int(i) {
|
||||
_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0);
|
||||
_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC);
|
||||
fd[i] = nextfd;
|
||||
nextfd++;
|
||||
if nextfd == pipe { // don't stomp on pipe
|
||||
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
|
||||
fd[i] = nextfd
|
||||
nextfd++
|
||||
if nextfd == pipe { // don't stomp on pipe
|
||||
nextfd++
|
||||
}
|
||||
}
|
||||
@ -173,21 +173,21 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, d
|
||||
// Pass 2: dup fd[i] down onto i.
|
||||
for i = 0; i < len(fd); i++ {
|
||||
if fd[i] == -1 {
|
||||
RawSyscall(SYS_CLOSE, uintptr(i), 0, 0);
|
||||
continue;
|
||||
RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
|
||||
continue
|
||||
}
|
||||
if fd[i] == int(i) {
|
||||
// dup2(i, i) won't clear close-on-exec flag on Linux,
|
||||
// probably not elsewhere either.
|
||||
_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0);
|
||||
_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
// The new fd is created NOT close-on-exec,
|
||||
// which is exactly what we want.
|
||||
_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(i), 0);
|
||||
_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(i), 0)
|
||||
if err1 != 0 {
|
||||
goto childerror
|
||||
}
|
||||
@ -205,11 +205,11 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, d
|
||||
_, _, err1 = RawSyscall(SYS_EXECVE,
|
||||
uintptr(unsafe.Pointer(argv0)),
|
||||
uintptr(unsafe.Pointer(&argv[0])),
|
||||
uintptr(unsafe.Pointer(&envv[0])));
|
||||
uintptr(unsafe.Pointer(&envv[0])))
|
||||
|
||||
childerror:
|
||||
// send error code on pipe
|
||||
RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)));
|
||||
RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)))
|
||||
for {
|
||||
RawSyscall(SYS_EXIT, 253, 0, 0)
|
||||
}
|
||||
@ -217,23 +217,23 @@ childerror:
|
||||
// Calling panic is not actually safe,
|
||||
// but the for loop above won't break
|
||||
// and this shuts up the compiler.
|
||||
panic("unreached");
|
||||
panic("unreached")
|
||||
}
|
||||
|
||||
func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int) (pid int, err int) {
|
||||
var p [2]int;
|
||||
var n int;
|
||||
var err1 uintptr;
|
||||
var wstatus WaitStatus;
|
||||
var p [2]int
|
||||
var n int
|
||||
var err1 uintptr
|
||||
var wstatus WaitStatus
|
||||
|
||||
p[0] = -1;
|
||||
p[1] = -1;
|
||||
p[0] = -1
|
||||
p[1] = -1
|
||||
|
||||
// Convert args to C form.
|
||||
argv0p := StringBytePtr(argv0);
|
||||
argvp := StringArrayPtr(argv);
|
||||
envvp := StringArrayPtr(envv);
|
||||
var dirp *byte;
|
||||
argv0p := StringBytePtr(argv0)
|
||||
argvp := StringArrayPtr(argv)
|
||||
envvp := StringArrayPtr(envv)
|
||||
var dirp *byte
|
||||
if len(dir) > 0 {
|
||||
dirp = StringBytePtr(dir)
|
||||
}
|
||||
@ -241,7 +241,7 @@ func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir stri
|
||||
// Acquire the fork lock so that no other threads
|
||||
// create new fds that are not yet close-on-exec
|
||||
// before we fork.
|
||||
ForkLock.Lock();
|
||||
ForkLock.Lock()
|
||||
|
||||
// Allocate child status pipe close on exec.
|
||||
if err = Pipe(&p); err != 0 {
|
||||
@ -255,22 +255,22 @@ func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir stri
|
||||
}
|
||||
|
||||
// Kick off child.
|
||||
pid, err = forkAndExecInChild(argv0p, argvp, envvp, traceme, dirp, fd, p[1]);
|
||||
pid, err = forkAndExecInChild(argv0p, argvp, envvp, traceme, dirp, fd, p[1])
|
||||
if err != 0 {
|
||||
error:
|
||||
if p[0] >= 0 {
|
||||
Close(p[0]);
|
||||
Close(p[1]);
|
||||
Close(p[0])
|
||||
Close(p[1])
|
||||
}
|
||||
ForkLock.Unlock();
|
||||
return 0, err;
|
||||
ForkLock.Unlock()
|
||||
return 0, err
|
||||
}
|
||||
ForkLock.Unlock();
|
||||
ForkLock.Unlock()
|
||||
|
||||
// Read child error status from pipe.
|
||||
Close(p[1]);
|
||||
n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), unsafe.Sizeof(err1));
|
||||
Close(p[0]);
|
||||
Close(p[1])
|
||||
n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
|
||||
Close(p[0])
|
||||
if err != 0 || n != 0 {
|
||||
if n == unsafe.Sizeof(err1) {
|
||||
err = int(err1)
|
||||
@ -281,15 +281,15 @@ func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir stri
|
||||
|
||||
// Child failed; wait for it to exit, to make sure
|
||||
// the zombies don't accumulate.
|
||||
_, err1 := Wait4(pid, &wstatus, 0, nil);
|
||||
_, err1 := Wait4(pid, &wstatus, 0, nil)
|
||||
for err1 == EINTR {
|
||||
_, err1 = Wait4(pid, &wstatus, 0, nil)
|
||||
}
|
||||
return 0, err;
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Read got EOF, so pipe closed on exec, so exec succeeded.
|
||||
return pid, 0;
|
||||
return pid, 0
|
||||
}
|
||||
|
||||
// Combination of fork and exec, careful to be thread safe.
|
||||
@ -307,6 +307,6 @@ func Exec(argv0 string, argv []string, envv []string) (err int) {
|
||||
_, _, err1 := RawSyscall(SYS_EXECVE,
|
||||
uintptr(unsafe.Pointer(StringBytePtr(argv0))),
|
||||
uintptr(unsafe.Pointer(&StringArrayPtr(argv)[0])),
|
||||
uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0])));
|
||||
return int(err1);
|
||||
uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0])))
|
||||
return int(err1)
|
||||
}
|
||||
|
@ -18,13 +18,13 @@ func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
// StringByteSlice returns a NUL-terminated slice of bytes
|
||||
// containing the text of s.
|
||||
func StringByteSlice(s string) []byte {
|
||||
a := make([]byte, len(s)+1);
|
||||
a := make([]byte, len(s)+1)
|
||||
for i := 0; i < len(s); i++ {
|
||||
a[i] = s[i]
|
||||
}
|
||||
return a;
|
||||
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] }
|
||||
func StringBytePtr(s string) *byte { return &StringByteSlice(s)[0] }
|
||||
|
@ -23,7 +23,7 @@ const OS = "darwin"
|
||||
// even linking this function into the binary. See ../os/getwd.go.
|
||||
const ImplementsGetwd = false
|
||||
|
||||
func Getwd() (string, int) { return "", ENOTSUP }
|
||||
func Getwd() (string, int) { return "", ENOTSUP }
|
||||
|
||||
|
||||
/*
|
||||
@ -34,7 +34,7 @@ func Getwd() (string, int) { return "", ENOTSUP }
|
||||
//sys setgroups(ngid int, gid *_Gid_t) (errno int)
|
||||
|
||||
func Getgroups() (gids []int, errno int) {
|
||||
n, err := getgroups(0, nil);
|
||||
n, err := getgroups(0, nil)
|
||||
if err != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
@ -47,16 +47,16 @@ func Getgroups() (gids []int, errno int) {
|
||||
return nil, EINVAL
|
||||
}
|
||||
|
||||
a := make([]_Gid_t, n);
|
||||
n, err = getgroups(n, &a[0]);
|
||||
a := make([]_Gid_t, n)
|
||||
n, err = getgroups(n, &a[0])
|
||||
if err != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
gids = make([]int, n);
|
||||
gids = make([]int, n)
|
||||
for i, v := range a[0:n] {
|
||||
gids[i] = int(v)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Setgroups(gids []int) (errno int) {
|
||||
@ -64,11 +64,11 @@ func Setgroups(gids []int) (errno int) {
|
||||
return setgroups(0, nil)
|
||||
}
|
||||
|
||||
a := make([]_Gid_t, len(gids));
|
||||
a := make([]_Gid_t, len(gids))
|
||||
for i, v := range gids {
|
||||
a[i] = _Gid_t(v)
|
||||
}
|
||||
return setgroups(len(a), &a[0]);
|
||||
return setgroups(len(a), &a[0])
|
||||
}
|
||||
|
||||
// Wait status is 7 bits at bottom, either 0 (exited),
|
||||
@ -80,44 +80,44 @@ func Setgroups(gids []int) (errno int) {
|
||||
type WaitStatus uint32
|
||||
|
||||
const (
|
||||
mask = 0x7F;
|
||||
core = 0x80;
|
||||
shift = 8;
|
||||
mask = 0x7F
|
||||
core = 0x80
|
||||
shift = 8
|
||||
|
||||
exited = 0;
|
||||
stopped = 0x7F;
|
||||
exited = 0
|
||||
stopped = 0x7F
|
||||
)
|
||||
|
||||
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||
|
||||
func (w WaitStatus) ExitStatus() int {
|
||||
if w&mask != exited {
|
||||
return -1
|
||||
}
|
||||
return int(w >> shift);
|
||||
return int(w >> shift)
|
||||
}
|
||||
|
||||
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
|
||||
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
|
||||
|
||||
func (w WaitStatus) Signal() int {
|
||||
sig := int(w & mask);
|
||||
sig := int(w & mask)
|
||||
if sig == stopped || sig == 0 {
|
||||
return -1
|
||||
}
|
||||
return sig;
|
||||
return sig
|
||||
}
|
||||
|
||||
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
|
||||
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) Stopped() bool { return w&mask == stopped && w>>shift != SIGSTOP }
|
||||
|
||||
func (w WaitStatus) Continued() 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;
|
||||
return int(w>>shift) & 0xFF
|
||||
}
|
||||
|
||||
func (w WaitStatus) TrapCause() int {
|
||||
@ -128,12 +128,12 @@ func (w WaitStatus) TrapCause() int {
|
||||
//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);
|
||||
var status _C_int
|
||||
wpid, errno = wait4(pid, &status, options, rusage)
|
||||
if wstatus != nil {
|
||||
*wstatus = WaitStatus(status)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
//sys pipe() (r int, w int, errno int)
|
||||
@ -142,13 +142,13 @@ func Pipe(p []int) (errno int) {
|
||||
if len(p) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
p[0], p[1], errno = pipe();
|
||||
return;
|
||||
p[0], p[1], errno = pipe()
|
||||
return
|
||||
}
|
||||
|
||||
func Sleep(ns int64) (errno int) {
|
||||
tv := NsecToTimeval(ns);
|
||||
return Select(0, nil, nil, nil, &tv);
|
||||
tv := NsecToTimeval(ns)
|
||||
return Select(0, nil, nil, nil, &tv)
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int)
|
||||
@ -165,173 +165,173 @@ func Sleep(ns int64) (errno int) {
|
||||
var SocketDisableIPv6 bool
|
||||
|
||||
type Sockaddr interface {
|
||||
sockaddr() (ptr uintptr, len _Socklen, errno int); // lowercase; only we can define Sockaddrs
|
||||
sockaddr() (ptr uintptr, len _Socklen, errno int) // lowercase; only we can define Sockaddrs
|
||||
}
|
||||
|
||||
type SockaddrInet4 struct {
|
||||
Port int;
|
||||
Addr [4]byte;
|
||||
raw RawSockaddrInet4;
|
||||
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);
|
||||
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;
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0
|
||||
}
|
||||
|
||||
type SockaddrInet6 struct {
|
||||
Port int;
|
||||
Addr [16]byte;
|
||||
raw RawSockaddrInet6;
|
||||
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);
|
||||
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;
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0
|
||||
}
|
||||
|
||||
type SockaddrUnix struct {
|
||||
Name string;
|
||||
raw RawSockaddrUnix;
|
||||
Name string
|
||||
raw RawSockaddrUnix
|
||||
}
|
||||
|
||||
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
|
||||
name := sa.Name;
|
||||
n := len(name);
|
||||
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;
|
||||
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;
|
||||
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));
|
||||
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
|
||||
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;
|
||||
n = i
|
||||
break
|
||||
}
|
||||
}
|
||||
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]));
|
||||
sa.Name = string(bytes[0:n]);
|
||||
return sa, 0;
|
||||
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]);
|
||||
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;
|
||||
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]);
|
||||
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 sa, 0
|
||||
}
|
||||
return nil, EAFNOSUPPORT;
|
||||
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);
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
nfd, errno = accept(fd, &rsa, &len)
|
||||
if errno != 0 {
|
||||
return
|
||||
}
|
||||
sa, errno = anyToSockaddr(&rsa);
|
||||
sa, errno = anyToSockaddr(&rsa)
|
||||
if errno != 0 {
|
||||
Close(nfd);
|
||||
nfd = 0;
|
||||
Close(nfd)
|
||||
nfd = 0
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Getsockname(fd int) (sa Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if errno = getsockname(fd, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
return anyToSockaddr(&rsa);
|
||||
return anyToSockaddr(&rsa)
|
||||
}
|
||||
|
||||
func Getpeername(fd int) (sa Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if errno = getpeername(fd, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
return anyToSockaddr(&rsa);
|
||||
return anyToSockaddr(&rsa)
|
||||
}
|
||||
|
||||
func Bind(fd int, sa Sockaddr) (errno int) {
|
||||
ptr, n, err := sa.sockaddr();
|
||||
ptr, n, err := sa.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return bind(fd, ptr, n);
|
||||
return bind(fd, ptr, n)
|
||||
}
|
||||
|
||||
func Connect(fd int, sa Sockaddr) (errno int) {
|
||||
ptr, n, err := sa.sockaddr();
|
||||
ptr, n, err := sa.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return connect(fd, ptr, n);
|
||||
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;
|
||||
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);
|
||||
var n = int32(value)
|
||||
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4)
|
||||
}
|
||||
|
||||
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
|
||||
@ -346,44 +346,44 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, errno int)
|
||||
|
||||
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if n, errno = recvfrom(fd, p, flags, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
from, errno = anyToSockaddr(&rsa);
|
||||
return;
|
||||
from, errno = anyToSockaddr(&rsa)
|
||||
return
|
||||
}
|
||||
|
||||
//sys sendto(s int, buf []byte, flags int, to uintptr, addrlen _Socklen) (errno int)
|
||||
|
||||
func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
|
||||
ptr, n, err := to.sockaddr();
|
||||
ptr, n, err := to.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return sendto(fd, p, flags, ptr, n);
|
||||
return sendto(fd, p, flags, ptr, n)
|
||||
}
|
||||
|
||||
//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;
|
||||
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);
|
||||
return kevent(kq, change, len(changes), event, len(events), timeout)
|
||||
}
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) = SYS___SYSCTL
|
||||
|
||||
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
|
||||
func nametomib(name string) (mib []_C_int, errno int) {
|
||||
const CTL_MAXNAME = 12;
|
||||
const siz = uintptr(unsafe.Sizeof(mib[0]));
|
||||
const CTL_MAXNAME = 12
|
||||
const siz = uintptr(unsafe.Sizeof(mib[0]))
|
||||
|
||||
// NOTE(rsc): It seems strange to set the buffer to have
|
||||
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
|
||||
@ -392,29 +392,29 @@ func nametomib(name string) (mib []_C_int, errno int) {
|
||||
// I am scared that if we don't include the +2 here, the kernel
|
||||
// will silently write 2 words farther than we specify
|
||||
// and we'll get memory corruption.
|
||||
var buf [CTL_MAXNAME + 2]_C_int;
|
||||
n := uintptr(CTL_MAXNAME) * siz;
|
||||
var buf [CTL_MAXNAME + 2]_C_int
|
||||
n := uintptr(CTL_MAXNAME) * siz
|
||||
|
||||
p := (*byte)(unsafe.Pointer(&buf[0]));
|
||||
bytes := StringByteSlice(name);
|
||||
p := (*byte)(unsafe.Pointer(&buf[0]))
|
||||
bytes := StringByteSlice(name)
|
||||
|
||||
// Magic sysctl: "setting" 0.3 to a string name
|
||||
// lets you read back the array of integers form.
|
||||
if errno = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); errno != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
return buf[0 : n/siz], 0;
|
||||
return buf[0 : n/siz], 0
|
||||
}
|
||||
|
||||
func Sysctl(name string) (value string, errno int) {
|
||||
// Translate name to mib number.
|
||||
mib, errno := nametomib(name);
|
||||
mib, errno := nametomib(name)
|
||||
if errno != 0 {
|
||||
return "", errno
|
||||
}
|
||||
|
||||
// Find size.
|
||||
n := uintptr(0);
|
||||
n := uintptr(0)
|
||||
if errno = sysctl(mib, nil, &n, nil, 0); errno != 0 {
|
||||
return "", errno
|
||||
}
|
||||
@ -423,7 +423,7 @@ func Sysctl(name string) (value string, errno int) {
|
||||
}
|
||||
|
||||
// Read into buffer of that size.
|
||||
buf := make([]byte, n);
|
||||
buf := make([]byte, n)
|
||||
if errno = sysctl(mib, &buf[0], &n, nil, 0); errno != 0 {
|
||||
return "", errno
|
||||
}
|
||||
@ -432,26 +432,26 @@ func Sysctl(name string) (value string, errno int) {
|
||||
if n > 0 && buf[n-1] == '\x00' {
|
||||
n--
|
||||
}
|
||||
return string(buf[0:n]), 0;
|
||||
return string(buf[0:n]), 0
|
||||
}
|
||||
|
||||
func SysctlUint32(name string) (value uint32, errno int) {
|
||||
// Translate name to mib number.
|
||||
mib, errno := nametomib(name);
|
||||
mib, errno := nametomib(name)
|
||||
if errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
|
||||
// Read into buffer of that size.
|
||||
n := uintptr(4);
|
||||
buf := make([]byte, 4);
|
||||
n := uintptr(4)
|
||||
buf := make([]byte, 4)
|
||||
if errno = sysctl(mib, &buf[0], &n, nil, 0); errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
if n != 4 {
|
||||
return 0, EIO
|
||||
}
|
||||
return *(*uint32)(unsafe.Pointer(&buf[0])), 0;
|
||||
return *(*uint32)(unsafe.Pointer(&buf[0])), 0
|
||||
}
|
||||
|
||||
// TODO: wrap
|
||||
|
@ -4,23 +4,23 @@
|
||||
|
||||
package syscall
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = int32(nsec / 1e9);
|
||||
ts.Nsec = int32(nsec % 1e9);
|
||||
return;
|
||||
ts.Sec = int32(nsec / 1e9)
|
||||
ts.Nsec = int32(nsec % 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
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 = int32(nsec / 1e9);
|
||||
return;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
//sys gettimeofday(tp *Timeval) (sec int32, usec int32, errno int)
|
||||
@ -28,14 +28,14 @@ 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 = int32(sec);
|
||||
tv.Usec = int32(usec);
|
||||
return err;
|
||||
sec, usec, err := gettimeofday(tv)
|
||||
tv.Sec = int32(sec)
|
||||
tv.Usec = int32(usec)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint32(fd);
|
||||
k.Filter = int16(mode);
|
||||
k.Flags = uint16(flags);
|
||||
k.Ident = uint32(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
@ -4,23 +4,23 @@
|
||||
|
||||
package syscall
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
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;
|
||||
ts.Sec = nsec / 1e9
|
||||
ts.Nsec = nsec % 1e9
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
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;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
tv.Sec = int64(nsec / 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
//sys gettimeofday(tp *Timeval) (sec int64, usec int32, errno int)
|
||||
@ -28,14 +28,14 @@ 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;
|
||||
sec, usec, err := gettimeofday(tv)
|
||||
tv.Sec = sec
|
||||
tv.Usec = usec
|
||||
return err
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint64(fd);
|
||||
k.Filter = int16(mode);
|
||||
k.Flags = uint16(flags);
|
||||
k.Ident = uint64(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ const OS = "freebsd"
|
||||
// even linking this function into the binary. See ../os/getwd.go.
|
||||
const ImplementsGetwd = false
|
||||
|
||||
func Getwd() (string, int) { return "", ENOTSUP }
|
||||
func Getwd() (string, int) { return "", ENOTSUP }
|
||||
|
||||
|
||||
/*
|
||||
@ -34,7 +34,7 @@ func Getwd() (string, int) { return "", ENOTSUP }
|
||||
//sys setgroups(ngid int, gid *_Gid_t) (errno int)
|
||||
|
||||
func Getgroups() (gids []int, errno int) {
|
||||
n, err := getgroups(0, nil);
|
||||
n, err := getgroups(0, nil)
|
||||
if err != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
@ -47,16 +47,16 @@ func Getgroups() (gids []int, errno int) {
|
||||
return nil, EINVAL
|
||||
}
|
||||
|
||||
a := make([]_Gid_t, n);
|
||||
n, err = getgroups(n, &a[0]);
|
||||
a := make([]_Gid_t, n)
|
||||
n, err = getgroups(n, &a[0])
|
||||
if err != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
gids = make([]int, n);
|
||||
gids = make([]int, n)
|
||||
for i, v := range a[0:n] {
|
||||
gids[i] = int(v)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Setgroups(gids []int) (errno int) {
|
||||
@ -64,11 +64,11 @@ func Setgroups(gids []int) (errno int) {
|
||||
return setgroups(0, nil)
|
||||
}
|
||||
|
||||
a := make([]_Gid_t, len(gids));
|
||||
a := make([]_Gid_t, len(gids))
|
||||
for i, v := range gids {
|
||||
a[i] = _Gid_t(v)
|
||||
}
|
||||
return setgroups(len(a), &a[0]);
|
||||
return setgroups(len(a), &a[0])
|
||||
}
|
||||
|
||||
// Wait status is 7 bits at bottom, either 0 (exited),
|
||||
@ -80,44 +80,44 @@ func Setgroups(gids []int) (errno int) {
|
||||
type WaitStatus uint32
|
||||
|
||||
const (
|
||||
mask = 0x7F;
|
||||
core = 0x80;
|
||||
shift = 8;
|
||||
mask = 0x7F
|
||||
core = 0x80
|
||||
shift = 8
|
||||
|
||||
exited = 0;
|
||||
stopped = 0x7F;
|
||||
exited = 0
|
||||
stopped = 0x7F
|
||||
)
|
||||
|
||||
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||
|
||||
func (w WaitStatus) ExitStatus() int {
|
||||
if w&mask != exited {
|
||||
return -1
|
||||
}
|
||||
return int(w >> shift);
|
||||
return int(w >> shift)
|
||||
}
|
||||
|
||||
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
|
||||
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
|
||||
|
||||
func (w WaitStatus) Signal() int {
|
||||
sig := int(w & mask);
|
||||
sig := int(w & mask)
|
||||
if sig == stopped || sig == 0 {
|
||||
return -1
|
||||
}
|
||||
return sig;
|
||||
return sig
|
||||
}
|
||||
|
||||
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
|
||||
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) Stopped() bool { return w&mask == stopped && w>>shift != SIGSTOP }
|
||||
|
||||
func (w WaitStatus) Continued() 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;
|
||||
return int(w>>shift) & 0xFF
|
||||
}
|
||||
|
||||
func (w WaitStatus) TrapCause() int {
|
||||
@ -128,12 +128,12 @@ func (w WaitStatus) TrapCause() int {
|
||||
//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);
|
||||
var status _C_int
|
||||
wpid, errno = wait4(pid, &status, options, rusage)
|
||||
if wstatus != nil {
|
||||
*wstatus = WaitStatus(status)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
//sys pipe() (r int, w int, errno int)
|
||||
@ -142,13 +142,13 @@ func Pipe(p []int) (errno int) {
|
||||
if len(p) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
p[0], p[1], errno = pipe();
|
||||
return;
|
||||
p[0], p[1], errno = pipe()
|
||||
return
|
||||
}
|
||||
|
||||
func Sleep(ns int64) (errno int) {
|
||||
tv := NsecToTimeval(ns);
|
||||
return Select(0, nil, nil, nil, &tv);
|
||||
tv := NsecToTimeval(ns)
|
||||
return Select(0, nil, nil, nil, &tv)
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int)
|
||||
@ -165,173 +165,173 @@ func Sleep(ns int64) (errno int) {
|
||||
var SocketDisableIPv6 bool
|
||||
|
||||
type Sockaddr interface {
|
||||
sockaddr() (ptr uintptr, len _Socklen, errno int); // lowercase; only we can define Sockaddrs
|
||||
sockaddr() (ptr uintptr, len _Socklen, errno int) // lowercase; only we can define Sockaddrs
|
||||
}
|
||||
|
||||
type SockaddrInet4 struct {
|
||||
Port int;
|
||||
Addr [4]byte;
|
||||
raw RawSockaddrInet4;
|
||||
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);
|
||||
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;
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0
|
||||
}
|
||||
|
||||
type SockaddrInet6 struct {
|
||||
Port int;
|
||||
Addr [16]byte;
|
||||
raw RawSockaddrInet6;
|
||||
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);
|
||||
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;
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), _Socklen(sa.raw.Len), 0
|
||||
}
|
||||
|
||||
type SockaddrUnix struct {
|
||||
Name string;
|
||||
raw RawSockaddrUnix;
|
||||
Name string
|
||||
raw RawSockaddrUnix
|
||||
}
|
||||
|
||||
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
|
||||
name := sa.Name;
|
||||
n := len(name);
|
||||
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;
|
||||
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;
|
||||
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));
|
||||
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
|
||||
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;
|
||||
n = i
|
||||
break
|
||||
}
|
||||
}
|
||||
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]));
|
||||
sa.Name = string(bytes[0:n]);
|
||||
return sa, 0;
|
||||
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]);
|
||||
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;
|
||||
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]);
|
||||
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 sa, 0
|
||||
}
|
||||
return nil, EAFNOSUPPORT;
|
||||
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);
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
nfd, errno = accept(fd, &rsa, &len)
|
||||
if errno != 0 {
|
||||
return
|
||||
}
|
||||
sa, errno = anyToSockaddr(&rsa);
|
||||
sa, errno = anyToSockaddr(&rsa)
|
||||
if errno != 0 {
|
||||
Close(nfd);
|
||||
nfd = 0;
|
||||
Close(nfd)
|
||||
nfd = 0
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Getsockname(fd int) (sa Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if errno = getsockname(fd, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
return anyToSockaddr(&rsa);
|
||||
return anyToSockaddr(&rsa)
|
||||
}
|
||||
|
||||
func Getpeername(fd int) (sa Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if errno = getpeername(fd, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
return anyToSockaddr(&rsa);
|
||||
return anyToSockaddr(&rsa)
|
||||
}
|
||||
|
||||
func Bind(fd int, sa Sockaddr) (errno int) {
|
||||
ptr, n, err := sa.sockaddr();
|
||||
ptr, n, err := sa.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return bind(fd, ptr, n);
|
||||
return bind(fd, ptr, n)
|
||||
}
|
||||
|
||||
func Connect(fd int, sa Sockaddr) (errno int) {
|
||||
ptr, n, err := sa.sockaddr();
|
||||
ptr, n, err := sa.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return connect(fd, ptr, n);
|
||||
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;
|
||||
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);
|
||||
var n = int32(value)
|
||||
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4)
|
||||
}
|
||||
|
||||
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
|
||||
@ -346,44 +346,44 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, errno int)
|
||||
|
||||
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if n, errno = recvfrom(fd, p, flags, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
from, errno = anyToSockaddr(&rsa);
|
||||
return;
|
||||
from, errno = anyToSockaddr(&rsa)
|
||||
return
|
||||
}
|
||||
|
||||
//sys sendto(s int, buf []byte, flags int, to uintptr, addrlen _Socklen) (errno int)
|
||||
|
||||
func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
|
||||
ptr, n, err := to.sockaddr();
|
||||
ptr, n, err := to.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return sendto(fd, p, flags, ptr, n);
|
||||
return sendto(fd, p, flags, ptr, n)
|
||||
}
|
||||
|
||||
//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;
|
||||
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);
|
||||
return kevent(kq, change, len(changes), event, len(events), timeout)
|
||||
}
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) = SYS___SYSCTL
|
||||
|
||||
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
|
||||
func nametomib(name string) (mib []_C_int, errno int) {
|
||||
const CTL_MAXNAME = 12;
|
||||
const siz = uintptr(unsafe.Sizeof(mib[0]));
|
||||
const CTL_MAXNAME = 12
|
||||
const siz = uintptr(unsafe.Sizeof(mib[0]))
|
||||
|
||||
// NOTE(rsc): It seems strange to set the buffer to have
|
||||
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
|
||||
@ -392,29 +392,29 @@ func nametomib(name string) (mib []_C_int, errno int) {
|
||||
// I am scared that if we don't include the +2 here, the kernel
|
||||
// will silently write 2 words farther than we specify
|
||||
// and we'll get memory corruption.
|
||||
var buf [CTL_MAXNAME + 2]_C_int;
|
||||
n := uintptr(CTL_MAXNAME) * siz;
|
||||
var buf [CTL_MAXNAME + 2]_C_int
|
||||
n := uintptr(CTL_MAXNAME) * siz
|
||||
|
||||
p := (*byte)(unsafe.Pointer(&buf[0]));
|
||||
bytes := StringByteSlice(name);
|
||||
p := (*byte)(unsafe.Pointer(&buf[0]))
|
||||
bytes := StringByteSlice(name)
|
||||
|
||||
// Magic sysctl: "setting" 0.3 to a string name
|
||||
// lets you read back the array of integers form.
|
||||
if errno = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); errno != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
return buf[0 : n/siz], 0;
|
||||
return buf[0 : n/siz], 0
|
||||
}
|
||||
|
||||
func Sysctl(name string) (value string, errno int) {
|
||||
// Translate name to mib number.
|
||||
mib, errno := nametomib(name);
|
||||
mib, errno := nametomib(name)
|
||||
if errno != 0 {
|
||||
return "", errno
|
||||
}
|
||||
|
||||
// Find size.
|
||||
n := uintptr(0);
|
||||
n := uintptr(0)
|
||||
if errno = sysctl(mib, nil, &n, nil, 0); errno != 0 {
|
||||
return "", errno
|
||||
}
|
||||
@ -423,7 +423,7 @@ func Sysctl(name string) (value string, errno int) {
|
||||
}
|
||||
|
||||
// Read into buffer of that size.
|
||||
buf := make([]byte, n);
|
||||
buf := make([]byte, n)
|
||||
if errno = sysctl(mib, &buf[0], &n, nil, 0); errno != 0 {
|
||||
return "", errno
|
||||
}
|
||||
@ -432,26 +432,26 @@ func Sysctl(name string) (value string, errno int) {
|
||||
if n > 0 && buf[n-1] == '\x00' {
|
||||
n--
|
||||
}
|
||||
return string(buf[0:n]), 0;
|
||||
return string(buf[0:n]), 0
|
||||
}
|
||||
|
||||
func SysctlUint32(name string) (value uint32, errno int) {
|
||||
// Translate name to mib number.
|
||||
mib, errno := nametomib(name);
|
||||
mib, errno := nametomib(name)
|
||||
if errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
|
||||
// Read into buffer of that size.
|
||||
n := uintptr(4);
|
||||
buf := make([]byte, 4);
|
||||
n := uintptr(4)
|
||||
buf := make([]byte, 4)
|
||||
if errno = sysctl(mib, &buf[0], &n, nil, 0); errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
if n != 4 {
|
||||
return 0, EIO
|
||||
}
|
||||
return *(*uint32)(unsafe.Pointer(&buf[0])), 0;
|
||||
return *(*uint32)(unsafe.Pointer(&buf[0])), 0
|
||||
}
|
||||
|
||||
// TODO: wrap
|
||||
|
@ -4,27 +4,27 @@
|
||||
|
||||
package syscall
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = int32(nsec / 1e9);
|
||||
ts.Nsec = int32(nsec % 1e9);
|
||||
return;
|
||||
ts.Sec = int32(nsec / 1e9)
|
||||
ts.Nsec = int32(nsec % 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
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 = int32(nsec / 1e9);
|
||||
return;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint32(fd);
|
||||
k.Filter = int16(mode);
|
||||
k.Flags = uint16(flags);
|
||||
k.Ident = uint32(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
@ -4,27 +4,27 @@
|
||||
|
||||
package syscall
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
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;
|
||||
ts.Sec = nsec / 1e9
|
||||
ts.Nsec = nsec % 1e9
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
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 = nsec % 1e9 / 1e3;
|
||||
tv.Sec = int64(nsec / 1e9);
|
||||
return;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Usec = nsec % 1e9 / 1e3
|
||||
tv.Sec = int64(nsec / 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint64(fd);
|
||||
k.Filter = int16(mode);
|
||||
k.Flags = uint16(flags);
|
||||
k.Ident = uint64(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ 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;
|
||||
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)
|
||||
@ -36,7 +36,7 @@ func Utimes(path string, tv []Timeval) (errno int) {
|
||||
if len(tv) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])));
|
||||
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||
}
|
||||
|
||||
//sys futimesat(dirfd int, path string, times *[2]Timeval) (errno int)
|
||||
@ -44,15 +44,15 @@ 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])));
|
||||
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);
|
||||
var buf [PathMax]byte
|
||||
n, err := Getcwd(&buf)
|
||||
if err != 0 {
|
||||
return "", err
|
||||
}
|
||||
@ -60,11 +60,11 @@ func Getwd() (wd string, errno int) {
|
||||
if n < 1 || n > len(buf) || buf[n-1] != 0 {
|
||||
return "", EINVAL
|
||||
}
|
||||
return string(buf[0 : n-1]), 0;
|
||||
return string(buf[0 : n-1]), 0
|
||||
}
|
||||
|
||||
func Getgroups() (gids []int, errno int) {
|
||||
n, err := getgroups(0, nil);
|
||||
n, err := getgroups(0, nil)
|
||||
if err != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
@ -77,16 +77,16 @@ func Getgroups() (gids []int, errno int) {
|
||||
return nil, EINVAL
|
||||
}
|
||||
|
||||
a := make([]_Gid_t, n);
|
||||
n, err = getgroups(n, &a[0]);
|
||||
a := make([]_Gid_t, n)
|
||||
n, err = getgroups(n, &a[0])
|
||||
if err != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
gids = make([]int, n);
|
||||
gids = make([]int, n)
|
||||
for i, v := range a[0:n] {
|
||||
gids[i] = int(v)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Setgroups(gids []int) (errno int) {
|
||||
@ -94,11 +94,11 @@ func Setgroups(gids []int) (errno int) {
|
||||
return setgroups(0, nil)
|
||||
}
|
||||
|
||||
a := make([]_Gid_t, len(gids));
|
||||
a := make([]_Gid_t, len(gids))
|
||||
for i, v := range gids {
|
||||
a[i] = _Gid_t(v)
|
||||
}
|
||||
return setgroups(len(a), &a[0]);
|
||||
return setgroups(len(a), &a[0])
|
||||
}
|
||||
|
||||
type WaitStatus uint32
|
||||
@ -113,65 +113,65 @@ type WaitStatus uint32
|
||||
// from stopped via the core dump bit.
|
||||
|
||||
const (
|
||||
mask = 0x7F;
|
||||
core = 0x80;
|
||||
exited = 0x00;
|
||||
stopped = 0x7F;
|
||||
shift = 8;
|
||||
mask = 0x7F
|
||||
core = 0x80
|
||||
exited = 0x00
|
||||
stopped = 0x7F
|
||||
shift = 8
|
||||
)
|
||||
|
||||
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||
|
||||
func (w WaitStatus) Signaled() bool { return w&mask != stopped && 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) Stopped() bool { return w&0xFF == stopped }
|
||||
|
||||
func (w WaitStatus) Continued() bool { return w == 0xFFFF }
|
||||
func (w WaitStatus) Continued() bool { return w == 0xFFFF }
|
||||
|
||||
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
|
||||
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;
|
||||
return int(w>>shift) & 0xFF
|
||||
}
|
||||
|
||||
func (w WaitStatus) Signal() int {
|
||||
if !w.Signaled() {
|
||||
return -1
|
||||
}
|
||||
return int(w & mask);
|
||||
return int(w & mask)
|
||||
}
|
||||
|
||||
func (w WaitStatus) StopSignal() int {
|
||||
if !w.Stopped() {
|
||||
return -1
|
||||
}
|
||||
return int(w>>shift) & 0xFF;
|
||||
return int(w>>shift) & 0xFF
|
||||
}
|
||||
|
||||
func (w WaitStatus) TrapCause() int {
|
||||
if w.StopSignal() != SIGTRAP {
|
||||
return -1
|
||||
}
|
||||
return int(w>>shift) >> 8;
|
||||
return int(w>>shift) >> 8
|
||||
}
|
||||
|
||||
//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);
|
||||
var status _C_int
|
||||
wpid, errno = wait4(pid, &status, options, rusage)
|
||||
if wstatus != nil {
|
||||
*wstatus = WaitStatus(status)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Sleep(nsec int64) (errno int) {
|
||||
tv := NsecToTimeval(nsec);
|
||||
_, err := Select(0, nil, nil, nil, &tv);
|
||||
return err;
|
||||
tv := NsecToTimeval(nsec)
|
||||
_, err := Select(0, nil, nil, nil, &tv)
|
||||
return err
|
||||
}
|
||||
|
||||
// For testing: clients can set this flag to force
|
||||
@ -179,61 +179,61 @@ func Sleep(nsec int64) (errno int) {
|
||||
var SocketDisableIPv6 bool
|
||||
|
||||
type Sockaddr interface {
|
||||
sockaddr() (ptr uintptr, len _Socklen, errno int); // lowercase; only we can define Sockaddrs
|
||||
sockaddr() (ptr uintptr, len _Socklen, errno int) // lowercase; only we can define Sockaddrs
|
||||
}
|
||||
|
||||
type SockaddrInet4 struct {
|
||||
Port int;
|
||||
Addr [4]byte;
|
||||
raw RawSockaddrInet4;
|
||||
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);
|
||||
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;
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet4, 0
|
||||
}
|
||||
|
||||
type SockaddrInet6 struct {
|
||||
Port int;
|
||||
Addr [16]byte;
|
||||
raw RawSockaddrInet6;
|
||||
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);
|
||||
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;
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), SizeofSockaddrInet6, 0
|
||||
}
|
||||
|
||||
type SockaddrUnix struct {
|
||||
Name string;
|
||||
raw RawSockaddrUnix;
|
||||
Name string
|
||||
raw RawSockaddrUnix
|
||||
}
|
||||
|
||||
func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
|
||||
name := sa.Name;
|
||||
n := len(name);
|
||||
name := sa.Name
|
||||
n := len(name)
|
||||
if n >= len(sa.raw.Path) || n == 0 {
|
||||
return 0, 0, EINVAL
|
||||
}
|
||||
sa.raw.Family = AF_UNIX;
|
||||
sa.raw.Family = AF_UNIX
|
||||
for i := 0; i < n; i++ {
|
||||
sa.raw.Path[i] = int8(name[i])
|
||||
}
|
||||
@ -242,14 +242,14 @@ func (sa *SockaddrUnix) sockaddr() (uintptr, _Socklen, int) {
|
||||
}
|
||||
|
||||
// length is family, name, NUL.
|
||||
return uintptr(unsafe.Pointer(&sa.raw)), 1 + _Socklen(n) + 1, 0;
|
||||
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);
|
||||
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
|
||||
sa := new(SockaddrUnix)
|
||||
if pp.Path[0] == 0 {
|
||||
// "Abstract" Unix domain socket.
|
||||
// Rewrite leading NUL as @ for textual display.
|
||||
@ -264,97 +264,97 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, int) {
|
||||
// abstract Unix domain sockets--they are supposed
|
||||
// to be uninterpreted fixed-size binary blobs--but
|
||||
// everyone uses this convention.
|
||||
n := 0;
|
||||
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;
|
||||
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]);
|
||||
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;
|
||||
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]);
|
||||
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 sa, 0
|
||||
}
|
||||
return nil, EAFNOSUPPORT;
|
||||
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);
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
nfd, errno = accept(fd, &rsa, &len)
|
||||
if errno != 0 {
|
||||
return
|
||||
}
|
||||
sa, errno = anyToSockaddr(&rsa);
|
||||
sa, errno = anyToSockaddr(&rsa)
|
||||
if errno != 0 {
|
||||
Close(nfd);
|
||||
nfd = 0;
|
||||
Close(nfd)
|
||||
nfd = 0
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
func Getsockname(fd int) (sa Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if errno = getsockname(fd, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
return anyToSockaddr(&rsa);
|
||||
return anyToSockaddr(&rsa)
|
||||
}
|
||||
|
||||
func Getpeername(fd int) (sa Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if errno = getpeername(fd, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
return anyToSockaddr(&rsa);
|
||||
return anyToSockaddr(&rsa)
|
||||
}
|
||||
|
||||
func Bind(fd int, sa Sockaddr) (errno int) {
|
||||
ptr, n, err := sa.sockaddr();
|
||||
ptr, n, err := sa.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return bind(fd, ptr, n);
|
||||
return bind(fd, ptr, n)
|
||||
}
|
||||
|
||||
func Connect(fd int, sa Sockaddr) (errno int) {
|
||||
ptr, n, err := sa.sockaddr();
|
||||
ptr, n, err := sa.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return connect(fd, ptr, n);
|
||||
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;
|
||||
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);
|
||||
var n = int32(value)
|
||||
return setsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), 4)
|
||||
}
|
||||
|
||||
func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
|
||||
@ -366,21 +366,21 @@ func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||
}
|
||||
|
||||
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
|
||||
var rsa RawSockaddrAny;
|
||||
var len _Socklen = SizeofSockaddrAny;
|
||||
var rsa RawSockaddrAny
|
||||
var len _Socklen = SizeofSockaddrAny
|
||||
if n, errno = recvfrom(fd, p, flags, &rsa, &len); errno != 0 {
|
||||
return
|
||||
}
|
||||
from, errno = anyToSockaddr(&rsa);
|
||||
return;
|
||||
from, errno = anyToSockaddr(&rsa)
|
||||
return
|
||||
}
|
||||
|
||||
func Sendto(fd int, p []byte, flags int, to Sockaddr) (errno int) {
|
||||
ptr, n, err := to.sockaddr();
|
||||
ptr, n, err := to.sockaddr()
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return sendto(fd, p, flags, ptr, n);
|
||||
return sendto(fd, p, flags, ptr, n)
|
||||
}
|
||||
|
||||
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (errno int)
|
||||
@ -392,37 +392,37 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, errno in
|
||||
// The ptrace syscall differs from glibc's ptrace.
|
||||
// Peeks returns the word in *data, not as the return value.
|
||||
|
||||
var buf [sizeofPtr]byte;
|
||||
var buf [sizeofPtr]byte
|
||||
|
||||
// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
|
||||
// access (PEEKUSER warns that it might), but if we don't
|
||||
// align our reads, we might straddle an unmapped page
|
||||
// boundary and not get the bytes leading up to the page
|
||||
// boundary.
|
||||
n := 0;
|
||||
n := 0
|
||||
if addr%sizeofPtr != 0 {
|
||||
errno = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])));
|
||||
errno = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
|
||||
if errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
n += copy(out, buf[addr%sizeofPtr:]);
|
||||
out = out[n:];
|
||||
n += copy(out, buf[addr%sizeofPtr:])
|
||||
out = out[n:]
|
||||
}
|
||||
|
||||
// Remainder.
|
||||
for len(out) > 0 {
|
||||
// We use an internal buffer to gaurantee alignment.
|
||||
// It's not documented if this is necessary, but we're paranoid.
|
||||
errno = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])));
|
||||
errno = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
|
||||
if errno != 0 {
|
||||
return n, errno
|
||||
}
|
||||
copied := copy(out, &buf);
|
||||
n += copied;
|
||||
out = out[copied:];
|
||||
copied := copy(out, &buf)
|
||||
n += copied
|
||||
out = out[copied:]
|
||||
}
|
||||
|
||||
return n, 0;
|
||||
return n, 0
|
||||
}
|
||||
|
||||
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, errno int) {
|
||||
@ -438,50 +438,50 @@ func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (c
|
||||
// with the possibility of straddling an invalid page.
|
||||
|
||||
// Leading edge.
|
||||
n := 0;
|
||||
n := 0
|
||||
if addr%sizeofPtr != 0 {
|
||||
var buf [sizeofPtr]byte;
|
||||
errno = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])));
|
||||
var buf [sizeofPtr]byte
|
||||
errno = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
|
||||
if errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
n += copy(buf[addr%sizeofPtr:], data);
|
||||
word := *((*uintptr)(unsafe.Pointer(&buf[0])));
|
||||
errno = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word);
|
||||
n += copy(buf[addr%sizeofPtr:], data)
|
||||
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
|
||||
errno = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
|
||||
if errno != 0 {
|
||||
return 0, errno
|
||||
}
|
||||
data = data[n:];
|
||||
data = data[n:]
|
||||
}
|
||||
|
||||
// Interior.
|
||||
for len(data) > sizeofPtr {
|
||||
word := *((*uintptr)(unsafe.Pointer(&data[0])));
|
||||
errno = ptrace(pokeReq, pid, addr+uintptr(n), word);
|
||||
word := *((*uintptr)(unsafe.Pointer(&data[0])))
|
||||
errno = ptrace(pokeReq, pid, addr+uintptr(n), word)
|
||||
if errno != 0 {
|
||||
return n, errno
|
||||
}
|
||||
n += sizeofPtr;
|
||||
data = data[sizeofPtr:];
|
||||
n += sizeofPtr
|
||||
data = data[sizeofPtr:]
|
||||
}
|
||||
|
||||
// Trailing edge.
|
||||
if len(data) > 0 {
|
||||
var buf [sizeofPtr]byte;
|
||||
errno = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])));
|
||||
var buf [sizeofPtr]byte
|
||||
errno = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
|
||||
if errno != 0 {
|
||||
return n, errno
|
||||
}
|
||||
copy(&buf, data);
|
||||
word := *((*uintptr)(unsafe.Pointer(&buf[0])));
|
||||
errno = ptrace(pokeReq, pid, addr+uintptr(n), word);
|
||||
copy(&buf, data)
|
||||
word := *((*uintptr)(unsafe.Pointer(&buf[0])))
|
||||
errno = ptrace(pokeReq, pid, addr+uintptr(n), word)
|
||||
if errno != 0 {
|
||||
return n, errno
|
||||
}
|
||||
n += len(data);
|
||||
n += len(data)
|
||||
}
|
||||
|
||||
return n, 0;
|
||||
return n, 0
|
||||
}
|
||||
|
||||
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, errno int) {
|
||||
@ -505,21 +505,21 @@ func PtraceSetOptions(pid int, options int) (errno int) {
|
||||
}
|
||||
|
||||
func PtraceGetEventMsg(pid int) (msg uint, errno int) {
|
||||
var data _C_long;
|
||||
errno = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)));
|
||||
msg = uint(data);
|
||||
return;
|
||||
var data _C_long
|
||||
errno = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
|
||||
msg = uint(data)
|
||||
return
|
||||
}
|
||||
|
||||
func PtraceCont(pid int, signal int) (errno int) {
|
||||
return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
|
||||
}
|
||||
|
||||
func PtraceSingleStep(pid int) (errno int) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
|
||||
func PtraceSingleStep(pid int) (errno int) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
|
||||
|
||||
func PtraceAttach(pid int) (errno int) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
|
||||
func PtraceAttach(pid int) (errno int) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
|
||||
|
||||
func PtraceDetach(pid int) (errno int) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
|
||||
func PtraceDetach(pid int) (errno int) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
|
||||
|
||||
// Sendto
|
||||
// Recvfrom
|
||||
|
@ -6,23 +6,23 @@ package syscall
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = int32(nsec / 1e9);
|
||||
ts.Nsec = int32(nsec % 1e9);
|
||||
return;
|
||||
ts.Sec = int32(nsec / 1e9)
|
||||
ts.Nsec = int32(nsec % 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
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 = int32(nsec / 1e9);
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3);
|
||||
return;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
return
|
||||
}
|
||||
|
||||
// 64-bit file system and 32-bit uid calls
|
||||
@ -64,102 +64,102 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, errno int)
|
||||
|
||||
const (
|
||||
// see linux/net.h
|
||||
_SOCKET = 1;
|
||||
_BIND = 2;
|
||||
_CONNECT = 3;
|
||||
_LISTEN = 4;
|
||||
_ACCEPT = 5;
|
||||
_GETSOCKNAME = 6;
|
||||
_GETPEERNAME = 7;
|
||||
_SOCKETPAIR = 8;
|
||||
_SEND = 9;
|
||||
_RECV = 10;
|
||||
_SENDTO = 11;
|
||||
_RECVFROM = 12;
|
||||
_SHUTDOWN = 13;
|
||||
_SETSOCKOPT = 14;
|
||||
_GETSOCKOPT = 15;
|
||||
_SENDMSG = 16;
|
||||
_RECVMSG = 17;
|
||||
_SOCKET = 1
|
||||
_BIND = 2
|
||||
_CONNECT = 3
|
||||
_LISTEN = 4
|
||||
_ACCEPT = 5
|
||||
_GETSOCKNAME = 6
|
||||
_GETPEERNAME = 7
|
||||
_SOCKETPAIR = 8
|
||||
_SEND = 9
|
||||
_RECV = 10
|
||||
_SENDTO = 11
|
||||
_RECVFROM = 12
|
||||
_SHUTDOWN = 13
|
||||
_SETSOCKOPT = 14
|
||||
_GETSOCKOPT = 15
|
||||
_SENDMSG = 16
|
||||
_RECVMSG = 17
|
||||
)
|
||||
|
||||
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
|
||||
|
||||
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int) {
|
||||
fd, errno = socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0);
|
||||
return;
|
||||
fd, errno = socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
|
||||
_, errno = socketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0);
|
||||
return;
|
||||
_, errno = socketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
|
||||
_, errno = socketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0);
|
||||
return;
|
||||
_, errno = socketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func bind(s int, addr uintptr, addrlen _Socklen) (errno int) {
|
||||
_, errno = socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0);
|
||||
return;
|
||||
_, errno = socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func connect(s int, addr uintptr, addrlen _Socklen) (errno int) {
|
||||
_, errno = socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0);
|
||||
return;
|
||||
_, errno = socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func socket(domain int, typ int, proto int) (fd int, errno int) {
|
||||
fd, errno = socketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0);
|
||||
return;
|
||||
fd, errno = socketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int) {
|
||||
_, errno = socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0);
|
||||
return;
|
||||
_, errno = socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
|
||||
return
|
||||
}
|
||||
|
||||
func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, errno int) {
|
||||
var base uintptr;
|
||||
var base uintptr
|
||||
if len(p) > 0 {
|
||||
base = uintptr(unsafe.Pointer(&p[0]))
|
||||
}
|
||||
n, errno = socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)));
|
||||
return;
|
||||
n, errno = socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
|
||||
return
|
||||
}
|
||||
|
||||
func sendto(s int, p []byte, flags int, to uintptr, addrlen _Socklen) (errno int) {
|
||||
var base uintptr;
|
||||
var base uintptr
|
||||
if len(p) > 0 {
|
||||
base = uintptr(unsafe.Pointer(&p[0]))
|
||||
}
|
||||
_, errno = socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), to, uintptr(addrlen));
|
||||
return;
|
||||
_, errno = socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), to, uintptr(addrlen))
|
||||
return
|
||||
}
|
||||
|
||||
func Listen(s int, n int) (errno int) {
|
||||
_, errno = socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0);
|
||||
return;
|
||||
_, errno = socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func Shutdown(s, how int) (errno int) {
|
||||
_, errno = socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0);
|
||||
return;
|
||||
_, errno = socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func Fstatfs(fd int, buf *Statfs_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Sizeof(*buf)), uintptr(unsafe.Pointer(buf)));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Sizeof(*buf)), uintptr(unsafe.Pointer(buf)))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Statfs(path string, buf *Statfs_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Sizeof(*buf)), uintptr(unsafe.Pointer(buf)));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Sizeof(*buf)), uintptr(unsafe.Pointer(buf)))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
|
||||
func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
|
||||
|
||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
|
||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
|
||||
|
@ -42,25 +42,25 @@ package syscall
|
||||
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, errno int)
|
||||
//sys sendto(s int, buf []byte, flags int, to uintptr, addrlen _Socklen) (errno int)
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
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;
|
||||
ts.Sec = nsec / 1e9
|
||||
ts.Nsec = nsec % 1e9
|
||||
return
|
||||
}
|
||||
|
||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||
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;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Sec = nsec / 1e9
|
||||
tv.Usec = nsec % 1e9 / 1e3
|
||||
return
|
||||
}
|
||||
|
||||
func (r *PtraceRegs) PC() uint64 { return r.Rip }
|
||||
func (r *PtraceRegs) PC() uint64 { return r.Rip }
|
||||
|
||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
|
||||
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
|
||||
|
@ -4,21 +4,21 @@
|
||||
|
||||
package syscall
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = int32(nsec / 1e9);
|
||||
ts.Nsec = int32(nsec % 1e9);
|
||||
return;
|
||||
ts.Sec = int32(nsec / 1e9)
|
||||
ts.Nsec = int32(nsec % 1e9)
|
||||
return
|
||||
}
|
||||
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
nsec += 999; // round up to microsecond
|
||||
tv.Sec = int32(nsec / 1e9);
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3);
|
||||
return;
|
||||
nsec += 999 // round up to microsecond
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
return
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int)
|
||||
@ -58,6 +58,6 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
//sys Statfs(path string, buf *Statfs_t) (errno int)
|
||||
|
||||
// TODO(kaib): add support for tracing
|
||||
func (r *PtraceRegs) PC() uint64 { return 0 }
|
||||
func (r *PtraceRegs) PC() uint64 { return 0 }
|
||||
|
||||
func (r *PtraceRegs) SetPC(pc uint64) {}
|
||||
func (r *PtraceRegs) SetPC(pc uint64) {}
|
||||
|
@ -54,8 +54,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
|
||||
if int64(int32(offset)) != offset {
|
||||
return 0, ERANGE
|
||||
}
|
||||
o, _, e := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence));
|
||||
return int64(o), int(e);
|
||||
o, _, e := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
|
||||
return int64(o), int(e)
|
||||
}
|
||||
|
||||
// Sleep by waiting on a condition variable that will never be signaled.
|
||||
@ -63,34 +63,34 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
|
||||
var tcv, tmu int
|
||||
|
||||
func init() {
|
||||
tmu, _ = MutexCreate();
|
||||
tcv, _ = CondCreate();
|
||||
tmu, _ = MutexCreate()
|
||||
tcv, _ = CondCreate()
|
||||
}
|
||||
|
||||
func Sleep(ns int64) (errno int) {
|
||||
ts := NsecToTimespec(ns);
|
||||
var tv Timeval;
|
||||
ts := NsecToTimespec(ns)
|
||||
var tv Timeval
|
||||
if errno = Gettimeofday(&tv); errno != 0 {
|
||||
return
|
||||
}
|
||||
ts.Sec += tv.Sec;
|
||||
ts.Nsec += tv.Usec * 1000;
|
||||
ts.Sec += tv.Sec
|
||||
ts.Nsec += tv.Usec * 1000
|
||||
switch {
|
||||
case ts.Nsec >= 1e9:
|
||||
ts.Nsec -= 1e9;
|
||||
ts.Sec++;
|
||||
ts.Nsec -= 1e9
|
||||
ts.Sec++
|
||||
case ts.Nsec <= -1e9:
|
||||
ts.Nsec += 1e9;
|
||||
ts.Sec--;
|
||||
ts.Nsec += 1e9
|
||||
ts.Sec--
|
||||
}
|
||||
if errno = MutexLock(tmu); errno != 0 {
|
||||
return
|
||||
}
|
||||
errno = CondTimedWaitAbs(tcv, tmu, &ts);
|
||||
errno = CondTimedWaitAbs(tcv, tmu, &ts)
|
||||
if e := MutexUnlock(tmu); e != 0 && errno == 0 {
|
||||
errno = e
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Implemented in NaCl but not here; maybe later:
|
||||
@ -111,10 +111,10 @@ func Sleep(ns int64) (errno int) {
|
||||
// Not implemented in NaCl but needed to compile other packages.
|
||||
|
||||
const (
|
||||
SIGTRAP = 5;
|
||||
SIGTRAP = 5
|
||||
)
|
||||
|
||||
func Pipe(p []int) (errno int) { return ENACL }
|
||||
func Pipe(p []int) (errno int) { return ENACL }
|
||||
|
||||
func fcntl(fd, cmd, arg int) (val int, errno int) {
|
||||
return 0, ENACL
|
||||
@ -128,25 +128,25 @@ func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
|
||||
return 0, ENACL
|
||||
}
|
||||
|
||||
func Mkdir(path string, mode int) (errno int) { return ENACL }
|
||||
func Mkdir(path string, mode int) (errno int) { return ENACL }
|
||||
|
||||
func Lstat(path string, stat *Stat_t) (errno int) {
|
||||
return ENACL
|
||||
}
|
||||
|
||||
func Chdir(path string) (errno int) { return ENACL }
|
||||
func Chdir(path string) (errno int) { return ENACL }
|
||||
|
||||
func Fchdir(fd int) (errno int) { return ENACL }
|
||||
func Fchdir(fd int) (errno int) { return ENACL }
|
||||
|
||||
func Unlink(path string) (errno int) { return ENACL }
|
||||
func Unlink(path string) (errno int) { return ENACL }
|
||||
|
||||
func Rmdir(path string) (errno int) { return ENACL }
|
||||
func Rmdir(path string) (errno int) { return ENACL }
|
||||
|
||||
func Link(oldpath, newpath string) (errno int) {
|
||||
return ENACL
|
||||
}
|
||||
|
||||
func Symlink(path, link string) (errno int) { return ENACL }
|
||||
func Symlink(path, link string) (errno int) { return ENACL }
|
||||
|
||||
func Readlink(path string, buf []byte) (n int, errno int) {
|
||||
return 0, ENACL
|
||||
@ -156,7 +156,7 @@ func Rename(oldpath, newpath string) (errno int) {
|
||||
return ENACL
|
||||
}
|
||||
|
||||
func Fchmod(fd int, mode int) (errno int) { return ENACL }
|
||||
func Fchmod(fd int, mode int) (errno int) { return ENACL }
|
||||
|
||||
func Chown(path string, uid int, gid int) (errno int) {
|
||||
return ENACL
|
||||
@ -184,65 +184,65 @@ func Ftruncate(fd int, length int64) (errno int) {
|
||||
|
||||
const ImplementsGetwd = true
|
||||
|
||||
func Getwd() (wd string, errno int) { return "", ENACL }
|
||||
func Getwd() (wd string, errno int) { return "", ENACL }
|
||||
|
||||
func Getuid() (uid int) { return -1 }
|
||||
func Getuid() (uid int) { return -1 }
|
||||
|
||||
func Geteuid() (euid int) { return -1 }
|
||||
func Geteuid() (euid int) { return -1 }
|
||||
|
||||
func Getgid() (gid int) { return -1 }
|
||||
func Getgid() (gid int) { return -1 }
|
||||
|
||||
func Getegid() (egid int) { return -1 }
|
||||
func Getegid() (egid int) { return -1 }
|
||||
|
||||
func Getppid() (ppid int) { return -1 }
|
||||
func Getppid() (ppid int) { return -1 }
|
||||
|
||||
func Getgroups() (gids []int, errno int) { return nil, ENACL }
|
||||
func Getgroups() (gids []int, errno int) { return nil, ENACL }
|
||||
|
||||
type Sockaddr interface {
|
||||
sockaddr();
|
||||
sockaddr()
|
||||
}
|
||||
|
||||
type SockaddrInet4 struct {
|
||||
Port int;
|
||||
Addr [4]byte;
|
||||
Port int
|
||||
Addr [4]byte
|
||||
}
|
||||
|
||||
func (*SockaddrInet4) sockaddr() {}
|
||||
func (*SockaddrInet4) sockaddr() {}
|
||||
|
||||
type SockaddrInet6 struct {
|
||||
Port int;
|
||||
Addr [16]byte;
|
||||
Port int
|
||||
Addr [16]byte
|
||||
}
|
||||
|
||||
func (*SockaddrInet6) sockaddr() {}
|
||||
func (*SockaddrInet6) sockaddr() {}
|
||||
|
||||
type SockaddrUnix struct {
|
||||
Name string;
|
||||
Name string
|
||||
}
|
||||
|
||||
func (*SockaddrUnix) sockaddr() {}
|
||||
func (*SockaddrUnix) sockaddr() {}
|
||||
|
||||
const (
|
||||
AF_INET = 1 + iota;
|
||||
AF_INET6;
|
||||
AF_UNIX;
|
||||
IPPROTO_TCP;
|
||||
SOCK_DGRAM;
|
||||
SOCK_STREAM;
|
||||
SOL_SOCKET;
|
||||
SOMAXCONN;
|
||||
SO_DONTROUTE;
|
||||
SO_KEEPALIVE;
|
||||
SO_LINGER;
|
||||
SO_RCVBUF;
|
||||
SO_REUSEADDR;
|
||||
SO_SNDBUF;
|
||||
TCP_NODELAY;
|
||||
WNOHANG;
|
||||
WSTOPPED;
|
||||
PTRACE_TRACEME;
|
||||
SO_BROADCAST = 0;
|
||||
SHUT_RDWR = 0;
|
||||
AF_INET = 1 + iota
|
||||
AF_INET6
|
||||
AF_UNIX
|
||||
IPPROTO_TCP
|
||||
SOCK_DGRAM
|
||||
SOCK_STREAM
|
||||
SOL_SOCKET
|
||||
SOMAXCONN
|
||||
SO_DONTROUTE
|
||||
SO_KEEPALIVE
|
||||
SO_LINGER
|
||||
SO_RCVBUF
|
||||
SO_REUSEADDR
|
||||
SO_SNDBUF
|
||||
TCP_NODELAY
|
||||
WNOHANG
|
||||
WSTOPPED
|
||||
PTRACE_TRACEME
|
||||
SO_BROADCAST = 0
|
||||
SHUT_RDWR = 0
|
||||
)
|
||||
|
||||
func Accept(fd int) (nfd int, sa Sockaddr, errno int) {
|
||||
@ -257,9 +257,9 @@ func Getpeername(fd int) (sa Sockaddr, errno int) {
|
||||
return nil, ENACL
|
||||
}
|
||||
|
||||
func Bind(fd int, sa Sockaddr) (errno int) { return ENACL }
|
||||
func Bind(fd int, sa Sockaddr) (errno int) { return ENACL }
|
||||
|
||||
func Connect(fd int, sa Sockaddr) (errno int) { return ENACL }
|
||||
func Connect(fd int, sa Sockaddr) (errno int) { return ENACL }
|
||||
|
||||
func Socket(domain, typ, proto int) (fd, errno int) {
|
||||
return 0, ENACL
|
||||
@ -269,7 +269,7 @@ func SetsockoptInt(fd, level, opt int, value int) (errno int) {
|
||||
return ENACL
|
||||
}
|
||||
|
||||
func Shutdown(fd, how int) (errno int) { return ENACL }
|
||||
func Shutdown(fd, how int) (errno int) { return ENACL }
|
||||
|
||||
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, errno int) {
|
||||
return 0, nil, ENACL
|
||||
@ -284,33 +284,33 @@ func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (errno int) {
|
||||
}
|
||||
|
||||
type Linger struct {
|
||||
Onoff int32;
|
||||
Linger int32;
|
||||
Onoff int32
|
||||
Linger int32
|
||||
}
|
||||
|
||||
func SetsockoptLinger(fd, level, opt int, l *Linger) (errno int) {
|
||||
return ENACL
|
||||
}
|
||||
|
||||
func Listen(s int, n int) (errno int) { return ENACL }
|
||||
func Listen(s int, n int) (errno int) { return ENACL }
|
||||
|
||||
type Rusage struct {
|
||||
Utime Timeval;
|
||||
Stime Timeval;
|
||||
Maxrss int32;
|
||||
Ixrss int32;
|
||||
Idrss int32;
|
||||
Isrss int32;
|
||||
Minflt int32;
|
||||
Majflt int32;
|
||||
Nswap int32;
|
||||
Inblock int32;
|
||||
Oublock int32;
|
||||
Msgsnd int32;
|
||||
Msgrcv int32;
|
||||
Nsignals int32;
|
||||
Nvcsw int32;
|
||||
Nivcsw int32;
|
||||
Utime Timeval
|
||||
Stime Timeval
|
||||
Maxrss int32
|
||||
Ixrss int32
|
||||
Idrss int32
|
||||
Isrss int32
|
||||
Minflt int32
|
||||
Majflt int32
|
||||
Nswap int32
|
||||
Inblock int32
|
||||
Oublock int32
|
||||
Msgsnd int32
|
||||
Msgrcv int32
|
||||
Nsignals int32
|
||||
Nvcsw int32
|
||||
Nivcsw int32
|
||||
}
|
||||
|
||||
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
|
||||
@ -319,20 +319,20 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int,
|
||||
|
||||
type WaitStatus uint32
|
||||
|
||||
func (WaitStatus) Exited() bool { return false }
|
||||
func (WaitStatus) Exited() bool { return false }
|
||||
|
||||
func (WaitStatus) ExitStatus() int { return -1 }
|
||||
func (WaitStatus) ExitStatus() int { return -1 }
|
||||
|
||||
func (WaitStatus) Signal() int { return -1 }
|
||||
func (WaitStatus) Signal() int { return -1 }
|
||||
|
||||
func (WaitStatus) CoreDump() bool { return false }
|
||||
func (WaitStatus) CoreDump() bool { return false }
|
||||
|
||||
func (WaitStatus) Stopped() bool { return false }
|
||||
func (WaitStatus) Stopped() bool { return false }
|
||||
|
||||
func (WaitStatus) Continued() bool { return false }
|
||||
func (WaitStatus) Continued() bool { return false }
|
||||
|
||||
func (WaitStatus) StopSignal() int { return -1 }
|
||||
func (WaitStatus) StopSignal() int { return -1 }
|
||||
|
||||
func (WaitStatus) Signaled() bool { return false }
|
||||
func (WaitStatus) Signaled() bool { return false }
|
||||
|
||||
func (WaitStatus) TrapCause() int { return -1 }
|
||||
func (WaitStatus) TrapCause() int { return -1 }
|
||||
|
@ -4,16 +4,16 @@
|
||||
|
||||
package syscall
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
||||
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||
tv.Sec = int32(nsec / 1e9);
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3);
|
||||
return;
|
||||
tv.Sec = int32(nsec / 1e9)
|
||||
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||
return
|
||||
}
|
||||
|
||||
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||
ts.Sec = int32(nsec / 1e9);
|
||||
ts.Nsec = int32(nsec % 1e9);
|
||||
return;
|
||||
ts.Sec = int32(nsec / 1e9)
|
||||
ts.Nsec = int32(nsec % 1e9)
|
||||
return
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,177 +9,177 @@ package syscall
|
||||
|
||||
// Constants
|
||||
const (
|
||||
EMULTIHOP = 0x48;
|
||||
EUNATCH = 0x31;
|
||||
EAFNOSUPPORT = 0x61;
|
||||
EREMCHG = 0x4e;
|
||||
EACCES = 0xd;
|
||||
EL3RST = 0x2f;
|
||||
EDESTADDRREQ = 0x59;
|
||||
EILSEQ = 0x54;
|
||||
ESPIPE = 0x1d;
|
||||
EMLINK = 0x1f;
|
||||
EOWNERDEAD = 0x82;
|
||||
ENOTTY = 0x19;
|
||||
EBADE = 0x34;
|
||||
EBADF = 0x9;
|
||||
EBADR = 0x35;
|
||||
EADV = 0x44;
|
||||
ERANGE = 0x22;
|
||||
ECANCELED = 0x7d;
|
||||
ETXTBSY = 0x1a;
|
||||
ENOMEM = 0xc;
|
||||
EINPROGRESS = 0x73;
|
||||
ENOTEMPTY = 0x27;
|
||||
ENOTBLK = 0xf;
|
||||
EPROTOTYPE = 0x5b;
|
||||
ERESTART = 0x55;
|
||||
EISNAM = 0x78;
|
||||
ENOMSG = 0x2a;
|
||||
EALREADY = 0x72;
|
||||
ETIMEDOUT = 0x6e;
|
||||
ENODATA = 0x3d;
|
||||
EINTR = 0x4;
|
||||
ENOLINK = 0x43;
|
||||
EPERM = 0x1;
|
||||
ELOOP = 0x28;
|
||||
ENETDOWN = 0x64;
|
||||
ESTALE = 0x74;
|
||||
ENOTSOCK = 0x58;
|
||||
ENOSR = 0x3f;
|
||||
ECHILD = 0xa;
|
||||
ELNRNG = 0x30;
|
||||
EPIPE = 0x20;
|
||||
EBADMSG = 0x4a;
|
||||
EBFONT = 0x3b;
|
||||
EREMOTE = 0x42;
|
||||
ETOOMANYREFS = 0x6d;
|
||||
EPFNOSUPPORT = 0x60;
|
||||
ENONET = 0x40;
|
||||
EXFULL = 0x36;
|
||||
EBADSLT = 0x39;
|
||||
ENOTNAM = 0x76;
|
||||
ENOCSI = 0x32;
|
||||
EADDRINUSE = 0x62;
|
||||
ENETRESET = 0x66;
|
||||
EISDIR = 0x15;
|
||||
EIDRM = 0x2b;
|
||||
ECOMM = 0x46;
|
||||
EBADFD = 0x4d;
|
||||
EL2HLT = 0x33;
|
||||
ENOKEY = 0x7e;
|
||||
EINVAL = 0x16;
|
||||
ESHUTDOWN = 0x6c;
|
||||
EKEYREJECTED = 0x81;
|
||||
ELIBSCN = 0x51;
|
||||
ENAVAIL = 0x77;
|
||||
EOVERFLOW = 0x4b;
|
||||
EUCLEAN = 0x75;
|
||||
ENOMEDIUM = 0x7b;
|
||||
EBUSY = 0x10;
|
||||
EPROTO = 0x47;
|
||||
ENODEV = 0x13;
|
||||
EKEYEXPIRED = 0x7f;
|
||||
EROFS = 0x1e;
|
||||
ELIBACC = 0x4f;
|
||||
E2BIG = 0x7;
|
||||
EDEADLK = 0x23;
|
||||
ENOTDIR = 0x14;
|
||||
ECONNRESET = 0x68;
|
||||
ENXIO = 0x6;
|
||||
EBADRQC = 0x38;
|
||||
ENAMETOOLONG = 0x24;
|
||||
ESOCKTNOSUPPORT = 0x5e;
|
||||
ELIBEXEC = 0x53;
|
||||
EDOTDOT = 0x49;
|
||||
EADDRNOTAVAIL = 0x63;
|
||||
ETIME = 0x3e;
|
||||
EPROTONOSUPPORT = 0x5d;
|
||||
ENOTRECOVERABLE = 0x83;
|
||||
EIO = 0x5;
|
||||
ENETUNREACH = 0x65;
|
||||
EXDEV = 0x12;
|
||||
EDQUOT = 0x7a;
|
||||
EREMOTEIO = 0x79;
|
||||
ENOSPC = 0x1c;
|
||||
ENOEXEC = 0x8;
|
||||
EMSGSIZE = 0x5a;
|
||||
EDOM = 0x21;
|
||||
ENOSTR = 0x3c;
|
||||
EFBIG = 0x1b;
|
||||
ESRCH = 0x3;
|
||||
ECHRNG = 0x2c;
|
||||
EHOSTDOWN = 0x70;
|
||||
ENOLCK = 0x25;
|
||||
ENFILE = 0x17;
|
||||
ENOSYS = 0x26;
|
||||
ENOTCONN = 0x6b;
|
||||
ENOTSUP = 0x5f;
|
||||
ESRMNT = 0x45;
|
||||
EDEADLOCK = 0x23;
|
||||
ECONNABORTED = 0x67;
|
||||
ENOANO = 0x37;
|
||||
EISCONN = 0x6a;
|
||||
EUSERS = 0x57;
|
||||
ENOPROTOOPT = 0x5c;
|
||||
EMFILE = 0x18;
|
||||
ENOBUFS = 0x69;
|
||||
EL3HLT = 0x2e;
|
||||
EFAULT = 0xe;
|
||||
EWOULDBLOCK = 0xb;
|
||||
ELIBBAD = 0x50;
|
||||
ESTRPIPE = 0x56;
|
||||
ECONNREFUSED = 0x6f;
|
||||
EAGAIN = 0xb;
|
||||
ELIBMAX = 0x52;
|
||||
EEXIST = 0x11;
|
||||
EL2NSYNC = 0x2d;
|
||||
ENOENT = 0x2;
|
||||
ENOPKG = 0x41;
|
||||
EKEYREVOKED = 0x80;
|
||||
EHOSTUNREACH = 0x71;
|
||||
ENOTUNIQ = 0x4c;
|
||||
EOPNOTSUPP = 0x5f;
|
||||
EMEDIUMTYPE = 0x7c;
|
||||
SIGBUS = 0x7;
|
||||
SIGTTIN = 0x15;
|
||||
SIGPROF = 0x1b;
|
||||
SIGFPE = 0x8;
|
||||
SIGHUP = 0x1;
|
||||
SIGTTOU = 0x16;
|
||||
SIGSTKFLT = 0x10;
|
||||
SIGUSR1 = 0xa;
|
||||
SIGURG = 0x17;
|
||||
SIGIO = 0x1d;
|
||||
SIGQUIT = 0x3;
|
||||
SIGCLD = 0x11;
|
||||
SHUT_RD = 0;
|
||||
SHUT_RDWR = 0x2;
|
||||
SHUT_WR = 0x1;
|
||||
SIGABRT = 0x6;
|
||||
SIGTRAP = 0x5;
|
||||
SIGVTALRM = 0x1a;
|
||||
SIGPOLL = 0x1d;
|
||||
SIGSEGV = 0xb;
|
||||
SIGCONT = 0x12;
|
||||
SIGPIPE = 0xd;
|
||||
SIGWINCH = 0x1c;
|
||||
SIGXFSZ = 0x19;
|
||||
SIGCHLD = 0x11;
|
||||
SIGSYS = 0x1f;
|
||||
SIGSTOP = 0x13;
|
||||
SIGALRM = 0xe;
|
||||
SIGUSR2 = 0xc;
|
||||
SIGTSTP = 0x14;
|
||||
SIGKILL = 0x9;
|
||||
SIGXCPU = 0x18;
|
||||
SIGUNUSED = 0x1f;
|
||||
SIGPWR = 0x1e;
|
||||
SIGILL = 0x4;
|
||||
SIGINT = 0x2;
|
||||
SIGIOT = 0x6;
|
||||
SIGTERM = 0xf;
|
||||
O_EXCL = 0x80;
|
||||
EMULTIHOP = 0x48
|
||||
EUNATCH = 0x31
|
||||
EAFNOSUPPORT = 0x61
|
||||
EREMCHG = 0x4e
|
||||
EACCES = 0xd
|
||||
EL3RST = 0x2f
|
||||
EDESTADDRREQ = 0x59
|
||||
EILSEQ = 0x54
|
||||
ESPIPE = 0x1d
|
||||
EMLINK = 0x1f
|
||||
EOWNERDEAD = 0x82
|
||||
ENOTTY = 0x19
|
||||
EBADE = 0x34
|
||||
EBADF = 0x9
|
||||
EBADR = 0x35
|
||||
EADV = 0x44
|
||||
ERANGE = 0x22
|
||||
ECANCELED = 0x7d
|
||||
ETXTBSY = 0x1a
|
||||
ENOMEM = 0xc
|
||||
EINPROGRESS = 0x73
|
||||
ENOTEMPTY = 0x27
|
||||
ENOTBLK = 0xf
|
||||
EPROTOTYPE = 0x5b
|
||||
ERESTART = 0x55
|
||||
EISNAM = 0x78
|
||||
ENOMSG = 0x2a
|
||||
EALREADY = 0x72
|
||||
ETIMEDOUT = 0x6e
|
||||
ENODATA = 0x3d
|
||||
EINTR = 0x4
|
||||
ENOLINK = 0x43
|
||||
EPERM = 0x1
|
||||
ELOOP = 0x28
|
||||
ENETDOWN = 0x64
|
||||
ESTALE = 0x74
|
||||
ENOTSOCK = 0x58
|
||||
ENOSR = 0x3f
|
||||
ECHILD = 0xa
|
||||
ELNRNG = 0x30
|
||||
EPIPE = 0x20
|
||||
EBADMSG = 0x4a
|
||||
EBFONT = 0x3b
|
||||
EREMOTE = 0x42
|
||||
ETOOMANYREFS = 0x6d
|
||||
EPFNOSUPPORT = 0x60
|
||||
ENONET = 0x40
|
||||
EXFULL = 0x36
|
||||
EBADSLT = 0x39
|
||||
ENOTNAM = 0x76
|
||||
ENOCSI = 0x32
|
||||
EADDRINUSE = 0x62
|
||||
ENETRESET = 0x66
|
||||
EISDIR = 0x15
|
||||
EIDRM = 0x2b
|
||||
ECOMM = 0x46
|
||||
EBADFD = 0x4d
|
||||
EL2HLT = 0x33
|
||||
ENOKEY = 0x7e
|
||||
EINVAL = 0x16
|
||||
ESHUTDOWN = 0x6c
|
||||
EKEYREJECTED = 0x81
|
||||
ELIBSCN = 0x51
|
||||
ENAVAIL = 0x77
|
||||
EOVERFLOW = 0x4b
|
||||
EUCLEAN = 0x75
|
||||
ENOMEDIUM = 0x7b
|
||||
EBUSY = 0x10
|
||||
EPROTO = 0x47
|
||||
ENODEV = 0x13
|
||||
EKEYEXPIRED = 0x7f
|
||||
EROFS = 0x1e
|
||||
ELIBACC = 0x4f
|
||||
E2BIG = 0x7
|
||||
EDEADLK = 0x23
|
||||
ENOTDIR = 0x14
|
||||
ECONNRESET = 0x68
|
||||
ENXIO = 0x6
|
||||
EBADRQC = 0x38
|
||||
ENAMETOOLONG = 0x24
|
||||
ESOCKTNOSUPPORT = 0x5e
|
||||
ELIBEXEC = 0x53
|
||||
EDOTDOT = 0x49
|
||||
EADDRNOTAVAIL = 0x63
|
||||
ETIME = 0x3e
|
||||
EPROTONOSUPPORT = 0x5d
|
||||
ENOTRECOVERABLE = 0x83
|
||||
EIO = 0x5
|
||||
ENETUNREACH = 0x65
|
||||
EXDEV = 0x12
|
||||
EDQUOT = 0x7a
|
||||
EREMOTEIO = 0x79
|
||||
ENOSPC = 0x1c
|
||||
ENOEXEC = 0x8
|
||||
EMSGSIZE = 0x5a
|
||||
EDOM = 0x21
|
||||
ENOSTR = 0x3c
|
||||
EFBIG = 0x1b
|
||||
ESRCH = 0x3
|
||||
ECHRNG = 0x2c
|
||||
EHOSTDOWN = 0x70
|
||||
ENOLCK = 0x25
|
||||
ENFILE = 0x17
|
||||
ENOSYS = 0x26
|
||||
ENOTCONN = 0x6b
|
||||
ENOTSUP = 0x5f
|
||||
ESRMNT = 0x45
|
||||
EDEADLOCK = 0x23
|
||||
ECONNABORTED = 0x67
|
||||
ENOANO = 0x37
|
||||
EISCONN = 0x6a
|
||||
EUSERS = 0x57
|
||||
ENOPROTOOPT = 0x5c
|
||||
EMFILE = 0x18
|
||||
ENOBUFS = 0x69
|
||||
EL3HLT = 0x2e
|
||||
EFAULT = 0xe
|
||||
EWOULDBLOCK = 0xb
|
||||
ELIBBAD = 0x50
|
||||
ESTRPIPE = 0x56
|
||||
ECONNREFUSED = 0x6f
|
||||
EAGAIN = 0xb
|
||||
ELIBMAX = 0x52
|
||||
EEXIST = 0x11
|
||||
EL2NSYNC = 0x2d
|
||||
ENOENT = 0x2
|
||||
ENOPKG = 0x41
|
||||
EKEYREVOKED = 0x80
|
||||
EHOSTUNREACH = 0x71
|
||||
ENOTUNIQ = 0x4c
|
||||
EOPNOTSUPP = 0x5f
|
||||
EMEDIUMTYPE = 0x7c
|
||||
SIGBUS = 0x7
|
||||
SIGTTIN = 0x15
|
||||
SIGPROF = 0x1b
|
||||
SIGFPE = 0x8
|
||||
SIGHUP = 0x1
|
||||
SIGTTOU = 0x16
|
||||
SIGSTKFLT = 0x10
|
||||
SIGUSR1 = 0xa
|
||||
SIGURG = 0x17
|
||||
SIGIO = 0x1d
|
||||
SIGQUIT = 0x3
|
||||
SIGCLD = 0x11
|
||||
SHUT_RD = 0
|
||||
SHUT_RDWR = 0x2
|
||||
SHUT_WR = 0x1
|
||||
SIGABRT = 0x6
|
||||
SIGTRAP = 0x5
|
||||
SIGVTALRM = 0x1a
|
||||
SIGPOLL = 0x1d
|
||||
SIGSEGV = 0xb
|
||||
SIGCONT = 0x12
|
||||
SIGPIPE = 0xd
|
||||
SIGWINCH = 0x1c
|
||||
SIGXFSZ = 0x19
|
||||
SIGCHLD = 0x11
|
||||
SIGSYS = 0x1f
|
||||
SIGSTOP = 0x13
|
||||
SIGALRM = 0xe
|
||||
SIGUSR2 = 0xc
|
||||
SIGTSTP = 0x14
|
||||
SIGKILL = 0x9
|
||||
SIGXCPU = 0x18
|
||||
SIGUNUSED = 0x1f
|
||||
SIGPWR = 0x1e
|
||||
SIGILL = 0x4
|
||||
SIGINT = 0x2
|
||||
SIGIOT = 0x6
|
||||
SIGTERM = 0xf
|
||||
O_EXCL = 0x80
|
||||
)
|
||||
|
||||
// Types
|
||||
|
@ -4,126 +4,126 @@
|
||||
package syscall
|
||||
|
||||
const (
|
||||
EPERM = 1;
|
||||
ENOENT = 2;
|
||||
ESRCH = 3;
|
||||
EINTR = 4;
|
||||
EIO = 5;
|
||||
ENXIO = 6;
|
||||
E2BIG = 7;
|
||||
ENOEXEC = 8;
|
||||
EBADF = 9;
|
||||
ECHILD = 10;
|
||||
EAGAIN = 11;
|
||||
ENOMEM = 12;
|
||||
EACCES = 13;
|
||||
EFAULT = 14;
|
||||
EBUSY = 16;
|
||||
EEXIST = 17;
|
||||
EXDEV = 18;
|
||||
ENODEV = 19;
|
||||
ENOTDIR = 20;
|
||||
EISDIR = 21;
|
||||
EINVAL = 22;
|
||||
ENFILE = 23;
|
||||
EMFILE = 24;
|
||||
ENOTTY = 25;
|
||||
EFBIG = 27;
|
||||
ENOSPC = 28;
|
||||
ESPIPE = 29;
|
||||
EROFS = 30;
|
||||
EMLINK = 31;
|
||||
EPIPE = 32;
|
||||
ENAMETOOLONG = 36;
|
||||
ENOSYS = 38;
|
||||
EDQUOT = 122;
|
||||
EDOM = 33;
|
||||
ERANGE = 34;
|
||||
ENOMSG = 35;
|
||||
ECHRNG = 37;
|
||||
EL3HLT = 39;
|
||||
EL3RST = 40;
|
||||
ELNRNG = 41;
|
||||
EUNATCH = 42;
|
||||
ENOCSI = 43;
|
||||
EL2HLT = 44;
|
||||
EDEADLK = 45;
|
||||
ENOLCK = 46;
|
||||
EBADE = 50;
|
||||
EBADR = 51;
|
||||
EXFULL = 52;
|
||||
ENOANO = 53;
|
||||
EBADRQC = 54;
|
||||
EBADSLT = 55;
|
||||
EBFONT = 57;
|
||||
ENOSTR = 60;
|
||||
ENODATA = 61;
|
||||
ETIME = 62;
|
||||
ENOSR = 63;
|
||||
ENONET = 64;
|
||||
ENOPKG = 65;
|
||||
EREMOTE = 66;
|
||||
ENOLINK = 67;
|
||||
EADV = 68;
|
||||
ESRMNT = 69;
|
||||
ECOMM = 70;
|
||||
EPROTO = 71;
|
||||
EMULTIHOP = 74;
|
||||
ELBIN = 75;
|
||||
EDOTDOT = 76;
|
||||
EBADMSG = 77;
|
||||
EFTYPE = 79;
|
||||
ENOTUNIQ = 80;
|
||||
EBADFD = 81;
|
||||
EREMCHG = 82;
|
||||
ELIBACC = 83;
|
||||
ELIBBAD = 84;
|
||||
ELIBSCN = 85;
|
||||
ELIBMAX = 86;
|
||||
ELIBEXEC = 87;
|
||||
ENMFILE = 89;
|
||||
ENOTEMPTY = 90;
|
||||
ELOOP = 92;
|
||||
EOPNOTSUPP = 95;
|
||||
EPFNOSUPPORT = 96;
|
||||
ECONNRESET = 104;
|
||||
ENOBUFS = 105;
|
||||
EAFNOSUPPORT = 106;
|
||||
EPROTOTYPE = 107;
|
||||
ENOTSOCK = 108;
|
||||
ENOPROTOOPT = 109;
|
||||
ESHUTDOWN = 110;
|
||||
ECONNREFUSED = 111;
|
||||
EADDRINUSE = 112;
|
||||
ECONNABORTED = 113;
|
||||
ENETUNREACH = 114;
|
||||
ENETDOWN = 115;
|
||||
ETIMEDOUT = 116;
|
||||
EHOSTDOWN = 117;
|
||||
EHOSTUNREACH = 118;
|
||||
EINPROGRESS = 119;
|
||||
EALREADY = 120;
|
||||
EDESTADDRREQ = 121;
|
||||
EPROTONOSUPPORT = 123;
|
||||
ESOCKTNOSUPPORT = 124;
|
||||
EADDRNOTAVAIL = 125;
|
||||
ENETRESET = 126;
|
||||
EISCONN = 127;
|
||||
ENOTCONN = 128;
|
||||
ETOOMANYREFS = 129;
|
||||
EPROCLIM = 130;
|
||||
EUSERS = 131;
|
||||
ESTALE = 133;
|
||||
ENOMEDIUM = 135;
|
||||
ENOSHARE = 136;
|
||||
ECASECLASH = 137;
|
||||
EILSEQ = 138;
|
||||
EOVERFLOW = 139;
|
||||
ECANCELED = 140;
|
||||
EL2NSYNC = 88;
|
||||
EIDRM = 91;
|
||||
EMSGSIZE = 132;
|
||||
ENACL = 99; /* otherwise unused */
|
||||
EPERM = 1
|
||||
ENOENT = 2
|
||||
ESRCH = 3
|
||||
EINTR = 4
|
||||
EIO = 5
|
||||
ENXIO = 6
|
||||
E2BIG = 7
|
||||
ENOEXEC = 8
|
||||
EBADF = 9
|
||||
ECHILD = 10
|
||||
EAGAIN = 11
|
||||
ENOMEM = 12
|
||||
EACCES = 13
|
||||
EFAULT = 14
|
||||
EBUSY = 16
|
||||
EEXIST = 17
|
||||
EXDEV = 18
|
||||
ENODEV = 19
|
||||
ENOTDIR = 20
|
||||
EISDIR = 21
|
||||
EINVAL = 22
|
||||
ENFILE = 23
|
||||
EMFILE = 24
|
||||
ENOTTY = 25
|
||||
EFBIG = 27
|
||||
ENOSPC = 28
|
||||
ESPIPE = 29
|
||||
EROFS = 30
|
||||
EMLINK = 31
|
||||
EPIPE = 32
|
||||
ENAMETOOLONG = 36
|
||||
ENOSYS = 38
|
||||
EDQUOT = 122
|
||||
EDOM = 33
|
||||
ERANGE = 34
|
||||
ENOMSG = 35
|
||||
ECHRNG = 37
|
||||
EL3HLT = 39
|
||||
EL3RST = 40
|
||||
ELNRNG = 41
|
||||
EUNATCH = 42
|
||||
ENOCSI = 43
|
||||
EL2HLT = 44
|
||||
EDEADLK = 45
|
||||
ENOLCK = 46
|
||||
EBADE = 50
|
||||
EBADR = 51
|
||||
EXFULL = 52
|
||||
ENOANO = 53
|
||||
EBADRQC = 54
|
||||
EBADSLT = 55
|
||||
EBFONT = 57
|
||||
ENOSTR = 60
|
||||
ENODATA = 61
|
||||
ETIME = 62
|
||||
ENOSR = 63
|
||||
ENONET = 64
|
||||
ENOPKG = 65
|
||||
EREMOTE = 66
|
||||
ENOLINK = 67
|
||||
EADV = 68
|
||||
ESRMNT = 69
|
||||
ECOMM = 70
|
||||
EPROTO = 71
|
||||
EMULTIHOP = 74
|
||||
ELBIN = 75
|
||||
EDOTDOT = 76
|
||||
EBADMSG = 77
|
||||
EFTYPE = 79
|
||||
ENOTUNIQ = 80
|
||||
EBADFD = 81
|
||||
EREMCHG = 82
|
||||
ELIBACC = 83
|
||||
ELIBBAD = 84
|
||||
ELIBSCN = 85
|
||||
ELIBMAX = 86
|
||||
ELIBEXEC = 87
|
||||
ENMFILE = 89
|
||||
ENOTEMPTY = 90
|
||||
ELOOP = 92
|
||||
EOPNOTSUPP = 95
|
||||
EPFNOSUPPORT = 96
|
||||
ECONNRESET = 104
|
||||
ENOBUFS = 105
|
||||
EAFNOSUPPORT = 106
|
||||
EPROTOTYPE = 107
|
||||
ENOTSOCK = 108
|
||||
ENOPROTOOPT = 109
|
||||
ESHUTDOWN = 110
|
||||
ECONNREFUSED = 111
|
||||
EADDRINUSE = 112
|
||||
ECONNABORTED = 113
|
||||
ENETUNREACH = 114
|
||||
ENETDOWN = 115
|
||||
ETIMEDOUT = 116
|
||||
EHOSTDOWN = 117
|
||||
EHOSTUNREACH = 118
|
||||
EINPROGRESS = 119
|
||||
EALREADY = 120
|
||||
EDESTADDRREQ = 121
|
||||
EPROTONOSUPPORT = 123
|
||||
ESOCKTNOSUPPORT = 124
|
||||
EADDRNOTAVAIL = 125
|
||||
ENETRESET = 126
|
||||
EISCONN = 127
|
||||
ENOTCONN = 128
|
||||
ETOOMANYREFS = 129
|
||||
EPROCLIM = 130
|
||||
EUSERS = 131
|
||||
ESTALE = 133
|
||||
ENOMEDIUM = 135
|
||||
ENOSHARE = 136
|
||||
ECASECLASH = 137
|
||||
EILSEQ = 138
|
||||
EOVERFLOW = 139
|
||||
ECANCELED = 140
|
||||
EL2NSYNC = 88
|
||||
EIDRM = 91
|
||||
EMSGSIZE = 132
|
||||
ENACL = 99 /* otherwise unused */
|
||||
)
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -6,662 +6,662 @@ package syscall
|
||||
import "unsafe"
|
||||
|
||||
func getgroups(ngid int, gid *_Gid_t) (n int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func setgroups(ngid int, gid *_Gid_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, errno int) {
|
||||
r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0);
|
||||
wpid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
|
||||
wpid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func pipe() (r int, w int, errno int) {
|
||||
r0, r1, e1 := Syscall(SYS_PIPE, 0, 0, 0);
|
||||
r = int(r0);
|
||||
w = int(r1);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, r1, e1 := Syscall(SYS_PIPE, 0, 0, 0)
|
||||
r = int(r0)
|
||||
w = int(r1)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func bind(s int, addr uintptr, addrlen _Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func connect(s int, addr uintptr, addrlen _Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func socket(domain int, typ int, proto int) (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto));
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int) {
|
||||
_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Shutdown(s int, how int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func sendto(s int, buf []byte, flags int, to uintptr, addrlen _Socklen) (errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, timeout *Timespec) (n int, errno int) {
|
||||
r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) {
|
||||
var _p0 *_C_int;
|
||||
var _p0 *_C_int
|
||||
if len(mib) > 0 {
|
||||
_p0 = &mib[0]
|
||||
}
|
||||
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(unsafe.Pointer(_p0)), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(unsafe.Pointer(_p0)), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func fcntl(fd int, cmd int, arg int) (val int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg));
|
||||
val = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
|
||||
val = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Access(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Adjtime(delta *Timeval, olddelta *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chdir(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chflags(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chmod(path string, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chown(path string, uid int, gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chroot(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Close(fd int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Dup(fd int) (nfd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0);
|
||||
nfd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
|
||||
nfd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Dup2(from int, to int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Exit(code int) {
|
||||
Syscall(SYS_EXIT, uintptr(code), 0, 0);
|
||||
return;
|
||||
Syscall(SYS_EXIT, uintptr(code), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchdir(fd int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchflags(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchmod(fd int, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchown(fd int, uid int, gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Flock(fd int, how int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fpathconf(fd int, name int) (val int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0);
|
||||
val = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
|
||||
val = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fstat(fd int, stat *Stat_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fstatfs(fd int, stat *Statfs_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fsync(fd int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Ftruncate(fd int, length int64) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getdtablesize() (size int) {
|
||||
r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0);
|
||||
size = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
|
||||
size = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getegid() (egid int) {
|
||||
r0, _, _ := Syscall(SYS_GETEGID, 0, 0, 0);
|
||||
egid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETEGID, 0, 0, 0)
|
||||
egid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Geteuid() (uid int) {
|
||||
r0, _, _ := Syscall(SYS_GETEUID, 0, 0, 0);
|
||||
uid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETEUID, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getfsstat(buf []Statfs_t, flags int) (n int, errno int) {
|
||||
var _p0 *Statfs_t;
|
||||
var _p0 *Statfs_t
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getgid() (gid int) {
|
||||
r0, _, _ := Syscall(SYS_GETGID, 0, 0, 0);
|
||||
gid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETGID, 0, 0, 0)
|
||||
gid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpgid(pid int) (pgid int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETPGID, uintptr(pid), 0, 0);
|
||||
pgid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETPGID, uintptr(pid), 0, 0)
|
||||
pgid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpgrp() (pgrp int) {
|
||||
r0, _, _ := Syscall(SYS_GETPGRP, 0, 0, 0);
|
||||
pgrp = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETPGRP, 0, 0, 0)
|
||||
pgrp = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpid() (pid int) {
|
||||
r0, _, _ := Syscall(SYS_GETPID, 0, 0, 0);
|
||||
pid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETPID, 0, 0, 0)
|
||||
pid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getppid() (ppid int) {
|
||||
r0, _, _ := Syscall(SYS_GETPPID, 0, 0, 0);
|
||||
ppid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETPPID, 0, 0, 0)
|
||||
ppid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpriority(which int, who int) (prio int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0);
|
||||
prio = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
|
||||
prio = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getrlimit(which int, lim *Rlimit) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getrusage(who int, rusage *Rusage) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getsid(pid int) (sid int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETSID, uintptr(pid), 0, 0);
|
||||
sid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETSID, uintptr(pid), 0, 0)
|
||||
sid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Gettimeofday(tv *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getuid() (uid int) {
|
||||
r0, _, _ := Syscall(SYS_GETUID, 0, 0, 0);
|
||||
uid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETUID, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Issetugid() (tainted bool) {
|
||||
r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0);
|
||||
tainted = bool(r0 != 0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
|
||||
tainted = bool(r0 != 0)
|
||||
return
|
||||
}
|
||||
|
||||
func Kill(pid int, signum int, posix int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Kqueue() (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0);
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Lchown(path string, uid int, gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Link(path string, link string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Listen(s int, backlog int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Lstat(path string, stat *Stat_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Mkdir(path string, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Mkfifo(path string, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Mknod(path string, mode int, dev int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(dev));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(dev))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Open(path string, mode int, perm int) (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm));
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm))
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Pathconf(path string, name int) (val int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(name), 0);
|
||||
val = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(name), 0)
|
||||
val = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Pread(fd int, p []byte, offset int64) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Read(fd int, p []byte) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Readlink(path string, buf []byte) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Rename(from string, to string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(StringBytePtr(from))), uintptr(unsafe.Pointer(StringBytePtr(to))), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(StringBytePtr(from))), uintptr(unsafe.Pointer(StringBytePtr(to))), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Revoke(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Rmdir(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
|
||||
r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0);
|
||||
newoffset = int64(int64(r1)<<32 | int64(r0));
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
|
||||
newoffset = int64(int64(r1)<<32 | int64(r0))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setegid(egid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Seteuid(euid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETEUID, uintptr(euid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETEUID, uintptr(euid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setgid(gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETGID, uintptr(gid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETGID, uintptr(gid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setlogin(name string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(StringBytePtr(name))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(StringBytePtr(name))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setpgid(pid int, pgid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setpriority(which int, who int, prio int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setregid(rgid int, egid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setreuid(ruid int, euid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setrlimit(which int, lim *Rlimit) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setsid() (pid int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_SETSID, 0, 0, 0);
|
||||
pid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_SETSID, 0, 0, 0)
|
||||
pid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Settimeofday(tp *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setuid(uid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETUID, uintptr(uid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETUID, uintptr(uid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Stat(path string, stat *Stat_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Statfs(path string, stat *Statfs_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Symlink(path string, link string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Sync() (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Truncate(path string, length int64) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(length), uintptr(length>>32));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(length), uintptr(length>>32))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Umask(newmask int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UMASK, uintptr(newmask), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Undelete(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Unlink(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Unmount(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Write(fd int, p []byte) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func read(fd int, buf *byte, nbuf int) (n int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func write(fd int, buf *byte, nbuf int) (n int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
@ -6,662 +6,662 @@ package syscall
|
||||
import "unsafe"
|
||||
|
||||
func getgroups(ngid int, gid *_Gid_t) (n int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func setgroups(ngid int, gid *_Gid_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, errno int) {
|
||||
r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0);
|
||||
wpid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
|
||||
wpid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func pipe() (r int, w int, errno int) {
|
||||
r0, r1, e1 := Syscall(SYS_PIPE, 0, 0, 0);
|
||||
r = int(r0);
|
||||
w = int(r1);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, r1, e1 := Syscall(SYS_PIPE, 0, 0, 0)
|
||||
r = int(r0)
|
||||
w = int(r1)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func bind(s int, addr uintptr, addrlen _Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func connect(s int, addr uintptr, addrlen _Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func socket(domain int, typ int, proto int) (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto));
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func setsockopt(s int, level int, name int, val uintptr, vallen int) (errno int) {
|
||||
_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Shutdown(s int, how int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func sendto(s int, buf []byte, flags int, to uintptr, addrlen _Socklen) (errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func kevent(kq int, change uintptr, nchange int, event uintptr, nevent int, timeout *Timespec) (n int, errno int) {
|
||||
r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (errno int) {
|
||||
var _p0 *_C_int;
|
||||
var _p0 *_C_int
|
||||
if len(mib) > 0 {
|
||||
_p0 = &mib[0]
|
||||
}
|
||||
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(unsafe.Pointer(_p0)), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(unsafe.Pointer(_p0)), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func fcntl(fd int, cmd int, arg int) (val int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg));
|
||||
val = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
|
||||
val = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Access(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Adjtime(delta *Timeval, olddelta *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chdir(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chflags(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chmod(path string, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chown(path string, uid int, gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Chroot(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Close(fd int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Dup(fd int) (nfd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0);
|
||||
nfd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
|
||||
nfd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Dup2(from int, to int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Exit(code int) {
|
||||
Syscall(SYS_EXIT, uintptr(code), 0, 0);
|
||||
return;
|
||||
Syscall(SYS_EXIT, uintptr(code), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchdir(fd int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchflags(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchmod(fd int, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchown(fd int, uid int, gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Flock(fd int, how int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fpathconf(fd int, name int) (val int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0);
|
||||
val = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
|
||||
val = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fstat(fd int, stat *Stat_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fstatfs(fd int, stat *Statfs_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Fsync(fd int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Ftruncate(fd int, length int64) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getdtablesize() (size int) {
|
||||
r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0);
|
||||
size = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
|
||||
size = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getegid() (egid int) {
|
||||
r0, _, _ := Syscall(SYS_GETEGID, 0, 0, 0);
|
||||
egid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETEGID, 0, 0, 0)
|
||||
egid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Geteuid() (uid int) {
|
||||
r0, _, _ := Syscall(SYS_GETEUID, 0, 0, 0);
|
||||
uid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETEUID, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getfsstat(buf []Statfs_t, flags int) (n int, errno int) {
|
||||
var _p0 *Statfs_t;
|
||||
var _p0 *Statfs_t
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getgid() (gid int) {
|
||||
r0, _, _ := Syscall(SYS_GETGID, 0, 0, 0);
|
||||
gid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETGID, 0, 0, 0)
|
||||
gid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpgid(pid int) (pgid int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETPGID, uintptr(pid), 0, 0);
|
||||
pgid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETPGID, uintptr(pid), 0, 0)
|
||||
pgid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpgrp() (pgrp int) {
|
||||
r0, _, _ := Syscall(SYS_GETPGRP, 0, 0, 0);
|
||||
pgrp = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETPGRP, 0, 0, 0)
|
||||
pgrp = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpid() (pid int) {
|
||||
r0, _, _ := Syscall(SYS_GETPID, 0, 0, 0);
|
||||
pid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETPID, 0, 0, 0)
|
||||
pid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getppid() (ppid int) {
|
||||
r0, _, _ := Syscall(SYS_GETPPID, 0, 0, 0);
|
||||
ppid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETPPID, 0, 0, 0)
|
||||
ppid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Getpriority(which int, who int) (prio int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0);
|
||||
prio = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
|
||||
prio = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getrlimit(which int, lim *Rlimit) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getrusage(who int, rusage *Rusage) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getsid(pid int) (sid int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_GETSID, uintptr(pid), 0, 0);
|
||||
sid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_GETSID, uintptr(pid), 0, 0)
|
||||
sid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Gettimeofday(tv *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Getuid() (uid int) {
|
||||
r0, _, _ := Syscall(SYS_GETUID, 0, 0, 0);
|
||||
uid = int(r0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_GETUID, 0, 0, 0)
|
||||
uid = int(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func Issetugid() (tainted bool) {
|
||||
r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0);
|
||||
tainted = bool(r0 != 0);
|
||||
return;
|
||||
r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
|
||||
tainted = bool(r0 != 0)
|
||||
return
|
||||
}
|
||||
|
||||
func Kill(pid int, signum int, posix int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Kqueue() (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0);
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Lchown(path string, uid int, gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(uid), uintptr(gid))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Link(path string, link string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Listen(s int, backlog int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Lstat(path string, stat *Stat_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Mkdir(path string, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Mkfifo(path string, mode int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Mknod(path string, mode int, dev int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(dev));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(dev))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Open(path string, mode int, perm int) (fd int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm));
|
||||
fd = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm))
|
||||
fd = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Pathconf(path string, name int) (val int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(name), 0);
|
||||
val = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(name), 0)
|
||||
val = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Pread(fd int, p []byte, offset int64) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Pwrite(fd int, p []byte, offset int64) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0);
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0)
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Read(fd int, p []byte) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Readlink(path string, buf []byte) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(buf) > 0 {
|
||||
_p0 = &buf[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Rename(from string, to string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(StringBytePtr(from))), uintptr(unsafe.Pointer(StringBytePtr(to))), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(StringBytePtr(from))), uintptr(unsafe.Pointer(StringBytePtr(to))), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Revoke(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Rmdir(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Seek(fd int, offset int64, whence int) (newoffset int64, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence));
|
||||
newoffset = int64(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
|
||||
newoffset = int64(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setegid(egid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Seteuid(euid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETEUID, uintptr(euid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETEUID, uintptr(euid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setgid(gid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETGID, uintptr(gid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETGID, uintptr(gid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setlogin(name string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(StringBytePtr(name))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(StringBytePtr(name))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setpgid(pid int, pgid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setpriority(which int, who int, prio int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio));
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setregid(rgid int, egid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setreuid(ruid int, euid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setrlimit(which int, lim *Rlimit) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setsid() (pid int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_SETSID, 0, 0, 0);
|
||||
pid = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_SETSID, 0, 0, 0)
|
||||
pid = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Settimeofday(tp *Timeval) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Setuid(uid int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SETUID, uintptr(uid), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SETUID, uintptr(uid), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Stat(path string, stat *Stat_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Statfs(path string, stat *Statfs_t) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(stat)), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Symlink(path string, link string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(unsafe.Pointer(StringBytePtr(link))), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Sync() (errno int) {
|
||||
_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Truncate(path string, length int64) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(length), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(length), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Umask(newmask int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UMASK, uintptr(newmask), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Undelete(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Unlink(path string) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(StringBytePtr(path))), 0, 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Unmount(path string, flags int) (errno int) {
|
||||
_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(flags), 0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func Write(fd int, p []byte) (n int, errno int) {
|
||||
var _p0 *byte;
|
||||
var _p0 *byte
|
||||
if len(p) > 0 {
|
||||
_p0 = &p[0]
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func read(fd int, buf *byte, nbuf int) (n int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
||||
func write(fd int, buf *byte, nbuf int) (n int, errno int) {
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf));
|
||||
n = int(r0);
|
||||
errno = int(e1);
|
||||
return;
|
||||
r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
|
||||
n = int(r0)
|
||||
errno = int(e1)
|
||||
return
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user