From 55e2a2334852996df9c39011c93a6c94d5c43155 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 12 Aug 2014 17:00:33 -0700 Subject: [PATCH] go.sys/unix: delete nacl It's a peculiar environment that probably doesn't belong here. We can bring it back easily if we need it. LGTM=dave, rsc R=rsc, dave CC=golang-codereviews https://golang.org/cl/128110043 --- unix/asm_nacl_386.s | 43 -- unix/asm_nacl_amd64p32.s | 41 -- unix/asm_nacl_arm.s | 43 -- unix/env_unix.go | 2 +- unix/fd_nacl.go | 326 ------------ unix/fs_nacl.go | 832 ------------------------------ unix/mkall.sh | 12 - unix/mksyscall.pl | 8 - unix/net_nacl.go | 912 --------------------------------- unix/srpc_nacl.go | 822 ----------------------------- unix/syscall_nacl.go | 311 ----------- unix/syscall_nacl_386.go | 32 -- unix/syscall_nacl_amd64p32.go | 32 -- unix/syscall_nacl_arm.go | 32 -- unix/tables_nacl.go | 324 ------------ unix/time_nacl_386.s | 11 - unix/time_nacl_amd64p32.s | 11 - unix/time_nacl_arm.s | 11 - unix/unzip_nacl.go | 685 ------------------------- unix/zsyscall_nacl_386.go | 63 --- unix/zsyscall_nacl_amd64p32.go | 63 --- unix/zsyscall_nacl_arm.go | 63 --- 22 files changed, 1 insertion(+), 4678 deletions(-) delete mode 100644 unix/asm_nacl_386.s delete mode 100644 unix/asm_nacl_amd64p32.s delete mode 100644 unix/asm_nacl_arm.s delete mode 100644 unix/fd_nacl.go delete mode 100644 unix/fs_nacl.go delete mode 100644 unix/net_nacl.go delete mode 100644 unix/srpc_nacl.go delete mode 100644 unix/syscall_nacl.go delete mode 100644 unix/syscall_nacl_386.go delete mode 100644 unix/syscall_nacl_amd64p32.go delete mode 100644 unix/syscall_nacl_arm.go delete mode 100644 unix/tables_nacl.go delete mode 100644 unix/time_nacl_386.s delete mode 100644 unix/time_nacl_amd64p32.s delete mode 100644 unix/time_nacl_arm.s delete mode 100644 unix/unzip_nacl.go delete mode 100644 unix/zsyscall_nacl_386.go delete mode 100644 unix/zsyscall_nacl_amd64p32.go delete mode 100644 unix/zsyscall_nacl_arm.go diff --git a/unix/asm_nacl_386.s b/unix/asm_nacl_386.s deleted file mode 100644 index cf041317..00000000 --- a/unix/asm_nacl_386.s +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" -#include "../runtime/syscall_nacl.h" // TODO: how to refer to this? - -// -// System call support for 386, Native Client -// - -#define NACL_SYSCALL(code) \ - MOVL $(0x10000 + ((code)<<5)), AX; CALL AX - -#define NACL_SYSJMP(code) \ - MOVL $(0x10000 + ((code)<<5)), AX; JMP AX - -TEXT unix·Syscall(SB),NOSPLIT,$12-28 - CALL runtime·entersyscall(SB) - MOVL trap+0(FP), AX - MOVL a1+4(FP), BX - MOVL BX, 0(SP) - MOVL a2+8(FP), BX - MOVL BX, 4(SP) - MOVL a3+12(FP), BX - MOVL BX, 8(SP) - SHLL $5, AX - ADDL $0x10000, AX - CALL AX - CMPL AX, $0 - JGE ok - MOVL $-1, r1+16(FP) - MOVL $-1, r2+20(FP) - NEGL AX - MOVL AX, err+24(FP) - CALL runtime·exitsyscall(SB) - RET -ok: - MOVL AX, r1+16(FP) - MOVL DX, r2+20(FP) - MOVL $0, err+24(FP) - CALL runtime·exitsyscall(SB) - RET diff --git a/unix/asm_nacl_amd64p32.s b/unix/asm_nacl_amd64p32.s deleted file mode 100644 index 9e46d7bc..00000000 --- a/unix/asm_nacl_amd64p32.s +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" -#include "../runtime/syscall_nacl.h" // TODO: how to refer to this? - -// -// System call support for amd64, Native Client -// - -#define NACL_SYSCALL(code) \ - MOVL $(0x10000 + ((code)<<5)), AX; CALL AX - -#define NACL_SYSJMP(code) \ - MOVL $(0x10000 + ((code)<<5)), AX; JMP AX - -TEXT unix·Syscall(SB),NOSPLIT,$0-28 - CALL runtime·entersyscall(SB) - MOVL trap+0(FP), AX - MOVL a1+4(FP), DI - MOVL a2+8(FP), SI - MOVL a3+12(FP), DX - // more args would use CX, R8, R9 - SHLL $5, AX - ADDL $0x10000, AX - CALL AX - CMPL AX, $0 - JGE ok - MOVL $-1, r1+16(FP) - MOVL $-1, r2+20(FP) - NEGL AX - MOVL AX, err+24(FP) - CALL runtime·exitsyscall(SB) - RET -ok: - MOVL AX, r1+16(FP) - MOVL DX, r2+20(FP) - MOVL $0, err+24(FP) - CALL runtime·exitsyscall(SB) - RET diff --git a/unix/asm_nacl_arm.s b/unix/asm_nacl_arm.s deleted file mode 100644 index ee8eb840..00000000 --- a/unix/asm_nacl_arm.s +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" -#include "../runtime/syscall_nacl.h" // TODO: how to refer to this? - -// -// System call support for ARM, Native Client -// - -#define NACL_SYSCALL(code) \ - MOVW $(0x10000 + ((code)<<5)), R8; BL (R8) - -#define NACL_SYSJMP(code) \ - MOVW $(0x10000 + ((code)<<5)), R8; B (R8) - -TEXT unix·Syscall(SB),NOSPLIT,$0-28 - BL runtime·entersyscall(SB) - MOVW trap+0(FP), R8 - MOVW a1+4(FP), R0 - MOVW a2+8(FP), R1 - MOVW a3+12(FP), R2 - // more args would use R3, and then stack. - MOVW $0x10000, R7 - ADD R8<<5, R7 - BL (R7) - CMP $0, R0 - BGE ok - MOVW $-1, R1 - MOVW R1, r1+16(FP) - MOVW R1, r2+20(FP) - RSB $0, R0 - MOVW R0, err+24(FP) - BL runtime·exitsyscall(SB) - RET -ok: - MOVW R0, r1+16(FP) - MOVW R1, r2+20(FP) - MOVW $0, R2 - MOVW R2, err+24(FP) - BL runtime·exitsyscall(SB) - RET diff --git a/unix/env_unix.go b/unix/env_unix.go index 19223eb8..c630bdab 100644 --- a/unix/env_unix.go +++ b/unix/env_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris +// +build darwin dragonfly freebsd linux netbsd openbsd solaris // Unix environment variables. diff --git a/unix/fd_nacl.go b/unix/fd_nacl.go deleted file mode 100644 index 3f67bb43..00000000 --- a/unix/fd_nacl.go +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// File descriptor support for Native Client. -// We want to provide access to a broader range of (simulated) files than -// Native Client allows, so we maintain our own file descriptor table exposed -// to higher-level packages. - -package unix - -import ( - "sync" -) - -// files is the table indexed by a file descriptor. -var files struct { - sync.RWMutex - tab []*file -} - -// A file is an open file, something with a file descriptor. -// A particular *file may appear in files multiple times, due to use of Dup or Dup2. -type file struct { - fdref int // uses in files.tab - impl fileImpl // underlying implementation -} - -// A fileImpl is the implementation of something that can be a file. -type fileImpl interface { - // Standard operations. - // These can be called concurrently from multiple goroutines. - stat(*Stat_t) error - read([]byte) (int, error) - write([]byte) (int, error) - seek(int64, int) (int64, error) - pread([]byte, int64) (int, error) - pwrite([]byte, int64) (int, error) - - // Close is called when the last reference to a *file is removed - // from the file descriptor table. It may be called concurrently - // with active operations such as blocked read or write calls. - close() error -} - -// newFD adds impl to the file descriptor table, -// returning the new file descriptor. -// Like Unix, it uses the lowest available descriptor. -func newFD(impl fileImpl) int { - files.Lock() - defer files.Unlock() - f := &file{impl: impl, fdref: 1} - for fd, oldf := range files.tab { - if oldf == nil { - files.tab[fd] = f - return fd - } - } - fd := len(files.tab) - files.tab = append(files.tab, f) - return fd -} - -// Install Native Client stdin, stdout, stderr. -func init() { - newFD(&naclFile{naclFD: 0}) - newFD(&naclFile{naclFD: 1}) - newFD(&naclFile{naclFD: 2}) -} - -// fdToFile retrieves the *file corresponding to a file descriptor. -func fdToFile(fd int) (*file, error) { - files.Lock() - defer files.Unlock() - if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil { - return nil, EBADF - } - return files.tab[fd], nil -} - -func Close(fd int) error { - files.Lock() - if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil { - files.Unlock() - return EBADF - } - f := files.tab[fd] - files.tab[fd] = nil - f.fdref-- - fdref := f.fdref - files.Unlock() - if fdref > 0 { - return nil - } - return f.impl.close() -} - -func CloseOnExec(fd int) { - // nothing to do - no exec -} - -func Dup(fd int) (int, error) { - files.Lock() - defer files.Unlock() - if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil { - return -1, EBADF - } - f := files.tab[fd] - f.fdref++ - for newfd, oldf := range files.tab { - if oldf == nil { - files.tab[newfd] = f - return newfd, nil - } - } - newfd := len(files.tab) - files.tab = append(files.tab, f) - return newfd, nil -} - -func Dup2(fd, newfd int) error { - files.Lock() - defer files.Unlock() - if fd < 0 || fd >= len(files.tab) || files.tab[fd] == nil || newfd < 0 || newfd >= len(files.tab)+100 { - files.Unlock() - return EBADF - } - f := files.tab[fd] - f.fdref++ - for cap(files.tab) <= newfd { - files.tab = append(files.tab[:cap(files.tab)], nil) - } - oldf := files.tab[newfd] - var oldfdref int - if oldf != nil { - oldf.fdref-- - oldfdref = oldf.fdref - } - files.tab[newfd] = f - files.Unlock() - if oldf != nil { - if oldfdref == 0 { - oldf.impl.close() - } - } - return nil -} - -func Fstat(fd int, st *Stat_t) error { - f, err := fdToFile(fd) - if err != nil { - return err - } - return f.impl.stat(st) -} - -func Read(fd int, b []byte) (int, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - return f.impl.read(b) -} - -var zerobuf [0]byte - -func Write(fd int, b []byte) (int, error) { - if b == nil { - // avoid nil in syscalls; nacl doesn't like that. - b = zerobuf[:] - } - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - return f.impl.write(b) -} - -func Pread(fd int, b []byte, offset int64) (int, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - return f.impl.pread(b, offset) -} - -func Pwrite(fd int, b []byte, offset int64) (int, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - return f.impl.pwrite(b, offset) -} - -func Seek(fd int, offset int64, whence int) (int64, error) { - f, err := fdToFile(fd) - if err != nil { - return 0, err - } - return f.impl.seek(offset, whence) -} - -// defaulFileImpl implements fileImpl. -// It can be embedded to complete a partial fileImpl implementation. -type defaultFileImpl struct{} - -func (*defaultFileImpl) close() error { return nil } -func (*defaultFileImpl) stat(*Stat_t) error { return ENOSYS } -func (*defaultFileImpl) read([]byte) (int, error) { return 0, ENOSYS } -func (*defaultFileImpl) write([]byte) (int, error) { return 0, ENOSYS } -func (*defaultFileImpl) seek(int64, int) (int64, error) { return 0, ENOSYS } -func (*defaultFileImpl) pread([]byte, int64) (int, error) { return 0, ENOSYS } -func (*defaultFileImpl) pwrite([]byte, int64) (int, error) { return 0, ENOSYS } - -// naclFile is the fileImpl implementation for a Native Client file descriptor. -type naclFile struct { - defaultFileImpl - naclFD int -} - -func (f *naclFile) stat(st *Stat_t) error { - return naclFstat(f.naclFD, st) -} - -func (f *naclFile) read(b []byte) (int, error) { - n, err := naclRead(f.naclFD, b) - if err != nil { - n = 0 - } - return n, err -} - -// implemented in package runtime, to add time header on playground -func naclWrite(fd int, b []byte) int - -func (f *naclFile) write(b []byte) (int, error) { - n := naclWrite(f.naclFD, b) - if n < 0 { - return 0, Errno(-n) - } - return n, nil -} - -func (f *naclFile) seek(off int64, whence int) (int64, error) { - old := off - err := naclSeek(f.naclFD, &off, whence) - if err != nil { - return old, err - } - return off, nil -} - -func (f *naclFile) prw(b []byte, offset int64, rw func([]byte) (int, error)) (int, error) { - // NaCl has no pread; simulate with seek and hope for no races. - old, err := f.seek(0, 1) - if err != nil { - return 0, err - } - if _, err := f.seek(offset, 0); err != nil { - return 0, err - } - n, err := rw(b) - f.seek(old, 0) - return n, err -} - -func (f *naclFile) pread(b []byte, offset int64) (int, error) { - return f.prw(b, offset, f.read) -} - -func (f *naclFile) pwrite(b []byte, offset int64) (int, error) { - return f.prw(b, offset, f.write) -} - -func (f *naclFile) close() error { - err := naclClose(f.naclFD) - f.naclFD = -1 - return err -} - -// A pipeFile is an in-memory implementation of a pipe. -// The byteq implementation is in net_nacl.go. -type pipeFile struct { - defaultFileImpl - rd *byteq - wr *byteq -} - -func (f *pipeFile) close() error { - if f.rd != nil { - f.rd.close() - } - if f.wr != nil { - f.wr.close() - } - return nil -} - -func (f *pipeFile) read(b []byte) (int, error) { - if f.rd == nil { - return 0, EINVAL - } - n, err := f.rd.read(b, 0) - if err == EAGAIN { - err = nil - } - return n, err -} - -func (f *pipeFile) write(b []byte) (int, error) { - if f.wr == nil { - return 0, EINVAL - } - n, err := f.wr.write(b, 0) - if err == EAGAIN { - err = EPIPE - } - return n, err -} - -func Pipe(fd []int) error { - q := newByteq() - fd[0] = newFD(&pipeFile{rd: q}) - fd[1] = newFD(&pipeFile{wr: q}) - return nil -} diff --git a/unix/fs_nacl.go b/unix/fs_nacl.go deleted file mode 100644 index e675b229..00000000 --- a/unix/fs_nacl.go +++ /dev/null @@ -1,832 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// A simulated Unix-like file system for use within NaCl. -// -// The simulation is not particularly tied to NaCl other than the reuse -// of NaCl's definition for the Stat_t structure. -// -// The file system need never be written to disk, so it is represented as -// in-memory Go data structures, never in a serialized form. -// -// TODO: Perhaps support symlinks, although they muck everything up. - -package unix - -import ( - "sync" - "unsafe" -) - -// Provided by package runtime. -func now() (sec int64, nsec int32) - -// An fsys is a file system. -// Since there is no I/O (everything is in memory), -// the global lock mu protects the whole file system state, -// and that's okay. -type fsys struct { - mu sync.Mutex - root *inode // root directory - cwd *inode // process current directory - inum uint64 // number of inodes created - dev []func() (devFile, error) // table for opening devices -} - -// A devFile is the implementation required of device files -// like /dev/null or /dev/random. -type devFile interface { - pread([]byte, int64) (int, error) - pwrite([]byte, int64) (int, error) -} - -// An inode is a (possibly special) file in the file system. -type inode struct { - Stat_t - data []byte - dir []dirent -} - -// A dirent describes a single directory entry. -type dirent struct { - name string - inode *inode -} - -// An fsysFile is the fileImpl implementation backed by the file system. -type fsysFile struct { - defaultFileImpl - fsys *fsys - inode *inode - openmode int - offset int64 - dev devFile -} - -// newFsys creates a new file system. -func newFsys() *fsys { - fs := &fsys{} - fs.mu.Lock() - defer fs.mu.Unlock() - ip := fs.newInode() - ip.Mode = 0555 | S_IFDIR - fs.dirlink(ip, ".", ip) - fs.dirlink(ip, "..", ip) - fs.cwd = ip - fs.root = ip - return fs -} - -var fs = newFsys() -var fsinit = func() {} - -func init() { - // do not trigger loading of zipped file system here - oldFsinit := fsinit - defer func() { fsinit = oldFsinit }() - fsinit = func() {} - Mkdir("/dev", 0555) - Mkdir("/tmp", 0777) - mkdev("/dev/null", 0666, openNull) - mkdev("/dev/random", 0444, openRandom) - mkdev("/dev/urandom", 0444, openRandom) - mkdev("/dev/zero", 0666, openZero) - chdirEnv() -} - -func chdirEnv() { - pwd, ok := Getenv("NACLPWD") - if ok { - chdir(pwd) - } -} - -// Except where indicated otherwise, unexported methods on fsys -// expect fs.mu to have been locked by the caller. - -// newInode creates a new inode. -func (fs *fsys) newInode() *inode { - fs.inum++ - ip := &inode{ - Stat_t: Stat_t{ - Ino: fs.inum, - Blksize: 512, - }, - } - return ip -} - -// atime sets ip.Atime to the current time. -func (fs *fsys) atime(ip *inode) { - sec, nsec := now() - ip.Atime, ip.AtimeNsec = sec, int64(nsec) -} - -// mtime sets ip.Mtime to the current time. -func (fs *fsys) mtime(ip *inode) { - sec, nsec := now() - ip.Mtime, ip.MtimeNsec = sec, int64(nsec) -} - -// dirlookup looks for an entry in the directory dp with the given name. -// It returns the directory entry and its index within the directory. -func (fs *fsys) dirlookup(dp *inode, name string) (de *dirent, index int, err error) { - fs.atime(dp) - for i := range dp.dir { - de := &dp.dir[i] - if de.name == name { - fs.atime(de.inode) - return de, i, nil - } - } - return nil, 0, ENOENT -} - -// dirlink adds to the directory dp an entry for name pointing at the inode ip. -// If dp already contains an entry for name, that entry is overwritten. -func (fs *fsys) dirlink(dp *inode, name string, ip *inode) { - fs.mtime(dp) - fs.atime(ip) - ip.Nlink++ - for i := range dp.dir { - if dp.dir[i].name == name { - dp.dir[i] = dirent{name, ip} - return - } - } - dp.dir = append(dp.dir, dirent{name, ip}) - dp.dirSize() -} - -func (dp *inode) dirSize() { - dp.Size = int64(len(dp.dir)) * (8 + 8 + 2 + 256) // Dirent -} - -// skipelem splits path into the first element and the remainder. -// the returned first element contains no slashes, and the returned -// remainder does not begin with a slash. -func skipelem(path string) (elem, rest string) { - for len(path) > 0 && path[0] == '/' { - path = path[1:] - } - if len(path) == 0 { - return "", "" - } - i := 0 - for i < len(path) && path[i] != '/' { - i++ - } - elem, path = path[:i], path[i:] - for len(path) > 0 && path[0] == '/' { - path = path[1:] - } - return elem, path -} - -// namei translates a file system path name into an inode. -// If parent is false, the returned ip corresponds to the given name, and elem is the empty string. -// If parent is true, the walk stops at the next-to-last element in the name, -// so that ip is the parent directory and elem is the final element in the path. -func (fs *fsys) namei(path string, parent bool) (ip *inode, elem string, err error) { - // Reject NUL in name. - for i := 0; i < len(path); i++ { - if path[i] == '\x00' { - return nil, "", EINVAL - } - } - - // Reject empty name. - if path == "" { - return nil, "", EINVAL - } - - if path[0] == '/' { - ip = fs.root - } else { - ip = fs.cwd - } - - for len(path) > 0 && path[len(path)-1] == '/' { - path = path[:len(path)-1] - } - - for { - elem, rest := skipelem(path) - if elem == "" { - if parent && ip.Mode&S_IFMT == S_IFDIR { - return ip, ".", nil - } - break - } - if ip.Mode&S_IFMT != S_IFDIR { - return nil, "", ENOTDIR - } - if len(elem) >= 256 { - return nil, "", ENAMETOOLONG - } - if parent && rest == "" { - // Stop one level early. - return ip, elem, nil - } - de, _, err := fs.dirlookup(ip, elem) - if err != nil { - return nil, "", err - } - ip = de.inode - path = rest - } - if parent { - return nil, "", ENOTDIR - } - return ip, "", nil -} - -// open opens or creates a file with the given name, open mode, -// and permission mode bits. -func (fs *fsys) open(name string, openmode int, mode uint32) (fileImpl, error) { - dp, elem, err := fs.namei(name, true) - if err != nil { - return nil, err - } - var ( - ip *inode - dev devFile - ) - de, _, err := fs.dirlookup(dp, elem) - if err != nil { - if openmode&O_CREATE == 0 { - return nil, err - } - ip = fs.newInode() - ip.Mode = mode - fs.dirlink(dp, elem, ip) - if ip.Mode&S_IFMT == S_IFDIR { - fs.dirlink(ip, ".", ip) - fs.dirlink(ip, "..", dp) - } - } else { - ip = de.inode - if openmode&(O_CREATE|O_EXCL) == O_CREATE|O_EXCL { - return nil, EEXIST - } - if openmode&O_TRUNC != 0 { - if ip.Mode&S_IFMT == S_IFDIR { - return nil, EISDIR - } - ip.data = nil - } - if ip.Mode&S_IFMT == S_IFCHR { - if ip.Rdev < 0 || ip.Rdev >= int64(len(fs.dev)) || fs.dev[ip.Rdev] == nil { - return nil, ENODEV - } - dev, err = fs.dev[ip.Rdev]() - if err != nil { - return nil, err - } - } - } - - switch openmode & O_ACCMODE { - case O_WRONLY, O_RDWR: - if ip.Mode&S_IFMT == S_IFDIR { - return nil, EISDIR - } - } - - switch ip.Mode & S_IFMT { - case S_IFDIR: - if openmode&O_ACCMODE != O_RDONLY { - return nil, EISDIR - } - - case S_IFREG: - // ok - - case S_IFCHR: - // handled above - - default: - // TODO: some kind of special file - return nil, EPERM - } - - f := &fsysFile{ - fsys: fs, - inode: ip, - openmode: openmode, - dev: dev, - } - if openmode&O_APPEND != 0 { - f.offset = ip.Size - } - return f, nil -} - -// fsysFile methods to implement fileImpl. - -func (f *fsysFile) stat(st *Stat_t) error { - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - *st = f.inode.Stat_t - return nil -} - -func (f *fsysFile) read(b []byte) (int, error) { - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - n, err := f.preadLocked(b, f.offset) - f.offset += int64(n) - return n, err -} - -func ReadDirent(fd int, buf []byte) (int, error) { - f, err := fdToFsysFile(fd) - if err != nil { - return 0, err - } - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - if f.inode.Mode&S_IFMT != S_IFDIR { - return 0, EINVAL - } - n, err := f.preadLocked(buf, f.offset) - f.offset += int64(n) - return n, err -} - -func (f *fsysFile) write(b []byte) (int, error) { - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - n, err := f.pwriteLocked(b, f.offset) - f.offset += int64(n) - return n, err -} - -func (f *fsysFile) seek(offset int64, whence int) (int64, error) { - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - switch whence { - case 1: - offset += f.offset - case 2: - offset += f.inode.Size - } - if offset < 0 { - return 0, EINVAL - } - if offset > f.inode.Size { - return 0, EINVAL - } - f.offset = offset - return offset, nil -} - -func (f *fsysFile) pread(b []byte, offset int64) (int, error) { - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - return f.preadLocked(b, offset) -} - -func (f *fsysFile) pwrite(b []byte, offset int64) (int, error) { - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - return f.pwriteLocked(b, offset) -} - -func (f *fsysFile) preadLocked(b []byte, offset int64) (int, error) { - if f.openmode&O_ACCMODE == O_WRONLY { - return 0, EINVAL - } - if offset < 0 { - return 0, EINVAL - } - if f.dev != nil { - f.fsys.atime(f.inode) - f.fsys.mu.Unlock() - defer f.fsys.mu.Lock() - return f.dev.pread(b, offset) - } - if offset > f.inode.Size { - return 0, nil - } - if int64(len(b)) > f.inode.Size-offset { - b = b[:f.inode.Size-offset] - } - - if f.inode.Mode&S_IFMT == S_IFDIR { - if offset%direntSize != 0 || len(b) != 0 && len(b) < direntSize { - return 0, EINVAL - } - fs.atime(f.inode) - n := 0 - for len(b) >= direntSize { - src := f.inode.dir[int(offset/direntSize)] - dst := (*Dirent)(unsafe.Pointer(&b[0])) - dst.Ino = int64(src.inode.Ino) - dst.Off = offset - dst.Reclen = direntSize - for i := range dst.Name { - dst.Name[i] = 0 - } - copy(dst.Name[:], src.name) - n += direntSize - offset += direntSize - b = b[direntSize:] - } - return n, nil - } - - fs.atime(f.inode) - n := copy(b, f.inode.data[offset:]) - return n, nil -} - -func (f *fsysFile) pwriteLocked(b []byte, offset int64) (int, error) { - if f.openmode&O_ACCMODE == O_RDONLY { - return 0, EINVAL - } - if offset < 0 { - return 0, EINVAL - } - if f.dev != nil { - f.fsys.atime(f.inode) - f.fsys.mu.Unlock() - defer f.fsys.mu.Lock() - return f.dev.pwrite(b, offset) - } - if offset > f.inode.Size { - return 0, EINVAL - } - f.fsys.mtime(f.inode) - n := copy(f.inode.data[offset:], b) - if n < len(b) { - f.inode.data = append(f.inode.data, b[n:]...) - f.inode.Size = int64(len(f.inode.data)) - } - return len(b), nil -} - -// Standard Unix system calls. - -func Open(path string, openmode int, perm uint32) (fd int, err error) { - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - f, err := fs.open(path, openmode, perm&0777|S_IFREG) - if err != nil { - return -1, err - } - return newFD(f), nil -} - -func Mkdir(path string, perm uint32) error { - fs.mu.Lock() - defer fs.mu.Unlock() - _, err := fs.open(path, O_CREATE|O_EXCL, perm&0777|S_IFDIR) - return err -} - -func Getcwd(buf []byte) (n int, err error) { - // Force package os to default to the old algorithm using .. and directory reads. - return 0, ENOSYS -} - -func Stat(path string, st *Stat_t) error { - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - *st = ip.Stat_t - return nil -} - -func Lstat(path string, st *Stat_t) error { - return Stat(path, st) -} - -func unlink(path string, isdir bool) error { - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - dp, elem, err := fs.namei(path, true) - if err != nil { - return err - } - if elem == "." || elem == ".." { - return EINVAL - } - de, _, err := fs.dirlookup(dp, elem) - if err != nil { - return err - } - if isdir { - if de.inode.Mode&S_IFMT != S_IFDIR { - return ENOTDIR - } - if len(de.inode.dir) != 2 { - return ENOTEMPTY - } - } else { - if de.inode.Mode&S_IFMT == S_IFDIR { - return EISDIR - } - } - de.inode.Nlink-- - *de = dp.dir[len(dp.dir)-1] - dp.dir = dp.dir[:len(dp.dir)-1] - dp.dirSize() - return nil -} - -func Unlink(path string) error { - return unlink(path, false) -} - -func Rmdir(path string) error { - return unlink(path, true) -} - -func Chmod(path string, mode uint32) error { - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - ip.Mode = ip.Mode&^0777 | mode&0777 - return nil -} - -func Fchmod(fd int, mode uint32) error { - f, err := fdToFsysFile(fd) - if err != nil { - return err - } - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - f.inode.Mode = f.inode.Mode&^0777 | mode&0777 - return nil -} - -func Chown(path string, uid, gid int) error { - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - ip.Uid = uint32(uid) - ip.Gid = uint32(gid) - return nil -} - -func Fchown(fd int, uid, gid int) error { - fs.mu.Lock() - defer fs.mu.Unlock() - f, err := fdToFsysFile(fd) - if err != nil { - return err - } - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - f.inode.Uid = uint32(uid) - f.inode.Gid = uint32(gid) - return nil -} - -func Lchown(path string, uid, gid int) error { - return Chown(path, uid, gid) -} - -func UtimesNano(path string, ts []Timespec) error { - if len(ts) != 2 { - return EINVAL - } - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - ip.Atime = ts[0].Sec - ip.AtimeNsec = int64(ts[0].Nsec) - ip.Mtime = ts[1].Sec - ip.MtimeNsec = int64(ts[1].Nsec) - return nil -} - -func Link(path, link string) error { - fsinit() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - dp, elem, err := fs.namei(link, true) - if err != nil { - return err - } - if ip.Mode&S_IFMT == S_IFDIR { - return EPERM - } - fs.dirlink(dp, elem, ip) - return nil -} - -func Rename(from, to string) error { - fsinit() - fdp, felem, err := fs.namei(from, true) - if err != nil { - return err - } - fde, _, err := fs.dirlookup(fdp, felem) - if err != nil { - return err - } - tdp, telem, err := fs.namei(to, true) - if err != nil { - return err - } - fs.dirlink(tdp, telem, fde.inode) - fde.inode.Nlink-- - *fde = fdp.dir[len(fdp.dir)-1] - fdp.dir = fdp.dir[:len(fdp.dir)-1] - fdp.dirSize() - return nil -} - -func (fs *fsys) truncate(ip *inode, length int64) error { - if length > 1e9 || ip.Mode&S_IFMT != S_IFREG { - return EINVAL - } - if length < int64(len(ip.data)) { - ip.data = ip.data[:length] - } else { - data := make([]byte, length) - copy(data, ip.data) - ip.data = data - } - ip.Size = int64(len(ip.data)) - return nil -} - -func Truncate(path string, length int64) error { - fsinit() - fs.mu.Lock() - defer fs.mu.Unlock() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - return fs.truncate(ip, length) -} - -func Ftruncate(fd int, length int64) error { - f, err := fdToFsysFile(fd) - if err != nil { - return err - } - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - return f.fsys.truncate(f.inode, length) -} - -func Chdir(path string) error { - fsinit() - return chdir(path) -} - -func chdir(path string) error { - fs.mu.Lock() - defer fs.mu.Unlock() - ip, _, err := fs.namei(path, false) - if err != nil { - return err - } - fs.cwd = ip - return nil -} - -func Fchdir(fd int) error { - f, err := fdToFsysFile(fd) - if err != nil { - return err - } - f.fsys.mu.Lock() - defer f.fsys.mu.Unlock() - if f.inode.Mode&S_IFMT != S_IFDIR { - return ENOTDIR - } - fs.cwd = f.inode - return nil -} - -func Readlink(path string, buf []byte) (n int, err error) { - return 0, ENOSYS -} - -func Symlink(path, link string) error { - return ENOSYS -} - -func Fsync(fd int) error { - return nil -} - -// Special devices. - -func mkdev(path string, mode uint32, open func() (devFile, error)) error { - f, err := fs.open(path, O_CREATE|O_RDONLY|O_EXCL, S_IFCHR|mode) - if err != nil { - return err - } - ip := f.(*fsysFile).inode - ip.Rdev = int64(len(fs.dev)) - fs.dev = append(fs.dev, open) - return nil -} - -type nullFile struct{} - -func openNull() (devFile, error) { return &nullFile{}, nil } -func (f *nullFile) close() error { return nil } -func (f *nullFile) pread(b []byte, offset int64) (int, error) { return 0, nil } -func (f *nullFile) pwrite(b []byte, offset int64) (int, error) { return len(b), nil } - -type zeroFile struct{} - -func openZero() (devFile, error) { return &zeroFile{}, nil } -func (f *zeroFile) close() error { return nil } -func (f *zeroFile) pwrite(b []byte, offset int64) (int, error) { return len(b), nil } - -func (f *zeroFile) pread(b []byte, offset int64) (int, error) { - for i := range b { - b[i] = 0 - } - return len(b), nil -} - -type randomFile struct { - naclFD int -} - -func openRandom() (devFile, error) { - fd, err := openNamedService("SecureRandom", O_RDONLY) - if err != nil { - return nil, err - } - return &randomFile{naclFD: fd}, nil -} - -func (f *randomFile) close() error { - naclClose(f.naclFD) - f.naclFD = -1 - return nil -} - -func (f *randomFile) pread(b []byte, offset int64) (int, error) { - return naclRead(f.naclFD, b) -} - -func (f *randomFile) pwrite(b []byte, offset int64) (int, error) { - return 0, EPERM -} - -func fdToFsysFile(fd int) (*fsysFile, error) { - f, err := fdToFile(fd) - if err != nil { - return nil, err - } - impl := f.impl - fsysf, ok := impl.(*fsysFile) - if !ok { - return nil, EINVAL - } - return fsysf, nil -} - -// create creates a file in the file system with the given name, mode, time, and data. -// It is meant to be called when initializing the file system image. -func create(name string, mode uint32, sec int64, data []byte) error { - fs.mu.Lock() - fs.mu.Unlock() - f, err := fs.open(name, O_CREATE|O_EXCL, mode) - if err != nil { - return err - } - ip := f.(*fsysFile).inode - ip.Atime = sec - ip.Mtime = sec - ip.Ctime = sec - if len(data) > 0 { - ip.Size = int64(len(data)) - ip.data = data - } - return nil -} diff --git a/unix/mkall.sh b/unix/mkall.sh index d890a8e8..5fb4166a 100755 --- a/unix/mkall.sh +++ b/unix/mkall.sh @@ -176,18 +176,6 @@ linux_arm) mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl" mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; -nacl_386) - mkerrors="" - mksyscall="./mksyscall.pl -l32 -nacl" - mksysnum="" - mktypes="" - ;; -nacl_amd64p32) - mkerrors="" - mksyscall="./mksyscall.pl -nacl" - mksysnum="" - mktypes="" - ;; netbsd_386) mkerrors="$mkerrors -m32" mksyscall="./mksyscall.pl -l32 -netbsd" diff --git a/unix/mksyscall.pl b/unix/mksyscall.pl index 3095bc8f..48e20630 100755 --- a/unix/mksyscall.pl +++ b/unix/mksyscall.pl @@ -28,7 +28,6 @@ my $plan9 = 0; my $openbsd = 0; my $netbsd = 0; my $dragonfly = 0; -my $nacl = 0; my $arm = 0; # 64-bit value should use (even, odd)-pair if($ARGV[0] eq "-b32") { @@ -54,10 +53,6 @@ if($ARGV[0] eq "-dragonfly") { $dragonfly = 1; shift; } -if($ARGV[0] eq "-nacl") { - $nacl = 1; - shift; -} if($ARGV[0] eq "-arm") { $arm = 1; shift; @@ -224,9 +219,6 @@ while(<>) { $sysname = "SYS_$func"; $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar $sysname =~ y/a-z/A-Z/; - if($nacl) { - $sysname =~ y/A-Z/a-z/; - } } # Actual call. diff --git a/unix/net_nacl.go b/unix/net_nacl.go deleted file mode 100644 index 1498c111..00000000 --- a/unix/net_nacl.go +++ /dev/null @@ -1,912 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// A simulated network for use within NaCl. -// The simulation is not particularly tied to NaCl, -// but other systems have real networks. - -package unix - -import ( - "sync" - "sync/atomic" -) - -// Interface to timers implemented in package runtime. -// Must be in sync with ../runtime/runtime.h:/^struct.Timer$ -// Really for use by package time, but we cannot import time here. - -type runtimeTimer struct { - i int32 - when int64 - period int64 - f func(int64, interface{}) // NOTE: must not be closure - arg interface{} -} - -func startTimer(*runtimeTimer) -func stopTimer(*runtimeTimer) bool - -type timer struct { - expired bool - q *queue - r runtimeTimer -} - -func (t *timer) start(q *queue, deadline int64) { - if deadline == 0 { - return - } - t.q = q - t.r.when = deadline - t.r.f = timerExpired - t.r.arg = t - startTimer(&t.r) -} - -func (t *timer) stop() { - stopTimer(&t.r) -} - -func timerExpired(now int64, i interface{}) { - t := i.(*timer) - go func() { - t.q.Lock() - defer t.q.Unlock() - t.expired = true - t.q.canRead.Broadcast() - t.q.canWrite.Broadcast() - }() -} - -// Network constants and data structures. These match the traditional values. - -const ( - AF_UNSPEC = iota - AF_UNIX - AF_INET - AF_INET6 -) - -const ( - SHUT_RD = iota - SHUT_WR - SHUT_RDWR -) - -const ( - SOCK_STREAM = 1 + iota - SOCK_DGRAM - SOCK_RAW - SOCK_SEQPACKET -) - -const ( - IPPROTO_IP = 0 - IPPROTO_IPV4 = 4 - IPPROTO_IPV6 = 0x29 - IPPROTO_TCP = 6 - IPPROTO_UDP = 0x11 -) - -// Misc constants expected by package net but not supported. -const ( - _ = iota - SOL_SOCKET - SO_TYPE - NET_RT_IFLIST - IFNAMSIZ - IFF_UP - IFF_BROADCAST - IFF_LOOPBACK - IFF_POINTOPOINT - IFF_MULTICAST - IPV6_V6ONLY - SOMAXCONN - F_DUPFD_CLOEXEC - SO_BROADCAST - SO_REUSEADDR - SO_REUSEPORT - SO_RCVBUF - SO_SNDBUF - SO_KEEPALIVE - SO_LINGER - SO_ERROR - IP_PORTRANGE - IP_PORTRANGE_DEFAULT - IP_PORTRANGE_LOW - IP_PORTRANGE_HIGH - IP_MULTICAST_IF - IP_MULTICAST_LOOP - IP_ADD_MEMBERSHIP - IPV6_PORTRANGE - IPV6_PORTRANGE_DEFAULT - IPV6_PORTRANGE_LOW - IPV6_PORTRANGE_HIGH - IPV6_MULTICAST_IF - IPV6_MULTICAST_LOOP - IPV6_JOIN_GROUP - TCP_NODELAY - TCP_KEEPINTVL - TCP_KEEPIDLE - - SYS_FCNTL = 500 // unsupported -) - -var SocketDisableIPv6 bool - -// A Sockaddr is one of the SockaddrXxx structs. -type Sockaddr interface { - // copy returns a copy of the underlying data. - copy() Sockaddr - - // key returns the value of the underlying data, - // for comparison as a map key. - key() interface{} -} - -type SockaddrInet4 struct { - Port int - Addr [4]byte -} - -func (sa *SockaddrInet4) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrInet4) key() interface{} { return *sa } - -type SockaddrInet6 struct { - Port int - ZoneId uint32 - Addr [16]byte -} - -func (sa *SockaddrInet6) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrInet6) key() interface{} { return *sa } - -type SockaddrUnix struct { - Name string -} - -func (sa *SockaddrUnix) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrUnix) key() interface{} { return *sa } - -type SockaddrDatalink struct { - Len uint8 - Family uint8 - Index uint16 - Type uint8 - Nlen uint8 - Alen uint8 - Slen uint8 - Data [12]int8 -} - -func (sa *SockaddrDatalink) copy() Sockaddr { - sa1 := *sa - return &sa1 -} - -func (sa *SockaddrDatalink) key() interface{} { return *sa } - -// RoutingMessage represents a routing message. -type RoutingMessage interface { - unimplemented() -} - -type IPMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type IPv6Mreq struct { - Multiaddr [16]byte /* in6_addr */ - Interface uint32 -} - -type Linger struct { - Onoff int32 - Linger int32 -} - -type ICMPv6Filter struct { - Filt [8]uint32 -} - -// A queue is the bookkeeping for a synchronized buffered queue. -// We do not use channels because we need to be able to handle -// writes after and during close, and because a chan byte would -// require too many send and receive operations in real use. -type queue struct { - sync.Mutex - canRead sync.Cond - canWrite sync.Cond - r int // total read index - w int // total write index - m int // index mask - closed bool -} - -func (q *queue) init(size int) { - if size&(size-1) != 0 { - panic("invalid queue size - must be power of two") - } - q.canRead.L = &q.Mutex - q.canWrite.L = &q.Mutex - q.m = size - 1 -} - -func past(deadline int64) bool { - sec, nsec := now() - return deadline > 0 && deadline < sec*1e9+int64(nsec) -} - -func (q *queue) waitRead(n int, deadline int64) (int, error) { - if past(deadline) { - return 0, EAGAIN - } - var t timer - t.start(q, deadline) - for q.w-q.r == 0 && !q.closed && !t.expired { - q.canRead.Wait() - } - t.stop() - m := q.w - q.r - if m == 0 && t.expired { - return 0, EAGAIN - } - if m > n { - m = n - q.canRead.Signal() // wake up next reader too - } - q.canWrite.Signal() - return m, nil -} - -func (q *queue) waitWrite(n int, deadline int64) (int, error) { - if past(deadline) { - return 0, EAGAIN - } - var t timer - t.start(q, deadline) - for q.w-q.r > q.m && !q.closed && !t.expired { - q.canWrite.Wait() - } - t.stop() - m := q.m + 1 - (q.w - q.r) - if m == 0 && t.expired { - return 0, EAGAIN - } - if m == 0 { - return 0, EAGAIN - } - if m > n { - m = n - q.canWrite.Signal() // wake up next writer too - } - q.canRead.Signal() - return m, nil -} - -func (q *queue) close() { - q.Lock() - defer q.Unlock() - q.closed = true - q.canRead.Broadcast() - q.canWrite.Broadcast() -} - -// A byteq is a byte queue. -type byteq struct { - queue - data []byte -} - -func newByteq() *byteq { - q := &byteq{ - data: make([]byte, 4096), - } - q.init(len(q.data)) - return q -} - -func (q *byteq) read(b []byte, deadline int64) (int, error) { - q.Lock() - defer q.Unlock() - n, err := q.waitRead(len(b), deadline) - if err != nil { - return 0, err - } - b = b[:n] - for len(b) > 0 { - m := copy(b, q.data[q.r&q.m:]) - q.r += m - b = b[m:] - } - return n, nil -} - -func (q *byteq) write(b []byte, deadline int64) (n int, err error) { - q.Lock() - defer q.Unlock() - for n < len(b) { - nn, err := q.waitWrite(len(b[n:]), deadline) - if err != nil { - return n, err - } - bb := b[n : n+nn] - n += nn - for len(bb) > 0 { - m := copy(q.data[q.w&q.m:], bb) - q.w += m - bb = bb[m:] - } - } - return n, nil -} - -// A msgq is a queue of messages. -type msgq struct { - queue - data []interface{} -} - -func newMsgq() *msgq { - q := &msgq{ - data: make([]interface{}, 32), - } - q.init(len(q.data)) - return q -} - -func (q *msgq) read(deadline int64) (interface{}, error) { - q.Lock() - defer q.Unlock() - n, err := q.waitRead(1, deadline) - if err != nil { - return nil, err - } - if n == 0 { - return nil, nil - } - m := q.data[q.r&q.m] - q.r++ - return m, nil -} - -func (q *msgq) write(m interface{}, deadline int64) error { - q.Lock() - defer q.Unlock() - _, err := q.waitWrite(1, deadline) - if err != nil { - return err - } - q.data[q.w&q.m] = m - q.w++ - return nil -} - -// An addr is a sequence of bytes uniquely identifying a network address. -// It is not human-readable. -type addr string - -// A conn is one side of a stream-based network connection. -// That is, a stream-based network connection is a pair of cross-connected conns. -type conn struct { - rd *byteq - wr *byteq - local addr - remote addr -} - -// A pktconn is one side of a packet-based network connection. -// That is, a packet-based network connection is a pair of cross-connected pktconns. -type pktconn struct { - rd *msgq - wr *msgq - local addr - remote addr -} - -// A listener accepts incoming stream-based network connections. -type listener struct { - rd *msgq - local addr -} - -// A netFile is an open network file. -type netFile struct { - defaultFileImpl - proto *netproto - sotype int - listener *msgq - packet *msgq - rd *byteq - wr *byteq - rddeadline int64 - wrdeadline int64 - addr Sockaddr - raddr Sockaddr -} - -// A netAddr is a network address in the global listener map. -// All the fields must have defined == operations. -type netAddr struct { - proto *netproto - sotype int - addr interface{} -} - -// net records the state of the network. -// It maps a network address to the listener on that address. -var net = struct { - sync.Mutex - listener map[netAddr]*netFile -}{ - listener: make(map[netAddr]*netFile), -} - -// TODO(rsc): Some day, do a better job with port allocation. -// For playground programs, incrementing is fine. -var nextport = 2 - -// A netproto contains protocol-specific functionality -// (one for AF_INET, one for AF_INET6 and so on). -// It is a struct instead of an interface because the -// implementation needs no state, and I expect to -// add some data fields at some point. -type netproto struct { - bind func(*netFile, Sockaddr) error -} - -var netprotoAF_INET = &netproto{ - bind: func(f *netFile, sa Sockaddr) error { - if sa == nil { - f.addr = &SockaddrInet4{ - Port: nextport, - Addr: [4]byte{127, 0, 0, 1}, - } - nextport++ - return nil - } - addr, ok := sa.(*SockaddrInet4) - if !ok { - return EINVAL - } - addr = addr.copy().(*SockaddrInet4) - if addr.Port == 0 { - addr.Port = nextport - nextport++ - } - f.addr = addr - return nil - }, -} - -var netprotos = map[int]*netproto{ - AF_INET: netprotoAF_INET, -} - -// These functions implement the usual BSD socket operations. - -func (f *netFile) bind(sa Sockaddr) error { - if f.addr != nil { - return EISCONN - } - if err := f.proto.bind(f, sa); err != nil { - return err - } - if f.sotype == SOCK_DGRAM { - _, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] - if ok { - f.addr = nil - return EADDRINUSE - } - net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f - f.packet = newMsgq() - } - return nil -} - -func (f *netFile) listen(backlog int) error { - net.Lock() - defer net.Unlock() - if f.listener != nil { - return EINVAL - } - _, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] - if ok { - return EADDRINUSE - } - net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f - f.listener = newMsgq() - return nil -} - -func (f *netFile) accept() (fd int, sa Sockaddr, err error) { - msg, err := f.listener.read(f.readDeadline()) - if err != nil { - return -1, nil, err - } - newf, ok := msg.(*netFile) - if !ok { - // must be eof - return -1, nil, EAGAIN - } - return newFD(newf), newf.raddr.copy(), nil -} - -func (f *netFile) connect(sa Sockaddr) error { - if past(f.writeDeadline()) { - return EAGAIN - } - if f.addr == nil { - if err := f.bind(nil); err != nil { - return err - } - } - net.Lock() - if sa == nil { - net.Unlock() - return EINVAL - } - sa = sa.copy() - if f.raddr != nil { - net.Unlock() - return EISCONN - } - if f.sotype == SOCK_DGRAM { - net.Unlock() - f.raddr = sa - return nil - } - if f.listener != nil { - net.Unlock() - return EISCONN - } - l, ok := net.listener[netAddr{f.proto, f.sotype, sa.key()}] - if !ok { - net.Unlock() - return ECONNREFUSED - } - f.raddr = sa - f.rd = newByteq() - f.wr = newByteq() - newf := &netFile{ - proto: f.proto, - sotype: f.sotype, - addr: f.raddr, - raddr: f.addr, - rd: f.wr, - wr: f.rd, - } - net.Unlock() - l.listener.write(newf, f.writeDeadline()) - return nil -} - -func (f *netFile) read(b []byte) (int, error) { - if f.rd == nil { - if f.raddr != nil { - n, _, err := f.recvfrom(b, 0) - return n, err - } - return 0, ENOTCONN - } - return f.rd.read(b, f.readDeadline()) -} - -func (f *netFile) write(b []byte) (int, error) { - if f.wr == nil { - if f.raddr != nil { - err := f.sendto(b, 0, f.raddr) - var n int - if err == nil { - n = len(b) - } - return n, err - } - return 0, ENOTCONN - } - return f.wr.write(b, f.writeDeadline()) -} - -type pktmsg struct { - buf []byte - addr Sockaddr -} - -func (f *netFile) recvfrom(p []byte, flags int) (n int, from Sockaddr, err error) { - if f.sotype != SOCK_DGRAM { - return 0, nil, EINVAL - } - if f.packet == nil { - return 0, nil, ENOTCONN - } - msg1, err := f.packet.read(f.readDeadline()) - if err != nil { - return 0, nil, err - } - msg, ok := msg1.(*pktmsg) - if !ok { - return 0, nil, EAGAIN - } - return copy(p, msg.buf), msg.addr, nil -} - -func (f *netFile) sendto(p []byte, flags int, to Sockaddr) error { - if f.sotype != SOCK_DGRAM { - return EINVAL - } - if f.packet == nil { - if err := f.bind(nil); err != nil { - return err - } - } - net.Lock() - if to == nil { - net.Unlock() - return EINVAL - } - to = to.copy() - l, ok := net.listener[netAddr{f.proto, f.sotype, to.key()}] - if !ok || l.packet == nil { - net.Unlock() - return ECONNREFUSED - } - net.Unlock() - msg := &pktmsg{ - buf: make([]byte, len(p)), - addr: f.addr, - } - copy(msg.buf, p) - l.packet.write(msg, f.writeDeadline()) - return nil -} - -func (f *netFile) close() error { - if f.listener != nil { - f.listener.close() - } - if f.packet != nil { - f.packet.close() - } - if f.rd != nil { - f.rd.close() - } - if f.wr != nil { - f.wr.close() - } - return nil -} - -func fdToNetFile(fd int) (*netFile, error) { - f, err := fdToFile(fd) - if err != nil { - return nil, err - } - impl := f.impl - netf, ok := impl.(*netFile) - if !ok { - return nil, EINVAL - } - return netf, nil -} - -func Socket(proto, sotype, unused int) (fd int, err error) { - p := netprotos[proto] - if p == nil { - return -1, EPROTONOSUPPORT - } - if sotype != SOCK_STREAM && sotype != SOCK_DGRAM { - return -1, ESOCKTNOSUPPORT - } - f := &netFile{ - proto: p, - sotype: sotype, - } - return newFD(f), nil -} - -func Bind(fd int, sa Sockaddr) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.bind(sa) -} - -func StopIO(fd int) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - f.close() - return nil -} - -func Listen(fd int, backlog int) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.listen(backlog) -} - -func Accept(fd int) (newfd int, sa Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, nil, err - } - return f.accept() -} - -func Getsockname(fd int) (sa Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return nil, err - } - if f.addr == nil { - return nil, ENOTCONN - } - return f.addr.copy(), nil -} - -func Getpeername(fd int) (sa Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return nil, err - } - if f.raddr == nil { - return nil, ENOTCONN - } - return f.raddr.copy(), nil -} - -func Connect(fd int, sa Sockaddr) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.connect(sa) -} - -func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, nil, err - } - return f.recvfrom(p, flags) -} - -func Sendto(fd int, p []byte, flags int, to Sockaddr) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - return f.sendto(p, flags, to) -} - -func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return - } - n, from, err = f.recvfrom(p, flags) - return -} - -func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) error { - _, err := SendmsgN(fd, p, oob, to, flags) - return err -} - -func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, err - } - switch f.sotype { - case SOCK_STREAM: - n, err = f.write(p) - case SOCK_DGRAM: - n = len(p) - err = f.sendto(p, flags, to) - } - if err != nil { - return 0, err - } - return n, nil -} - -func GetsockoptInt(fd, level, opt int) (value int, err error) { - f, err := fdToNetFile(fd) - if err != nil { - return 0, err - } - switch { - case level == SOL_SOCKET && opt == SO_TYPE: - return f.sotype, nil - } - return 0, ENOTSUP -} - -func SetsockoptInt(fd, level, opt int, value int) error { - return nil -} - -func SetsockoptByte(fd, level, opt int, value byte) error { - _, err := fdToNetFile(fd) - if err != nil { - return err - } - return ENOTSUP -} - -func SetsockoptLinger(fd, level, opt int, l *Linger) error { - return nil -} - -func SetReadDeadline(fd int, t int64) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - atomic.StoreInt64(&f.rddeadline, t) - return nil -} - -func (f *netFile) readDeadline() int64 { - return atomic.LoadInt64(&f.rddeadline) -} - -func SetWriteDeadline(fd int, t int64) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - atomic.StoreInt64(&f.wrdeadline, t) - return nil -} - -func (f *netFile) writeDeadline() int64 { - return atomic.LoadInt64(&f.wrdeadline) -} - -func Shutdown(fd int, how int) error { - f, err := fdToNetFile(fd) - if err != nil { - return err - } - switch how { - case SHUT_RD: - f.rd.close() - case SHUT_WR: - f.wr.close() - case SHUT_RDWR: - f.rd.close() - f.wr.close() - } - return nil -} - -func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { panic("SetsockoptICMPv") } -func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) error { panic("SetsockoptIPMreq") } -func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) error { panic("SetsockoptIPv") } -func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) error { panic("SetsockoptInet") } -func SetsockoptString(fd, level, opt int, s string) error { panic("SetsockoptString") } -func SetsockoptTimeval(fd, level, opt int, tv *Timeval) error { panic("SetsockoptTimeval") } -func Socketpair(domain, typ, proto int) (fd [2]int, err error) { panic("Socketpair") } - -func SetNonblock(fd int, nonblocking bool) error { return nil } diff --git a/unix/srpc_nacl.go b/unix/srpc_nacl.go deleted file mode 100644 index d289415b..00000000 --- a/unix/srpc_nacl.go +++ /dev/null @@ -1,822 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Native Client SRPC message passing. -// This code is needed to invoke SecureRandom, the NaCl equivalent of /dev/random. - -package unix - -import ( - "errors" - "sync" - "unsafe" -) - -// An srpcClient represents the client side of an SRPC connection. -type srpcClient struct { - fd int // to server - r msgReceiver - s msgSender - service map[string]srpcService // services by name - - outMu sync.Mutex // protects writing to connection - - mu sync.Mutex // protects following fields - muxer bool // is someone reading and muxing responses - pending map[uint32]*srpc - idGen uint32 // generator for request IDs -} - -// An srpcService is a single method that the server offers. -type srpcService struct { - num uint32 // method number - fmt string // argument format; see "parsing of RPC messages" below -} - -// An srpc represents a single srpc issued by a client. -type srpc struct { - Ret []interface{} - Done chan *srpc - Err error - c *srpcClient - id uint32 -} - -// newClient allocates a new SRPC client using the file descriptor fd. -func newClient(fd int) (*srpcClient, error) { - c := new(srpcClient) - c.fd = fd - c.r.fd = fd - c.s.fd = fd - c.service = make(map[string]srpcService) - c.pending = make(map[uint32]*srpc) - - // service discovery request - m := &msg{ - isRequest: 1, - template: []interface{}{[]byte(nil)}, - size: []int{4000}, // max size to accept for returned byte slice - } - if err := m.pack(); err != nil { - return nil, errors.New("Native Client SRPC service_discovery: preparing request: " + err.Error()) - } - c.s.send(m) - m, err := c.r.recv() - if err != nil { - return nil, err - } - m.unpack() - if m.status != uint32(srpcOK) { - return nil, errors.New("Native Client SRPC service_discovery: " + srpcErrno(m.status).Error()) - } - list := m.value[0].([]byte) - var n uint32 - for len(list) > 0 { - var line []byte - i := byteIndex(list, '\n') - if i < 0 { - line, list = list, nil - } else { - line, list = list[:i], list[i+1:] - } - i = byteIndex(line, ':') - if i >= 0 { - c.service[string(line)] = srpcService{n, string(line[i+1:])} - } - n++ - } - - return c, nil -} - -func byteIndex(b []byte, c byte) int { - for i, bi := range b { - if bi == c { - return i - } - } - return -1 -} - -var yourTurn srpc - -func (c *srpcClient) wait(r *srpc) { - var rx *srpc - for rx = range r.Done { - if rx != &yourTurn { - break - } - c.input() - } - return -} - -func (c *srpcClient) input() { - // read message - m, err := c.r.recv() - if err != nil { - println("Native Client SRPC receive error:", err.Error()) - return - } - if m.unpack(); m.status != uint32(srpcOK) { - println("Native Client SRPC receive error: invalid message: ", srpcErrno(m.status).Error()) - return - } - - // deliver to intended recipient - c.mu.Lock() - rpc, ok := c.pending[m.id] - if ok { - delete(c.pending, m.id) - } - - // wake a new muxer if there are more RPCs to read - c.muxer = false - for _, rpc := range c.pending { - c.muxer = true - rpc.Done <- &yourTurn - break - } - c.mu.Unlock() - if !ok { - println("Native Client: unexpected response for ID", m.id) - return - } - rpc.Ret = m.value - rpc.Done <- rpc -} - -// Wait blocks until the RPC has finished. -func (r *srpc) Wait() { - r.c.wait(r) -} - -// Start issues an RPC request for method name with the given arguments. -// The RPC r must not be in use for another pending request. -// To wait for the RPC to finish, receive from r.Done and then -// inspect r.Ret and r.Errno. -func (r *srpc) Start(name string, arg []interface{}) { - r.Err = nil - r.c.mu.Lock() - srv, ok := r.c.service[name] - if !ok { - r.c.mu.Unlock() - r.Err = srpcErrBadRPCNumber - r.Done <- r - return - } - r.c.pending[r.id] = r - if !r.c.muxer { - r.c.muxer = true - r.Done <- &yourTurn - } - r.c.mu.Unlock() - - var m msg - m.id = r.id - m.isRequest = 1 - m.rpc = srv.num - m.value = arg - - // Fill in the return values and sizes to generate - // the right type chars. We'll take most any size. - - // Skip over input arguments. - // We could check them against arg, but the server - // will do that anyway. - i := 0 - for srv.fmt[i] != ':' { - i++ - } - format := srv.fmt[i+1:] - - // Now the return prototypes. - m.template = make([]interface{}, len(format)) - m.size = make([]int, len(format)) - for i := 0; i < len(format); i++ { - switch format[i] { - default: - println("Native Client SRPC: unexpected service type " + string(format[i])) - r.Err = srpcErrBadRPCNumber - r.Done <- r - return - case 'b': - m.template[i] = false - case 'C': - m.template[i] = []byte(nil) - m.size[i] = 1 << 30 - case 'd': - m.template[i] = float64(0) - case 'D': - m.template[i] = []float64(nil) - m.size[i] = 1 << 30 - case 'h': - m.template[i] = int(-1) - case 'i': - m.template[i] = int32(0) - case 'I': - m.template[i] = []int32(nil) - m.size[i] = 1 << 30 - case 's': - m.template[i] = "" - m.size[i] = 1 << 30 - } - } - - if err := m.pack(); err != nil { - r.Err = errors.New("Native Client RPC Start " + name + ": preparing request: " + err.Error()) - r.Done <- r - return - } - - r.c.outMu.Lock() - r.c.s.send(&m) - r.c.outMu.Unlock() -} - -// Call is a convenience wrapper that starts the RPC request, -// waits for it to finish, and then returns the results. -// Its implementation is: -// -// r.Start(name, arg) -// r.Wait() -// return r.Ret, r.Errno -// -func (c *srpcClient) Call(name string, arg ...interface{}) (ret []interface{}, err error) { - r := c.NewRPC(nil) - r.Start(name, arg) - r.Wait() - return r.Ret, r.Err -} - -// NewRPC creates a new RPC on the client connection. -func (c *srpcClient) NewRPC(done chan *srpc) *srpc { - if done == nil { - done = make(chan *srpc, 1) - } - c.mu.Lock() - id := c.idGen - c.idGen++ - c.mu.Unlock() - return &srpc{Done: done, c: c, id: id} -} - -// The current protocol number. -// Kind of useless, since there have been backwards-incompatible changes -// to the wire protocol that did not update the protocol number. -// At this point it's really just a sanity check. -const protocol = 0xc0da0002 - -// An srpcErrno is an SRPC status code. -type srpcErrno uint32 - -const ( - srpcOK srpcErrno = 256 + iota - srpcErrBreak - srpcErrMessageTruncated - srpcErrNoMemory - srpcErrProtocolMismatch - srpcErrBadRPCNumber - srpcErrBadArgType - srpcErrTooFewArgs - srpcErrTooManyArgs - srpcErrInArgTypeMismatch - srpcErrOutArgTypeMismatch - srpcErrInternalError - srpcErrAppError -) - -var srpcErrstr = [...]string{ - srpcOK - srpcOK: "ok", - srpcErrBreak - srpcOK: "break", - srpcErrMessageTruncated - srpcOK: "message truncated", - srpcErrNoMemory - srpcOK: "out of memory", - srpcErrProtocolMismatch - srpcOK: "protocol mismatch", - srpcErrBadRPCNumber - srpcOK: "invalid RPC method number", - srpcErrBadArgType - srpcOK: "unexpected argument type", - srpcErrTooFewArgs - srpcOK: "too few arguments", - srpcErrTooManyArgs - srpcOK: "too many arguments", - srpcErrInArgTypeMismatch - srpcOK: "input argument type mismatch", - srpcErrOutArgTypeMismatch - srpcOK: "output argument type mismatch", - srpcErrInternalError - srpcOK: "internal error", - srpcErrAppError - srpcOK: "application error", -} - -func (e srpcErrno) Error() string { - if e < srpcOK || int(e-srpcOK) >= len(srpcErrstr) { - return "srpcErrno(" + itoa(int(e)) + ")" - } - return srpcErrstr[e-srpcOK] -} - -// A msgHdr is the data argument to the imc_recvmsg -// and imc_sendmsg system calls. -type msgHdr struct { - iov *iov - niov int32 - desc *int32 - ndesc int32 - flags uint32 -} - -// A single region for I/O. -type iov struct { - base *byte - len int32 -} - -const maxMsgSize = 1<<16 - 4*4 - -// A msgReceiver receives messages from a file descriptor. -type msgReceiver struct { - fd int - data [maxMsgSize]byte - desc [8]int32 - hdr msgHdr - iov iov -} - -func (r *msgReceiver) recv() (*msg, error) { - // Init pointers to buffers where syscall recvmsg can write. - r.iov.base = &r.data[0] - r.iov.len = int32(len(r.data)) - r.hdr.iov = &r.iov - r.hdr.niov = 1 - r.hdr.desc = &r.desc[0] - r.hdr.ndesc = int32(len(r.desc)) - n, _, e := Syscall(sys_imc_recvmsg, uintptr(r.fd), uintptr(unsafe.Pointer(&r.hdr)), 0) - if e != 0 { - println("Native Client imc_recvmsg: ", e.Error()) - return nil, e - } - - // Make a copy of the data so that the next recvmsg doesn't - // smash it. The system call did not update r.iov.len. Instead it - // returned the total byte count as n. - m := new(msg) - m.data = make([]byte, n) - copy(m.data, r.data[0:]) - - // Make a copy of the desc too. - // The system call *did* update r.hdr.ndesc. - if r.hdr.ndesc > 0 { - m.desc = make([]int32, r.hdr.ndesc) - copy(m.desc, r.desc[:]) - } - - return m, nil -} - -// A msgSender sends messages on a file descriptor. -type msgSender struct { - fd int - hdr msgHdr - iov iov -} - -func (s *msgSender) send(m *msg) error { - if len(m.data) > 0 { - s.iov.base = &m.data[0] - } - s.iov.len = int32(len(m.data)) - s.hdr.iov = &s.iov - s.hdr.niov = 1 - s.hdr.desc = nil - s.hdr.ndesc = 0 - _, _, e := Syscall(sys_imc_sendmsg, uintptr(s.fd), uintptr(unsafe.Pointer(&s.hdr)), 0) - if e != 0 { - println("Native Client imc_sendmsg: ", e.Error()) - return e - } - return nil -} - -// A msg is the Go representation of an SRPC message. -type msg struct { - data []byte // message data - desc []int32 // message file descriptors - - // parsed version of message - id uint32 - isRequest uint32 - rpc uint32 - status uint32 - value []interface{} - template []interface{} - size []int - format string - broken bool -} - -// reading from a msg - -func (m *msg) uint32() uint32 { - if m.broken { - return 0 - } - if len(m.data) < 4 { - m.broken = true - return 0 - } - b := m.data[:4] - x := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - m.data = m.data[4:] - return x -} - -func (m *msg) uint64() uint64 { - x := uint64(m.uint32()) | uint64(m.uint32())<<32 - if m.broken { - return 0 - } - return x -} - -func (m *msg) bytes(n int) []byte { - if m.broken { - return nil - } - if len(m.data) < n { - m.broken = true - return nil - } - x := m.data[0:n] - m.data = m.data[n:] - return x -} - -// writing to a msg - -func (m *msg) wuint32(x uint32) { - m.data = append(m.data, byte(x), byte(x>>8), byte(x>>16), byte(x>>24)) -} - -func (m *msg) wuint64(x uint64) { - lo := uint32(x) - hi := uint32(x >> 32) - m.data = append(m.data, byte(lo), byte(lo>>8), byte(lo>>16), byte(lo>>24), byte(hi), byte(hi>>8), byte(hi>>16), byte(hi>>24)) -} - -func (m *msg) wbytes(p []byte) { - m.data = append(m.data, p...) -} - -func (m *msg) wstring(s string) { - m.data = append(m.data, s...) -} - -// Parsing of RPC messages. -// -// Each message begins with -// total_size uint32 -// total_descs uint32 -// fragment_size uint32 -// fragment_descs uint32 -// -// If fragment_size < total_size or fragment_descs < total_descs, the actual -// message is broken up in multiple messages; follow-up messages omit -// the "total" fields and begin with the "fragment" fields. -// We do not support putting fragmented messages back together. -// To do this we would need to change the message receiver. -// -// After that size information, the message header follows: -// protocol uint32 -// requestID uint32 -// isRequest uint32 -// rpcNumber uint32 -// status uint32 -// numValue uint32 -// numTemplate uint32 -// -// After the header come numTemplate fixed-size arguments, -// numValue fixed-size arguments, and then the variable-sized -// part of the values. The templates describe the expected results -// and have no associated variable sized data in the request. -// -// Each fixed-size argument has the form: -// tag uint32 // really a char, like 'b' or 'C' -// pad uint32 // unused -// val1 uint32 -// val2 uint32 -// -// The tags are: -// 'b': bool; val1 == 0 or 1 -// 'C': []byte; val1 == len, data in variable-sized section -// 'd': float64; (val1, val2) is data -// 'D': []float64; val1 == len, data in variable-sized section -// 'h': int; val1 == file descriptor -// 'i': int32; descriptor in next entry in m.desc -// 'I': []int; val1 == len, data in variable-sized section -// 's': string; val1 == len, data in variable-sized section -// - -func (m *msg) pack() error { - m.data = m.data[:0] - m.desc = m.desc[:0] - - // sizes, to fill in later - m.wuint32(0) - m.wuint32(0) - m.wuint32(0) - m.wuint32(0) - - // message header - m.wuint32(protocol) - m.wuint32(m.id) - m.wuint32(m.isRequest) - m.wuint32(m.rpc) - m.wuint32(m.status) - m.wuint32(uint32(len(m.value))) - m.wuint32(uint32(len(m.template))) - - // fixed-size templates - for i, x := range m.template { - var tag, val1, val2 uint32 - switch x.(type) { - default: - return errors.New("unexpected template type") - case bool: - tag = 'b' - case []byte: - tag = 'C' - val1 = uint32(m.size[i]) - case float64: - tag = 'd' - case []float64: - tag = 'D' - val1 = uint32(m.size[i]) - case int: - tag = 'h' - case int32: - tag = 'i' - case []int32: - tag = 'I' - val1 = uint32(m.size[i]) - case string: - tag = 's' - val1 = uint32(m.size[i]) - } - m.wuint32(tag) - m.wuint32(0) - m.wuint32(val1) - m.wuint32(val2) - } - - // fixed-size values - for _, x := range m.value { - var tag, val1, val2 uint32 - switch x := x.(type) { - default: - return errors.New("unexpected value type") - case bool: - tag = 'b' - if x { - val1 = 1 - } - case []byte: - tag = 'C' - val1 = uint32(len(x)) - case float64: - tag = 'd' - v := float64bits(x) - val1 = uint32(v) - val2 = uint32(v >> 32) - case []float64: - tag = 'D' - val1 = uint32(len(x)) - case int32: - tag = 'i' - m.desc = append(m.desc, x) - case []int32: - tag = 'I' - val1 = uint32(len(x)) - case string: - tag = 's' - val1 = uint32(len(x) + 1) - } - m.wuint32(tag) - m.wuint32(0) - m.wuint32(val1) - m.wuint32(val2) - } - - // variable-length data for values - for _, x := range m.value { - switch x := x.(type) { - case []byte: - m.wbytes(x) - case []float64: - for _, f := range x { - m.wuint64(float64bits(f)) - } - case []int32: - for _, j := range x { - m.wuint32(uint32(j)) - } - case string: - m.wstring(x) - m.wstring("\x00") - } - } - - // fill in sizes - data := m.data - m.data = m.data[:0] - m.wuint32(uint32(len(data))) - m.wuint32(uint32(len(m.desc))) - m.wuint32(uint32(len(data))) - m.wuint32(uint32(len(m.desc))) - m.data = data - - return nil -} - -func (m *msg) unpack() error { - totalSize := m.uint32() - totalDesc := m.uint32() - fragSize := m.uint32() - fragDesc := m.uint32() - if totalSize != fragSize || totalDesc != fragDesc { - return errors.New("Native Client: fragmented RPC messages not supported") - } - if m.uint32() != protocol { - return errors.New("Native Client: RPC protocol mismatch") - } - - // message header - m.id = m.uint32() - m.isRequest = m.uint32() - m.rpc = m.uint32() - m.status = m.uint32() - m.value = make([]interface{}, m.uint32()) - m.template = make([]interface{}, m.uint32()) - m.size = make([]int, len(m.template)) - if m.broken { - return errors.New("Native Client: malformed message") - } - - // fixed-size templates - for i := range m.template { - tag := m.uint32() - m.uint32() // padding - val1 := m.uint32() - m.uint32() // val2 - switch tag { - default: - return errors.New("Native Client: unexpected template type " + string(rune(tag))) - case 'b': - m.template[i] = false - case 'C': - m.template[i] = []byte(nil) - m.size[i] = int(val1) - case 'd': - m.template[i] = float64(0) - case 'D': - m.template[i] = []float64(nil) - m.size[i] = int(val1) - case 'i': - m.template[i] = int32(0) - case 'I': - m.template[i] = []int32(nil) - m.size[i] = int(val1) - case 'h': - m.template[i] = int(0) - case 's': - m.template[i] = "" - m.size[i] = int(val1) - } - } - - // fixed-size values - var ( - strsize []uint32 - d int - ) - for i := range m.value { - tag := m.uint32() - m.uint32() // padding - val1 := m.uint32() - val2 := m.uint32() - switch tag { - default: - return errors.New("Native Client: unexpected value type " + string(rune(tag))) - case 'b': - m.value[i] = val1 > 0 - case 'C': - m.value[i] = []byte(nil) - strsize = append(strsize, val1) - case 'd': - m.value[i] = float64frombits(uint64(val1) | uint64(val2)<<32) - case 'D': - m.value[i] = make([]float64, val1) - case 'i': - m.value[i] = int32(val1) - case 'I': - m.value[i] = make([]int32, val1) - case 'h': - m.value[i] = int(m.desc[d]) - d++ - case 's': - m.value[i] = "" - strsize = append(strsize, val1) - } - } - - // variable-sized parts of values - for i, x := range m.value { - switch x := x.(type) { - case []byte: - m.value[i] = m.bytes(int(strsize[0])) - strsize = strsize[1:] - case []float64: - for i := range x { - x[i] = float64frombits(m.uint64()) - } - case []int32: - for i := range x { - x[i] = int32(m.uint32()) - } - case string: - m.value[i] = string(m.bytes(int(strsize[0]))) - strsize = strsize[1:] - } - } - - if len(m.data) > 0 { - return errors.New("Native Client: junk at end of message") - } - return nil -} - -func float64bits(x float64) uint64 { - return *(*uint64)(unsafe.Pointer(&x)) -} - -func float64frombits(x uint64) float64 { - return *(*float64)(unsafe.Pointer(&x)) -} - -// At startup, connect to the name service. -var nsClient = nsConnect() - -func nsConnect() *srpcClient { - var ns int32 = -1 - _, _, errno := Syscall(sys_nameservice, uintptr(unsafe.Pointer(&ns)), 0, 0) - if errno != 0 { - println("Native Client nameservice:", errno.Error()) - return nil - } - - sock, _, errno := Syscall(sys_imc_connect, uintptr(ns), 0, 0) - if errno != 0 { - println("Native Client nameservice connect:", errno.Error()) - return nil - } - - c, err := newClient(int(sock)) - if err != nil { - println("Native Client nameservice init:", err.Error()) - return nil - } - - return c -} - -const ( - nsSuccess = 0 - nsNameNotFound = 1 - nsDuplicateName = 2 - nsInsufficientResources = 3 - nsPermissionDenied = 4 - nsInvalidArgument = 5 -) - -func openNamedService(name string, mode int32) (fd int, err error) { - if nsClient == nil { - return 0, errors.New("no name service") - } - ret, err := nsClient.Call("lookup:si:ih", name, int32(mode)) - if err != nil { - return 0, err - } - status := ret[0].(int32) - fd = ret[1].(int) - switch status { - case nsSuccess: - // ok - case nsNameNotFound: - return -1, ENOENT - case nsDuplicateName: - return -1, EEXIST - case nsInsufficientResources: - return -1, EWOULDBLOCK - case nsPermissionDenied: - return -1, EPERM - case nsInvalidArgument: - return -1, EINVAL - default: - return -1, EINVAL - } - return fd, nil -} diff --git a/unix/syscall_nacl.go b/unix/syscall_nacl.go deleted file mode 100644 index d0abd068..00000000 --- a/unix/syscall_nacl.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -import ( - "sync" - "unsafe" -) - -//sys naclClose(fd int) (err error) = sys_close -//sys Exit(code int) (err error) -//sys naclFstat(fd int, stat *Stat_t) (err error) = sys_fstat -//sys naclRead(fd int, b []byte) (n int, err error) = sys_read -//sys naclSeek(fd int, off *int64, whence int) (err error) = sys_lseek - -const direntSize = 8 + 8 + 2 + 256 - -// native_client/src/trusted/service_runtime/include/sys/dirent.h -type Dirent struct { - Ino int64 - Off int64 - Reclen uint16 - Name [256]byte -} - -func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { - origlen := len(buf) - count = 0 - for max != 0 && len(buf) > 0 { - dirent := (*Dirent)(unsafe.Pointer(&buf[0])) - buf = buf[dirent.Reclen:] - if dirent.Ino == 0 { // File absent in directory. - continue - } - bytes := (*[512 + PathMax]byte)(unsafe.Pointer(&dirent.Name[0])) - var name = string(bytes[0:clen(bytes[:])]) - if name == "." || name == ".." { // Useless names - continue - } - max-- - count++ - names = append(names, name) - } - return origlen - len(buf), count, names -} - -func clen(n []byte) int { - for i := 0; i < len(n); i++ { - if n[i] == 0 { - return i - } - } - return len(n) -} - -const PathMax = 256 - -// An Errno is an unsigned number describing an error condition. -// It implements the error interface. The zero Errno is by convention -// a non-error, so code to convert from Errno to error should use: -// err = nil -// if errno != 0 { -// err = errno -// } -type Errno uintptr - -func (e Errno) Error() string { - if 0 <= int(e) && int(e) < len(errorstr) { - s := errorstr[e] - if s != "" { - return s - } - } - return "errno " + itoa(int(e)) -} - -func (e Errno) Temporary() bool { - return e == EINTR || e == EMFILE || e.Timeout() -} - -func (e Errno) Timeout() bool { - return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT -} - -// A Signal is a number describing a process signal. -// It implements the os.Signal interface. -type Signal int - -const ( - _ Signal = iota - SIGCHLD - SIGINT - SIGKILL - SIGTRAP - SIGQUIT -) - -func (s Signal) Signal() {} - -func (s Signal) String() string { - if 0 <= s && int(s) < len(signals) { - str := signals[s] - if str != "" { - return str - } - } - return "signal " + itoa(int(s)) -} - -var signals = [...]string{} - -// File system - -const ( - Stdin = 0 - Stdout = 1 - Stderr = 2 -) - -// native_client/src/trusted/service_runtime/include/sys/fcntl.h -const ( - O_RDONLY = 0 - O_WRONLY = 1 - O_RDWR = 2 - O_ACCMODE = 3 - - O_CREAT = 0100 - O_CREATE = O_CREAT // for ken - O_TRUNC = 01000 - O_APPEND = 02000 - O_EXCL = 0200 - O_NONBLOCK = 04000 - O_NDELAY = O_NONBLOCK - O_SYNC = 010000 - O_FSYNC = O_SYNC - O_ASYNC = 020000 - - O_CLOEXEC = 0 - - FD_CLOEXEC = 1 -) - -// native_client/src/trusted/service_runtime/include/sys/fcntl.h -const ( - F_DUPFD = 0 - F_GETFD = 1 - F_SETFD = 2 - F_GETFL = 3 - F_SETFL = 4 - F_GETOWN = 5 - F_SETOWN = 6 - F_GETLK = 7 - F_SETLK = 8 - F_SETLKW = 9 - F_RGETLK = 10 - F_RSETLK = 11 - F_CNVT = 12 - F_RSETLKW = 13 - - F_RDLCK = 1 - F_WRLCK = 2 - F_UNLCK = 3 - F_UNLKSYS = 4 -) - -// native_client/src/trusted/service_runtime/include/bits/stat.h -const ( - S_IFMT = 0000370000 - S_IFSHM_SYSV = 0000300000 - S_IFSEMA = 0000270000 - S_IFCOND = 0000260000 - S_IFMUTEX = 0000250000 - S_IFSHM = 0000240000 - S_IFBOUNDSOCK = 0000230000 - S_IFSOCKADDR = 0000220000 - S_IFDSOCK = 0000210000 - - S_IFSOCK = 0000140000 - S_IFLNK = 0000120000 - S_IFREG = 0000100000 - S_IFBLK = 0000060000 - S_IFDIR = 0000040000 - S_IFCHR = 0000020000 - S_IFIFO = 0000010000 - - S_UNSUP = 0000370000 - - S_ISUID = 0004000 - S_ISGID = 0002000 - S_ISVTX = 0001000 - - S_IREAD = 0400 - S_IWRITE = 0200 - S_IEXEC = 0100 - - S_IRWXU = 0700 - S_IRUSR = 0400 - S_IWUSR = 0200 - S_IXUSR = 0100 - - S_IRWXG = 070 - S_IRGRP = 040 - S_IWGRP = 020 - S_IXGRP = 010 - - S_IRWXO = 07 - S_IROTH = 04 - S_IWOTH = 02 - S_IXOTH = 01 -) - -// native_client/src/trusted/service_runtime/include/sys/stat.h -// native_client/src/trusted/service_runtime/include/machine/_types.h -type Stat_t struct { - Dev int64 - Ino uint64 - Mode uint32 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev int64 - Size int64 - Blksize int32 - Blocks int32 - Atime int64 - AtimeNsec int64 - Mtime int64 - MtimeNsec int64 - Ctime int64 - CtimeNsec int64 -} - -// Processes -// Not supported on NaCl - just enough for package os. - -var ForkLock sync.RWMutex - -type WaitStatus uint32 - -func (w WaitStatus) Exited() bool { return false } -func (w WaitStatus) ExitStatus() int { return 0 } -func (w WaitStatus) Signaled() bool { return false } -func (w WaitStatus) Signal() Signal { return 0 } -func (w WaitStatus) CoreDump() bool { return false } -func (w WaitStatus) Stopped() bool { return false } -func (w WaitStatus) Continued() bool { return false } -func (w WaitStatus) StopSignal() Signal { return 0 } -func (w WaitStatus) TrapCause() int { return 0 } - -// XXX made up -type Rusage struct { - Utime Timeval - Stime Timeval -} - -// XXX made up -type ProcAttr struct { - Dir string - Env []string - Files []uintptr - Sys *SysProcAttr -} - -type SysProcAttr struct { -} - -// System - -func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) -func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { return 0, 0, ENOSYS } -func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { return 0, 0, ENOSYS } -func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { - return 0, 0, ENOSYS -} - -func Sysctl(key string) (string, error) { - if key == "kern.hostname" { - return "naclbox", nil - } - return "", ENOSYS -} - -// Unimplemented Unix midden heap. - -const ImplementsGetwd = false - -func Getwd() (wd string, err error) { return "", ENOSYS } -func Getegid() int { return 1 } -func Geteuid() int { return 1 } -func Getgid() int { return 1 } -func Getgroups() ([]int, error) { return []int{1}, nil } -func Getpagesize() int { return 65536 } -func Getppid() int { return 2 } -func Getpid() int { return 3 } -func Getuid() int { return 1 } -func Kill(pid int, signum Signal) error { return ENOSYS } -func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { - return 0, ENOSYS -} -func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { - return 0, 0, ENOSYS -} -func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { - return 0, ENOSYS -} -func RouteRIB(facility, param int) ([]byte, error) { return nil, ENOSYS } -func ParseRoutingMessage(b []byte) ([]RoutingMessage, error) { return nil, ENOSYS } -func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { return nil, ENOSYS } -func SysctlUint32(name string) (value uint32, err error) { return 0, ENOSYS } diff --git a/unix/syscall_nacl_386.go b/unix/syscall_nacl_386.go deleted file mode 100644 index aa6314ab..00000000 --- a/unix/syscall_nacl_386.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -type Timespec struct { - Sec int64 - Nsec int32 -} - -type Timeval struct { - Sec int64 - Usec int32 -} - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return -} - -func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } - -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return -} diff --git a/unix/syscall_nacl_amd64p32.go b/unix/syscall_nacl_amd64p32.go deleted file mode 100644 index aa6314ab..00000000 --- a/unix/syscall_nacl_amd64p32.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -type Timespec struct { - Sec int64 - Nsec int32 -} - -type Timeval struct { - Sec int64 - Usec int32 -} - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return -} - -func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } - -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return -} diff --git a/unix/syscall_nacl_arm.go b/unix/syscall_nacl_arm.go deleted file mode 100644 index a54fbe1c..00000000 --- a/unix/syscall_nacl_arm.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -type Timespec struct { - Sec int64 - Nsec int32 -} - -type Timeval struct { - Sec int64 - Usec int32 -} - -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = int64(nsec / 1e9) - ts.Nsec = int32(nsec % 1e9) - return -} - -func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } - -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Usec = int32(nsec % 1e9 / 1e3) - tv.Sec = int64(nsec / 1e9) - return -} diff --git a/unix/tables_nacl.go b/unix/tables_nacl.go deleted file mode 100644 index deb409af..00000000 --- a/unix/tables_nacl.go +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -// TODO: generate with runtime/mknacl.sh, allow override with IRT. -const ( - sys_null = 1 - sys_nameservice = 2 - sys_dup = 8 - sys_dup2 = 9 - sys_open = 10 - sys_close = 11 - sys_read = 12 - sys_write = 13 - sys_lseek = 14 - sys_ioctl = 15 - sys_stat = 16 - sys_fstat = 17 - sys_chmod = 18 - sys_brk = 20 - sys_mmap = 21 - sys_munmap = 22 - sys_getdents = 23 - sys_mprotect = 24 - sys_list_mappings = 25 - sys_exit = 30 - sys_getpid = 31 - sys_sched_yield = 32 - sys_sysconf = 33 - sys_gettimeofday = 40 - sys_clock = 41 - sys_nanosleep = 42 - sys_clock_getres = 43 - sys_clock_gettime = 44 - sys_mkdir = 45 - sys_rmdir = 46 - sys_chdir = 47 - sys_getcwd = 48 - sys_unlink = 49 - sys_imc_makeboundsock = 60 - sys_imc_accept = 61 - sys_imc_connect = 62 - sys_imc_sendmsg = 63 - sys_imc_recvmsg = 64 - sys_imc_mem_obj_create = 65 - sys_imc_socketpair = 66 - sys_mutex_create = 70 - sys_mutex_lock = 71 - sys_mutex_trylock = 72 - sys_mutex_unlock = 73 - sys_cond_create = 74 - sys_cond_wait = 75 - sys_cond_signal = 76 - sys_cond_broadcast = 77 - sys_cond_timed_wait_abs = 79 - sys_thread_create = 80 - sys_thread_exit = 81 - sys_tls_init = 82 - sys_thread_nice = 83 - sys_tls_get = 84 - sys_second_tls_set = 85 - sys_second_tls_get = 86 - sys_exception_handler = 87 - sys_exception_stack = 88 - sys_exception_clear_flag = 89 - sys_sem_create = 100 - sys_sem_wait = 101 - sys_sem_post = 102 - sys_sem_get_value = 103 - sys_dyncode_create = 104 - sys_dyncode_modify = 105 - sys_dyncode_delete = 106 - sys_test_infoleak = 109 - sys_test_crash = 110 - sys_test_syscall_1 = 111 - sys_test_syscall_2 = 112 -) - -// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) -const ( - // native_client/src/trusted/service_runtime/include/sys/errno.h - // The errors are mainly copied from Linux. - EPERM Errno = 1 /* Operation not permitted */ - ENOENT Errno = 2 /* No such file or directory */ - ESRCH Errno = 3 /* No such process */ - EINTR Errno = 4 /* Interrupted system call */ - EIO Errno = 5 /* I/O error */ - ENXIO Errno = 6 /* No such device or address */ - E2BIG Errno = 7 /* Argument list too long */ - ENOEXEC Errno = 8 /* Exec format error */ - EBADF Errno = 9 /* Bad file number */ - ECHILD Errno = 10 /* No child processes */ - EAGAIN Errno = 11 /* Try again */ - ENOMEM Errno = 12 /* Out of memory */ - EACCES Errno = 13 /* Permission denied */ - EFAULT Errno = 14 /* Bad address */ - EBUSY Errno = 16 /* Device or resource busy */ - EEXIST Errno = 17 /* File exists */ - EXDEV Errno = 18 /* Cross-device link */ - ENODEV Errno = 19 /* No such device */ - ENOTDIR Errno = 20 /* Not a directory */ - EISDIR Errno = 21 /* Is a directory */ - EINVAL Errno = 22 /* Invalid argument */ - ENFILE Errno = 23 /* File table overflow */ - EMFILE Errno = 24 /* Too many open files */ - ENOTTY Errno = 25 /* Not a typewriter */ - EFBIG Errno = 27 /* File too large */ - ENOSPC Errno = 28 /* No space left on device */ - ESPIPE Errno = 29 /* Illegal seek */ - EROFS Errno = 30 /* Read-only file system */ - EMLINK Errno = 31 /* Too many links */ - EPIPE Errno = 32 /* Broken pipe */ - ENAMETOOLONG Errno = 36 /* File name too long */ - ENOSYS Errno = 38 /* Function not implemented */ - EDQUOT Errno = 122 /* Quota exceeded */ - EDOM Errno = 33 /* Math arg out of domain of func */ - ERANGE Errno = 34 /* Math result not representable */ - EDEADLK Errno = 35 /* Deadlock condition */ - ENOLCK Errno = 37 /* No record locks available */ - ENOTEMPTY Errno = 39 /* Directory not empty */ - ELOOP Errno = 40 /* Too many symbolic links */ - ENOMSG Errno = 42 /* No message of desired type */ - EIDRM Errno = 43 /* Identifier removed */ - ECHRNG Errno = 44 /* Channel number out of range */ - EL2NSYNC Errno = 45 /* Level 2 not synchronized */ - EL3HLT Errno = 46 /* Level 3 halted */ - EL3RST Errno = 47 /* Level 3 reset */ - ELNRNG Errno = 48 /* Link number out of range */ - EUNATCH Errno = 49 /* Protocol driver not attached */ - ENOCSI Errno = 50 /* No CSI structure available */ - EL2HLT Errno = 51 /* Level 2 halted */ - EBADE Errno = 52 /* Invalid exchange */ - EBADR Errno = 53 /* Invalid request descriptor */ - EXFULL Errno = 54 /* Exchange full */ - ENOANO Errno = 55 /* No anode */ - EBADRQC Errno = 56 /* Invalid request code */ - EBADSLT Errno = 57 /* Invalid slot */ - EDEADLOCK Errno = EDEADLK /* File locking deadlock error */ - EBFONT Errno = 59 /* Bad font file fmt */ - ENOSTR Errno = 60 /* Device not a stream */ - ENODATA Errno = 61 /* No data (for no delay io) */ - ETIME Errno = 62 /* Timer expired */ - ENOSR Errno = 63 /* Out of streams resources */ - ENONET Errno = 64 /* Machine is not on the network */ - ENOPKG Errno = 65 /* Package not installed */ - EREMOTE Errno = 66 /* The object is remote */ - ENOLINK Errno = 67 /* The link has been severed */ - EADV Errno = 68 /* Advertise error */ - ESRMNT Errno = 69 /* Srmount error */ - ECOMM Errno = 70 /* Communication error on send */ - EPROTO Errno = 71 /* Protocol error */ - EMULTIHOP Errno = 72 /* Multihop attempted */ - EDOTDOT Errno = 73 /* Cross mount point (not really error) */ - EBADMSG Errno = 74 /* Trying to read unreadable message */ - EOVERFLOW Errno = 75 /* Value too large for defined data type */ - ENOTUNIQ Errno = 76 /* Given log. name not unique */ - EBADFD Errno = 77 /* f.d. invalid for this operation */ - EREMCHG Errno = 78 /* Remote address changed */ - ELIBACC Errno = 79 /* Can't access a needed shared lib */ - ELIBBAD Errno = 80 /* Accessing a corrupted shared lib */ - ELIBSCN Errno = 81 /* .lib section in a.out corrupted */ - ELIBMAX Errno = 82 /* Attempting to link in too many libs */ - ELIBEXEC Errno = 83 /* Attempting to exec a shared library */ - EILSEQ Errno = 84 - EUSERS Errno = 87 - ENOTSOCK Errno = 88 /* Socket operation on non-socket */ - EDESTADDRREQ Errno = 89 /* Destination address required */ - EMSGSIZE Errno = 90 /* Message too long */ - EPROTOTYPE Errno = 91 /* Protocol wrong type for socket */ - ENOPROTOOPT Errno = 92 /* Protocol not available */ - EPROTONOSUPPORT Errno = 93 /* Unknown protocol */ - ESOCKTNOSUPPORT Errno = 94 /* Socket type not supported */ - EOPNOTSUPP Errno = 95 /* Operation not supported on transport endpoint */ - EPFNOSUPPORT Errno = 96 /* Protocol family not supported */ - EAFNOSUPPORT Errno = 97 /* Address family not supported by protocol family */ - EADDRINUSE Errno = 98 /* Address already in use */ - EADDRNOTAVAIL Errno = 99 /* Address not available */ - ENETDOWN Errno = 100 /* Network interface is not configured */ - ENETUNREACH Errno = 101 /* Network is unreachable */ - ENETRESET Errno = 102 - ECONNABORTED Errno = 103 /* Connection aborted */ - ECONNRESET Errno = 104 /* Connection reset by peer */ - ENOBUFS Errno = 105 /* No buffer space available */ - EISCONN Errno = 106 /* Socket is already connected */ - ENOTCONN Errno = 107 /* Socket is not connected */ - ESHUTDOWN Errno = 108 /* Can't send after socket shutdown */ - ETOOMANYREFS Errno = 109 - ETIMEDOUT Errno = 110 /* Connection timed out */ - ECONNREFUSED Errno = 111 /* Connection refused */ - EHOSTDOWN Errno = 112 /* Host is down */ - EHOSTUNREACH Errno = 113 /* Host is unreachable */ - EALREADY Errno = 114 /* Socket already connected */ - EINPROGRESS Errno = 115 /* Connection already in progress */ - ESTALE Errno = 116 - ENOTSUP Errno = EOPNOTSUPP /* Not supported */ - ENOMEDIUM Errno = 123 /* No medium (in tape drive) */ - ECANCELED Errno = 125 /* Operation canceled. */ - ELBIN Errno = 2048 /* Inode is remote (not really error) */ - EFTYPE Errno = 2049 /* Inappropriate file type or format */ - ENMFILE Errno = 2050 /* No more files */ - EPROCLIM Errno = 2051 - ENOSHARE Errno = 2052 /* No such host or network path */ - ECASECLASH Errno = 2053 /* Filename exists with different case */ - EWOULDBLOCK Errno = EAGAIN /* Operation would block */ -) - -// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) -var errorstr = [...]string{ - EPERM: "Operation not permitted", - ENOENT: "No such file or directory", - ESRCH: "No such process", - EINTR: "Interrupted system call", - EIO: "I/O error", - ENXIO: "No such device or address", - E2BIG: "Argument list too long", - ENOEXEC: "Exec format error", - EBADF: "Bad file number", - ECHILD: "No child processes", - EAGAIN: "Try again", - ENOMEM: "Out of memory", - EACCES: "Permission denied", - EFAULT: "Bad address", - EBUSY: "Device or resource busy", - EEXIST: "File exists", - EXDEV: "Cross-device link", - ENODEV: "No such device", - ENOTDIR: "Not a directory", - EISDIR: "Is a directory", - EINVAL: "Invalid argument", - ENFILE: "File table overflow", - EMFILE: "Too many open files", - ENOTTY: "Not a typewriter", - EFBIG: "File too large", - ENOSPC: "No space left on device", - ESPIPE: "Illegal seek", - EROFS: "Read-only file system", - EMLINK: "Too many links", - EPIPE: "Broken pipe", - ENAMETOOLONG: "File name too long", - ENOSYS: "not implemented on Native Client", - EDQUOT: "Quota exceeded", - EDOM: "Math arg out of domain of func", - ERANGE: "Math result not representable", - EDEADLK: "Deadlock condition", - ENOLCK: "No record locks available", - ENOTEMPTY: "Directory not empty", - ELOOP: "Too many symbolic links", - ENOMSG: "No message of desired type", - EIDRM: "Identifier removed", - ECHRNG: "Channel number out of range", - EL2NSYNC: "Level 2 not synchronized", - EL3HLT: "Level 3 halted", - EL3RST: "Level 3 reset", - ELNRNG: "Link number out of range", - EUNATCH: "Protocol driver not attached", - ENOCSI: "No CSI structure available", - EL2HLT: "Level 2 halted", - EBADE: "Invalid exchange", - EBADR: "Invalid request descriptor", - EXFULL: "Exchange full", - ENOANO: "No anode", - EBADRQC: "Invalid request code", - EBADSLT: "Invalid slot", - EBFONT: "Bad font file fmt", - ENOSTR: "Device not a stream", - ENODATA: "No data (for no delay io)", - ETIME: "Timer expired", - ENOSR: "Out of streams resources", - ENONET: "Machine is not on the network", - ENOPKG: "Package not installed", - EREMOTE: "The object is remote", - ENOLINK: "The link has been severed", - EADV: "Advertise error", - ESRMNT: "Srmount error", - ECOMM: "Communication error on send", - EPROTO: "Protocol error", - EMULTIHOP: "Multihop attempted", - EDOTDOT: "Cross mount point (not really error)", - EBADMSG: "Trying to read unreadable message", - EOVERFLOW: "Value too large for defined data type", - ENOTUNIQ: "Given log. name not unique", - EBADFD: "f.d. invalid for this operation", - EREMCHG: "Remote address changed", - ELIBACC: "Can't access a needed shared lib", - ELIBBAD: "Accessing a corrupted shared lib", - ELIBSCN: ".lib section in a.out corrupted", - ELIBMAX: "Attempting to link in too many libs", - ELIBEXEC: "Attempting to exec a shared library", - ENOTSOCK: "Socket operation on non-socket", - EDESTADDRREQ: "Destination address required", - EMSGSIZE: "Message too long", - EPROTOTYPE: "Protocol wrong type for socket", - ENOPROTOOPT: "Protocol not available", - EPROTONOSUPPORT: "Unknown protocol", - ESOCKTNOSUPPORT: "Socket type not supported", - EOPNOTSUPP: "Operation not supported on transport endpoint", - EPFNOSUPPORT: "Protocol family not supported", - EAFNOSUPPORT: "Address family not supported by protocol family", - EADDRINUSE: "Address already in use", - EADDRNOTAVAIL: "Address not available", - ENETDOWN: "Network interface is not configured", - ENETUNREACH: "Network is unreachable", - ECONNABORTED: "Connection aborted", - ECONNRESET: "Connection reset by peer", - ENOBUFS: "No buffer space available", - EISCONN: "Socket is already connected", - ENOTCONN: "Socket is not connected", - ESHUTDOWN: "Can't send after socket shutdown", - ETIMEDOUT: "Connection timed out", - ECONNREFUSED: "Connection refused", - EHOSTDOWN: "Host is down", - EHOSTUNREACH: "Host is unreachable", - EALREADY: "Socket already connected", - EINPROGRESS: "Connection already in progress", - ENOMEDIUM: "No medium (in tape drive)", - ECANCELED: "Operation canceled.", - ELBIN: "Inode is remote (not really error)", - EFTYPE: "Inappropriate file type or format", - ENMFILE: "No more files", - ENOSHARE: "No such host or network path", - ECASECLASH: "Filename exists with different case", -} diff --git a/unix/time_nacl_386.s b/unix/time_nacl_386.s deleted file mode 100644 index c0c89dcc..00000000 --- a/unix/time_nacl_386.s +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" - -TEXT ·startTimer(SB),NOSPLIT,$0 - JMP time·startTimer(SB) - -TEXT ·stopTimer(SB),NOSPLIT,$0 - JMP time·stopTimer(SB) diff --git a/unix/time_nacl_amd64p32.s b/unix/time_nacl_amd64p32.s deleted file mode 100644 index c0c89dcc..00000000 --- a/unix/time_nacl_amd64p32.s +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" - -TEXT ·startTimer(SB),NOSPLIT,$0 - JMP time·startTimer(SB) - -TEXT ·stopTimer(SB),NOSPLIT,$0 - JMP time·stopTimer(SB) diff --git a/unix/time_nacl_arm.s b/unix/time_nacl_arm.s deleted file mode 100644 index 4f4b4d89..00000000 --- a/unix/time_nacl_arm.s +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" - -TEXT ·startTimer(SB),NOSPLIT,$0 - B time·startTimer(SB) - -TEXT ·stopTimer(SB),NOSPLIT,$0 - B time·stopTimer(SB) diff --git a/unix/unzip_nacl.go b/unix/unzip_nacl.go deleted file mode 100644 index 22afb068..00000000 --- a/unix/unzip_nacl.go +++ /dev/null @@ -1,685 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Small in-memory unzip implementation. -// A simplified copy of the pre-Go 1 compress/flate/inflate.go -// and a modified copy of the zip reader in package time. -// (The one in package time does not support decompression; this one does.) - -package unix - -const ( - maxCodeLen = 16 // max length of Huffman code - maxHist = 32768 // max history required - maxLit = 286 - maxDist = 32 - numCodes = 19 // number of codes in Huffman meta-code -) - -type decompressor struct { - in string // compressed input - out []byte // uncompressed output - b uint32 // input bits, at top of b - nb uint - err bool // invalid input - eof bool // reached EOF - - h1, h2 huffmanDecoder // decoders for literal/length, distance - bits [maxLit + maxDist]int // lengths defining Huffman codes - codebits [numCodes]int -} - -func (f *decompressor) nextBlock() { - for f.nb < 1+2 { - if f.moreBits(); f.err { - return - } - } - f.eof = f.b&1 == 1 - f.b >>= 1 - typ := f.b & 3 - f.b >>= 2 - f.nb -= 1 + 2 - switch typ { - case 0: - f.dataBlock() - case 1: - // compressed, fixed Huffman tables - f.huffmanBlock(&fixedHuffmanDecoder, nil) - case 2: - // compressed, dynamic Huffman tables - if f.readHuffman(); f.err { - break - } - f.huffmanBlock(&f.h1, &f.h2) - default: - // 3 is reserved. - f.err = true - } -} - -// RFC 1951 section 3.2.7. -// Compression with dynamic Huffman codes - -var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15} - -func (f *decompressor) readHuffman() { - // HLIT[5], HDIST[5], HCLEN[4]. - for f.nb < 5+5+4 { - if f.moreBits(); f.err { - return - } - } - nlit := int(f.b&0x1F) + 257 - f.b >>= 5 - ndist := int(f.b&0x1F) + 1 - f.b >>= 5 - nclen := int(f.b&0xF) + 4 - f.b >>= 4 - f.nb -= 5 + 5 + 4 - - // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order. - for i := 0; i < nclen; i++ { - for f.nb < 3 { - if f.moreBits(); f.err { - return - } - } - f.codebits[codeOrder[i]] = int(f.b & 0x7) - f.b >>= 3 - f.nb -= 3 - } - for i := nclen; i < len(codeOrder); i++ { - f.codebits[codeOrder[i]] = 0 - } - if !f.h1.init(f.codebits[0:]) { - f.err = true - return - } - - // HLIT + 257 code lengths, HDIST + 1 code lengths, - // using the code length Huffman code. - for i, n := 0, nlit+ndist; i < n; { - x := f.huffSym(&f.h1) - if f.err { - return - } - if x < 16 { - // Actual length. - f.bits[i] = x - i++ - continue - } - // Repeat previous length or zero. - var rep int - var nb uint - var b int - switch x { - default: - f.err = true - return - case 16: - rep = 3 - nb = 2 - if i == 0 { - f.err = true - return - } - b = f.bits[i-1] - case 17: - rep = 3 - nb = 3 - b = 0 - case 18: - rep = 11 - nb = 7 - b = 0 - } - for f.nb < nb { - if f.moreBits(); f.err { - return - } - } - rep += int(f.b & uint32(1<>= nb - f.nb -= nb - if i+rep > n { - f.err = true - return - } - for j := 0; j < rep; j++ { - f.bits[i] = b - i++ - } - } - - if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) { - f.err = true - return - } -} - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) huffmanBlock(hl, hd *huffmanDecoder) { - for { - v := f.huffSym(hl) - if f.err { - return - } - var n uint // number of bits extra - var length int - switch { - case v < 256: - f.out = append(f.out, byte(v)) - continue - case v == 256: - // Done with huffman block; read next block. - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - default: - length = 258 - n = 0 - } - if n > 0 { - for f.nb < n { - if f.moreBits(); f.err { - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if hd == nil { - for f.nb < 5 { - if f.moreBits(); f.err { - return - } - } - dist = int(reverseByte[(f.b&0x1F)<<3]) - f.b >>= 5 - f.nb -= 5 - } else { - if dist = f.huffSym(hd); f.err { - return - } - } - - switch { - case dist < 4: - dist++ - case dist >= 30: - f.err = true - return - default: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if f.moreBits(); f.err { - return - } - } - extra |= int(f.b & uint32(1<>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - } - - // Copy [-dist:-dist+length] into output. - // Encoding can be prescient, so no check on length. - if dist > len(f.out) { - f.err = true - return - } - - p := len(f.out) - dist - for i := 0; i < length; i++ { - f.out = append(f.out, f.out[p]) - p++ - } - } -} - -// Copy a single uncompressed data block from input to output. -func (f *decompressor) dataBlock() { - // Uncompressed. - // Discard current half-byte. - f.nb = 0 - f.b = 0 - - if len(f.in) < 4 { - f.err = true - return - } - - buf := f.in[:4] - f.in = f.in[4:] - n := int(buf[0]) | int(buf[1])<<8 - nn := int(buf[2]) | int(buf[3])<<8 - if uint16(nn) != uint16(^n) { - f.err = true - return - } - - if len(f.in) < n { - f.err = true - return - } - f.out = append(f.out, f.in[:n]...) - f.in = f.in[n:] -} - -func (f *decompressor) moreBits() { - if len(f.in) == 0 { - f.err = true - return - } - c := f.in[0] - f.in = f.in[1:] - f.b |= uint32(c) << f.nb - f.nb += 8 -} - -// Read the next Huffman-encoded symbol from f according to h. -func (f *decompressor) huffSym(h *huffmanDecoder) int { - for n := uint(h.min); n <= uint(h.max); n++ { - lim := h.limit[n] - if lim == -1 { - continue - } - for f.nb < n { - if f.moreBits(); f.err { - return 0 - } - } - v := int(f.b & uint32(1<>8]) | int(reverseByte[v&0xFF])<<8 // reverse bits - if v <= lim { - f.b >>= n - f.nb -= n - return h.codes[v-h.base[n]] - } - } - f.err = true - return 0 -} - -var reverseByte = [256]byte{ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -} - -// Hard-coded Huffman tables for DEFLATE algorithm. -// See RFC 1951, section 3.2.6. -var fixedHuffmanDecoder = huffmanDecoder{ - 7, 9, - [maxCodeLen + 1]int{7: 23, 199, 511}, - [maxCodeLen + 1]int{7: 0, 24, 224}, - []int{ - // length 7: 256-279 - 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, - - // length 8: 0-143 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, - - // length 8: 280-287 - 280, 281, 282, 283, 284, 285, 286, 287, - - // length 9: 144-255 - 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, - }, -} - -// Huffman decoder is based on -// J. Brian Connell, ``A Huffman-Shannon-Fano Code,'' -// Proceedings of the IEEE, 61(7) (July 1973), pp 1046-1047. -type huffmanDecoder struct { - // min, max code length - min, max int - - // limit[i] = largest code word of length i - // Given code v of length n, - // need more bits if v > limit[n]. - limit [maxCodeLen + 1]int - - // base[i] = smallest code word of length i - seq number - base [maxCodeLen + 1]int - - // codes[seq number] = output code. - // Given code v of length n, value is - // codes[v - base[n]]. - codes []int -} - -// Initialize Huffman decoding tables from array of code lengths. -func (h *huffmanDecoder) init(bits []int) bool { - // Count number of codes of each length, - // compute min and max length. - var count [maxCodeLen + 1]int - var min, max int - for _, n := range bits { - if n == 0 { - continue - } - if min == 0 || n < min { - min = n - } - if n > max { - max = n - } - count[n]++ - } - if max == 0 { - return false - } - - h.min = min - h.max = max - - // For each code range, compute - // nextcode (first code of that length), - // limit (last code of that length), and - // base (offset from first code to sequence number). - code := 0 - seq := 0 - var nextcode [maxCodeLen]int - for i := min; i <= max; i++ { - n := count[i] - nextcode[i] = code - h.base[i] = code - seq - code += n - seq += n - h.limit[i] = code - 1 - code <<= 1 - } - - // Make array mapping sequence numbers to codes. - if len(h.codes) < len(bits) { - h.codes = make([]int, len(bits)) - } - for i, n := range bits { - if n == 0 { - continue - } - code := nextcode[n] - nextcode[n]++ - seq := code - h.base[n] - h.codes[seq] = i - } - return true -} - -func inflate(in string) (out []byte) { - var d decompressor - d.in = in - for !d.err && !d.eof { - d.nextBlock() - } - if len(d.in) != 0 { - println("fs unzip: junk at end of compressed data") - return nil - } - return d.out -} - -// get4 returns the little-endian 32-bit value in b. -func zget4(b string) int { - if len(b) < 4 { - return 0 - } - return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24 -} - -// get2 returns the little-endian 16-bit value in b. -func zget2(b string) int { - if len(b) < 2 { - return 0 - } - return int(b[0]) | int(b[1])<<8 -} - -func unzip(data string) { - const ( - zecheader = 0x06054b50 - zcheader = 0x02014b50 - ztailsize = 22 - zheadersize = 30 - zheader = 0x04034b50 - ) - - buf := data[len(data)-ztailsize:] - n := zget2(buf[10:]) - size := zget4(buf[12:]) - off := zget4(buf[16:]) - - hdr := data[off : off+size] - for i := 0; i < n; i++ { - // zip entry layout: - // 0 magic[4] - // 4 madevers[1] - // 5 madeos[1] - // 6 extvers[1] - // 7 extos[1] - // 8 flags[2] - // 10 meth[2] - // 12 modtime[2] - // 14 moddate[2] - // 16 crc[4] - // 20 csize[4] - // 24 uncsize[4] - // 28 namelen[2] - // 30 xlen[2] - // 32 fclen[2] - // 34 disknum[2] - // 36 iattr[2] - // 38 eattr[4] - // 42 off[4] - // 46 name[namelen] - // 46+namelen+xlen+fclen - next header - // - if zget4(hdr) != zcheader { - println("fs unzip: bad magic") - break - } - meth := zget2(hdr[10:]) - mtime := zget2(hdr[12:]) - mdate := zget2(hdr[14:]) - csize := zget4(hdr[20:]) - size := zget4(hdr[24:]) - namelen := zget2(hdr[28:]) - xlen := zget2(hdr[30:]) - fclen := zget2(hdr[32:]) - xattr := uint32(zget4(hdr[38:])) >> 16 - off := zget4(hdr[42:]) - name := hdr[46 : 46+namelen] - hdr = hdr[46+namelen+xlen+fclen:] - - // zip per-file header layout: - // 0 magic[4] - // 4 extvers[1] - // 5 extos[1] - // 6 flags[2] - // 8 meth[2] - // 10 modtime[2] - // 12 moddate[2] - // 14 crc[4] - // 18 csize[4] - // 22 uncsize[4] - // 26 namelen[2] - // 28 xlen[2] - // 30 name[namelen] - // 30+namelen+xlen - file data - // - buf := data[off : off+zheadersize+namelen] - if zget4(buf) != zheader || - zget2(buf[8:]) != meth || - zget2(buf[26:]) != namelen || - buf[30:30+namelen] != name { - println("fs unzip: inconsistent zip file") - return - } - xlen = zget2(buf[28:]) - - off += zheadersize + namelen + xlen - - var fdata []byte - switch meth { - case 0: - // buf is uncompressed - buf = data[off : off+size] - fdata = []byte(buf) - case 8: - // buf is deflate-compressed - buf = data[off : off+csize] - fdata = inflate(buf) - if len(fdata) != size { - println("fs unzip: inconsistent size in zip file") - return - } - } - - if xattr&S_IFMT == 0 { - if xattr&0777 == 0 { - xattr |= 0666 - } - if len(name) > 0 && name[len(name)-1] == '/' { - xattr |= S_IFDIR - xattr |= 0111 - } else { - xattr |= S_IFREG - } - } - - if err := create(name, xattr, zipToTime(mdate, mtime), fdata); err != nil { - print("fs unzip: create ", name, ": ", err.Error(), "\n") - } - } - - chdirEnv() -} - -func zipToTime(date, time int) int64 { - dd := date & 0x1f - mm := date >> 5 & 0xf - yy := date >> 9 // since 1980 - - sec := int64(315532800) // jan 1 1980 - sec += int64(yy) * 365 * 86400 - sec += int64(yy) / 4 * 86400 - if yy%4 > 0 || mm >= 3 { - sec += 86400 - } - sec += int64(daysBeforeMonth[mm]) * 86400 - sec += int64(dd-1) * 86400 - - h := time >> 11 - m := time >> 5 & 0x3F - s := time & 0x1f * 2 - sec += int64(h*3600 + m*60 + s) - - return sec -} - -var daysBeforeMonth = [...]int32{ - 0, - 0, - 31, - 31 + 28, - 31 + 28 + 31, - 31 + 28 + 31 + 30, - 31 + 28 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31, -} diff --git a/unix/zsyscall_nacl_386.go b/unix/zsyscall_nacl_386.go deleted file mode 100644 index 787787c2..00000000 --- a/unix/zsyscall_nacl_386.go +++ /dev/null @@ -1,63 +0,0 @@ -// mkunix.pl -l32 -nacl syscall_nacl.go syscall_nacl_386.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package unix - -import "unsafe" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclClose(fd int) (err error) { - _, _, e1 := Syscall(sys_close, uintptr(fd), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exit(code int) (err error) { - _, _, e1 := Syscall(sys_exit, uintptr(code), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclFstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(sys_fstat, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclRead(fd int, b []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(sys_read, uintptr(fd), uintptr(_p0), uintptr(len(b))) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclSeek(fd int, off *int64, whence int) (err error) { - _, _, e1 := Syscall(sys_lseek, uintptr(fd), uintptr(unsafe.Pointer(off)), uintptr(whence)) - if e1 != 0 { - err = e1 - } - return -} diff --git a/unix/zsyscall_nacl_amd64p32.go b/unix/zsyscall_nacl_amd64p32.go deleted file mode 100644 index 430c7b04..00000000 --- a/unix/zsyscall_nacl_amd64p32.go +++ /dev/null @@ -1,63 +0,0 @@ -// mkunix.pl -nacl syscall_nacl.go syscall_nacl_amd64p32.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package unix - -import "unsafe" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclClose(fd int) (err error) { - _, _, e1 := Syscall(sys_close, uintptr(fd), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exit(code int) (err error) { - _, _, e1 := Syscall(sys_exit, uintptr(code), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclFstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(sys_fstat, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclRead(fd int, b []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(sys_read, uintptr(fd), uintptr(_p0), uintptr(len(b))) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclSeek(fd int, off *int64, whence int) (err error) { - _, _, e1 := Syscall(sys_lseek, uintptr(fd), uintptr(unsafe.Pointer(off)), uintptr(whence)) - if e1 != 0 { - err = e1 - } - return -} diff --git a/unix/zsyscall_nacl_arm.go b/unix/zsyscall_nacl_arm.go deleted file mode 100644 index 622850dd..00000000 --- a/unix/zsyscall_nacl_arm.go +++ /dev/null @@ -1,63 +0,0 @@ -// mkunix.pl -l32 -nacl -arm syscall_nacl.go syscall_nacl_arm.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package unix - -import "unsafe" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclClose(fd int) (err error) { - _, _, e1 := Syscall(sys_close, uintptr(fd), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Exit(code int) (err error) { - _, _, e1 := Syscall(sys_exit, uintptr(code), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclFstat(fd int, stat *Stat_t) (err error) { - _, _, e1 := Syscall(sys_fstat, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclRead(fd int, b []byte) (n int, err error) { - var _p0 unsafe.Pointer - if len(b) > 0 { - _p0 = unsafe.Pointer(&b[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(sys_read, uintptr(fd), uintptr(_p0), uintptr(len(b))) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func naclSeek(fd int, off *int64, whence int) (err error) { - _, _, e1 := Syscall(sys_lseek, uintptr(fd), uintptr(unsafe.Pointer(off)), uintptr(whence)) - if e1 != 0 { - err = e1 - } - return -}