mirror of https://github.com/golang/go.git
os: add js/wasm architecture
This commit adds the js/wasm architecture to the os package. Access to the actual file system is supported through Node.js. Updates #18892 Change-Id: I6fa642fb294ca020b2c545649d4324d981aa0408 Reviewed-on: https://go-review.googlesource.com/109977 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
a7e0a920ad
commit
063f97a611
|
|
@ -143,6 +143,11 @@
|
|||
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
|
||||
},
|
||||
|
||||
// func getRandomData(r []byte)
|
||||
"runtime.getRandomData": (sp) => {
|
||||
crypto.getRandomValues(loadSlice(sp + 8));
|
||||
},
|
||||
|
||||
// func boolVal(value bool) Value
|
||||
"syscall/js.boolVal": (sp) => {
|
||||
storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
|
||||
|
|
|
|||
|
|
@ -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 nacl
|
||||
// +build nacl js,wasm
|
||||
|
||||
package poll
|
||||
|
||||
|
|
@ -42,6 +42,9 @@ func (pd *pollDesc) wait(mode int, isFile bool) error {
|
|||
if pd.closing {
|
||||
return errClosing(isFile)
|
||||
}
|
||||
if isFile { // TODO(neelance): wasm: Use callbacks from JS to block until the read/write finished.
|
||||
return nil
|
||||
}
|
||||
return ErrTimeout
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 windows
|
||||
// +build darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package poll
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package poll
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// This file implements sysSocket and accept for platforms that do not
|
||||
// provide a fast path for setting SetNonblock and CloseOnExec.
|
||||
|
||||
// +build darwin nacl solaris
|
||||
// +build darwin js,wasm nacl solaris
|
||||
|
||||
package poll
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2018 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
|
||||
|
||||
func IsNonblock(fd int) (nonblocking bool, err error) {
|
||||
return false, nil
|
||||
}
|
||||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 windows
|
||||
// +build darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os_test
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// +build js,wasm
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrNotFound is the error resulting if a path search failed to find an executable file.
|
||||
var ErrNotFound = errors.New("executable file not found in $PATH")
|
||||
|
||||
// LookPath searches for an executable named file in the
|
||||
// directories named by the PATH environment variable.
|
||||
// If file contains a slash, it is tried directly and the PATH is not consulted.
|
||||
// The result may be an absolute path or a path relative to the current directory.
|
||||
func LookPath(file string) (string, error) {
|
||||
// Wasm can not execute processes, so act as if there are no executables at all.
|
||||
return "", &Error{file, ErrNotFound}
|
||||
}
|
||||
|
|
@ -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 windows
|
||||
// +build darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 linux netbsd dragonfly nacl
|
||||
// +build linux netbsd dragonfly nacl js,wasm
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 windows
|
||||
// +build darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -1390,7 +1390,7 @@ func TestSeek(t *testing.T) {
|
|||
|
||||
func TestSeekError(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "nacl":
|
||||
case "js", "nacl", "plan9":
|
||||
t.Skipf("skipping test on %v", runtime.GOOS)
|
||||
}
|
||||
|
||||
|
|
@ -2252,6 +2252,8 @@ func TestPipeThreads(t *testing.T) {
|
|||
t.Skip("skipping on Windows; issue 19098")
|
||||
case "plan9":
|
||||
t.Skip("skipping on Plan 9; does not support runtime poller")
|
||||
case "js":
|
||||
t.Skip("skipping on js; no support for os.Pipe")
|
||||
}
|
||||
|
||||
threads := 100
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 nacl solaris
|
||||
// +build darwin dragonfly js,wasm nacl solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Test broken pipes on Unix systems.
|
||||
// +build !windows,!plan9,!nacl
|
||||
// +build !windows,!plan9,!nacl,!js
|
||||
|
||||
package os_test
|
||||
|
||||
|
|
|
|||
|
|
@ -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 windows
|
||||
// +build darwin dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package signal
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build js,wasm nacl
|
||||
|
||||
package os
|
||||
|
||||
import (
|
||||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 nacl netbsd openbsd
|
||||
// +build darwin dragonfly freebsd js,wasm nacl netbsd openbsd
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// +build js,wasm
|
||||
|
||||
package os
|
||||
|
||||
// supportsCloseOnExec reports whether the platform supports the
|
||||
// O_CLOEXEC flag.
|
||||
const supportsCloseOnExec = false
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !nacl
|
||||
// +build !js
|
||||
// +build !plan9
|
||||
// +build !windows
|
||||
|
||||
|
|
|
|||
|
|
@ -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 !android,linux nacl netbsd openbsd solaris
|
||||
// +build darwin dragonfly freebsd js,wasm !android,linux nacl netbsd openbsd solaris
|
||||
// +build !cgo osusergo
|
||||
|
||||
package user
|
||||
|
|
|
|||
|
|
@ -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 nacl netbsd openbsd solaris
|
||||
// +build darwin dragonfly js,wasm nacl netbsd openbsd solaris
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package filepath
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import (
|
|||
)
|
||||
|
||||
func TestWriteHeapDumpNonempty(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" {
|
||||
t.Skip("WriteHeapDump is not available on NaCl.")
|
||||
if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
|
||||
t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS)
|
||||
}
|
||||
f, err := ioutil.TempFile("", "heapdumptest")
|
||||
if err != nil {
|
||||
|
|
@ -42,8 +42,8 @@ func objfin(x *Obj) {
|
|||
}
|
||||
|
||||
func TestWriteHeapDumpFinalizers(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" {
|
||||
t.Skip("WriteHeapDump is not available on NaCl.")
|
||||
if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
|
||||
t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS)
|
||||
}
|
||||
f, err := ioutil.TempFile("", "heapdumptest")
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// +build js,wasm
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func exit(code int32)
|
||||
|
||||
func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
|
||||
if fd > 2 {
|
||||
throw("runtime.write to fd > 2 is unsupported")
|
||||
}
|
||||
wasmWrite(fd, p, n)
|
||||
return n
|
||||
}
|
||||
|
||||
// Stubs so tests can link correctly. These should never be called.
|
||||
func open(name *byte, mode, perm int32) int32 { panic("not implemented") }
|
||||
func closefd(fd int32) int32 { panic("not implemented") }
|
||||
func read(fd int32, p unsafe.Pointer, n int32) int32 { panic("not implemented") }
|
||||
|
||||
//go:noescape
|
||||
func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
|
||||
|
||||
func usleep(usec uint32)
|
||||
|
||||
func exitThread(wait *uint32)
|
||||
|
||||
type mOS struct{}
|
||||
|
||||
func osyield()
|
||||
|
||||
const _SIGSEGV = 0xb
|
||||
|
||||
func sigpanic() {
|
||||
g := getg()
|
||||
if !canpanic(g) {
|
||||
throw("unexpected signal during runtime execution")
|
||||
}
|
||||
|
||||
// js only invokes the exception handler for memory faults.
|
||||
g.sig = _SIGSEGV
|
||||
panicmem()
|
||||
}
|
||||
|
||||
type sigset struct{}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
|
||||
func mpreinit(mp *m) {
|
||||
mp.gsignal = malg(32 * 1024)
|
||||
mp.gsignal.m = mp
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigsave(mp *m) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func msigrestore(sigmask sigset) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func clearSignalHandlers() {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func sigblock() {
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
// Called on the new thread, cannot allocate memory.
|
||||
func minit() {
|
||||
}
|
||||
|
||||
// Called from dropm to undo the effect of an minit.
|
||||
func unminit() {
|
||||
}
|
||||
|
||||
func osinit() {
|
||||
ncpu = 1
|
||||
getg().m.procid = 2
|
||||
physPageSize = 64 * 1024
|
||||
}
|
||||
|
||||
// wasm has no signals
|
||||
const _NSIG = 0
|
||||
|
||||
func signame(sig uint32) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func crash() {
|
||||
*(*int32)(nil) = 0
|
||||
}
|
||||
|
||||
func getRandomData(r []byte)
|
||||
|
||||
func goenvs() {
|
||||
goenvs_unix()
|
||||
}
|
||||
|
||||
func initsig(preinit bool) {
|
||||
}
|
||||
|
||||
// May run with m.p==nil, so write barriers are not allowed.
|
||||
//go:nowritebarrier
|
||||
func newosproc(mp *m) {
|
||||
panic("newosproc: not implemented")
|
||||
}
|
||||
|
||||
func setProcessCPUProfiler(hz int32) {}
|
||||
func setThreadCPUProfiler(hz int32) {}
|
||||
func sigdisable(uint32) {}
|
||||
func sigenable(uint32) {}
|
||||
func sigignore(uint32) {}
|
||||
|
||||
//go:linkname os_sigpipe os.sigpipe
|
||||
func os_sigpipe() {
|
||||
throw("too many writes on closed pipe")
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func cputicks() int64 {
|
||||
// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand().
|
||||
// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
|
||||
// TODO: need more entropy to better seed fastrand.
|
||||
return nanotime()
|
||||
}
|
||||
|
||||
//go:linkname syscall_now syscall.now
|
||||
func syscall_now() (sec int64, nsec int32) {
|
||||
sec, nsec, _ = time_now()
|
||||
return
|
||||
}
|
||||
|
||||
// gsignalStack is unused on js.
|
||||
type gsignalStack struct{}
|
||||
|
|
@ -193,3 +193,7 @@ TEXT ·nanotime(SB), NOSPLIT, $0
|
|||
TEXT ·walltime(SB), NOSPLIT, $0
|
||||
CallImport
|
||||
RET
|
||||
|
||||
TEXT ·getRandomData(SB), NOSPLIT, $0
|
||||
CallImport
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -180,6 +180,9 @@ func testBrokenTimestamps(t *testing.T, data []byte) {
|
|||
}
|
||||
|
||||
func TestTraceStress(t *testing.T) {
|
||||
if runtime.GOOS == "js" {
|
||||
t.Skip("no os.Pipe on js")
|
||||
}
|
||||
if IsEnabled() {
|
||||
t.Skip("skipping because -test.trace is set")
|
||||
}
|
||||
|
|
@ -322,6 +325,9 @@ func TestTraceStress(t *testing.T) {
|
|||
// Do a bunch of various stuff (timers, GC, network, etc) in a separate goroutine.
|
||||
// And concurrently with all that start/stop trace 3 times.
|
||||
func TestTraceStressStartStop(t *testing.T) {
|
||||
if runtime.GOOS == "js" {
|
||||
t.Skip("no os.Pipe on js")
|
||||
}
|
||||
if IsEnabled() {
|
||||
t.Skip("skipping because -test.trace is set")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
package syscall
|
||||
|
||||
|
|
|
|||
|
|
@ -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 386 amd64 amd64p32 arm arm64 ppc64le mips64le mipsle
|
||||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mips64le mipsle wasm
|
||||
|
||||
package syscall
|
||||
|
||||
|
|
|
|||
|
|
@ -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 js,wasm linux nacl netbsd openbsd solaris
|
||||
|
||||
// Unix environment variables.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,497 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// +build js,wasm
|
||||
|
||||
package syscall
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
// Provided by package runtime.
|
||||
func now() (sec int64, nsec int32)
|
||||
|
||||
var jsProcess = js.Global.Get("process")
|
||||
var jsFS = js.Global.Get("fs")
|
||||
var constants = jsFS.Get("constants")
|
||||
|
||||
var (
|
||||
nodeWRONLY = constants.Get("O_WRONLY").Int()
|
||||
nodeRDWR = constants.Get("O_RDWR").Int()
|
||||
nodeCREATE = constants.Get("O_CREAT").Int()
|
||||
nodeTRUNC = constants.Get("O_TRUNC").Int()
|
||||
nodeAPPEND = constants.Get("O_APPEND").Int()
|
||||
nodeEXCL = constants.Get("O_EXCL").Int()
|
||||
nodeNONBLOCK = constants.Get("O_NONBLOCK").Int()
|
||||
nodeSYNC = constants.Get("O_SYNC").Int()
|
||||
)
|
||||
|
||||
type jsFile struct {
|
||||
path string
|
||||
entries []string
|
||||
pos int64
|
||||
seeked bool
|
||||
}
|
||||
|
||||
var filesMu sync.Mutex
|
||||
var files = map[int]*jsFile{
|
||||
0: &jsFile{},
|
||||
1: &jsFile{},
|
||||
2: &jsFile{},
|
||||
}
|
||||
|
||||
func fdToFile(fd int) (*jsFile, error) {
|
||||
filesMu.Lock()
|
||||
f, ok := files[fd]
|
||||
filesMu.Unlock()
|
||||
if !ok {
|
||||
return nil, EBADF
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func Open(path string, openmode int, perm uint32) (int, error) {
|
||||
if err := checkPath(path); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
flags := 0
|
||||
if openmode&O_WRONLY != 0 {
|
||||
flags |= nodeWRONLY
|
||||
}
|
||||
if openmode&O_RDWR != 0 {
|
||||
flags |= nodeRDWR
|
||||
}
|
||||
if openmode&O_CREATE != 0 {
|
||||
flags |= nodeCREATE
|
||||
}
|
||||
if openmode&O_TRUNC != 0 {
|
||||
flags |= nodeTRUNC
|
||||
}
|
||||
if openmode&O_APPEND != 0 {
|
||||
flags |= nodeAPPEND
|
||||
}
|
||||
if openmode&O_EXCL != 0 {
|
||||
flags |= nodeEXCL
|
||||
}
|
||||
if openmode&O_NONBLOCK != 0 {
|
||||
flags |= nodeNONBLOCK
|
||||
}
|
||||
if openmode&O_SYNC != 0 {
|
||||
flags |= nodeSYNC
|
||||
}
|
||||
|
||||
jsFD, err := fsCall("openSync", path, flags, perm)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fd := jsFD.Int()
|
||||
|
||||
var entries []string
|
||||
if stat, err := fsCall("fstatSync", fd); err == nil && stat.Call("isDirectory").Bool() {
|
||||
dir, err := fsCall("readdirSync", path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
entries = make([]string, dir.Length())
|
||||
for i := range entries {
|
||||
entries[i] = dir.Index(i).String()
|
||||
}
|
||||
}
|
||||
|
||||
f := &jsFile{
|
||||
path: path,
|
||||
entries: entries,
|
||||
}
|
||||
filesMu.Lock()
|
||||
files[fd] = f
|
||||
filesMu.Unlock()
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
func Close(fd int) error {
|
||||
filesMu.Lock()
|
||||
delete(files, fd)
|
||||
filesMu.Unlock()
|
||||
_, err := fsCall("closeSync", fd)
|
||||
return err
|
||||
}
|
||||
|
||||
func CloseOnExec(fd int) {
|
||||
// nothing to do - no exec
|
||||
}
|
||||
|
||||
func Mkdir(path string, perm uint32) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("mkdirSync", path, perm)
|
||||
return err
|
||||
}
|
||||
|
||||
func ReadDirent(fd int, buf []byte) (int, error) {
|
||||
f, err := fdToFile(fd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if f.entries == nil {
|
||||
return 0, EINVAL
|
||||
}
|
||||
|
||||
n := 0
|
||||
for len(f.entries) > 0 {
|
||||
entry := f.entries[0]
|
||||
l := 2 + len(entry)
|
||||
if l > len(buf) {
|
||||
break
|
||||
}
|
||||
buf[0] = byte(l)
|
||||
buf[1] = byte(l >> 8)
|
||||
copy(buf[2:], entry)
|
||||
buf = buf[l:]
|
||||
n += l
|
||||
f.entries = f.entries[1:]
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func setStat(st *Stat_t, jsSt js.Value) {
|
||||
st.Dev = int64(jsSt.Get("dev").Int())
|
||||
st.Ino = uint64(jsSt.Get("ino").Int())
|
||||
st.Mode = uint32(jsSt.Get("mode").Int())
|
||||
st.Nlink = uint32(jsSt.Get("nlink").Int())
|
||||
st.Uid = uint32(jsSt.Get("uid").Int())
|
||||
st.Gid = uint32(jsSt.Get("gid").Int())
|
||||
st.Rdev = int64(jsSt.Get("rdev").Int())
|
||||
st.Size = int64(jsSt.Get("size").Int())
|
||||
st.Blksize = int32(jsSt.Get("blksize").Int())
|
||||
st.Blocks = int32(jsSt.Get("blocks").Int())
|
||||
atime := int64(jsSt.Get("atimeMs").Int())
|
||||
st.Atime = atime / 1000
|
||||
st.AtimeNsec = (atime % 1000) * 1000000
|
||||
mtime := int64(jsSt.Get("mtimeMs").Int())
|
||||
st.Mtime = mtime / 1000
|
||||
st.MtimeNsec = (mtime % 1000) * 1000000
|
||||
ctime := int64(jsSt.Get("ctimeMs").Int())
|
||||
st.Ctime = ctime / 1000
|
||||
st.CtimeNsec = (ctime % 1000) * 1000000
|
||||
}
|
||||
|
||||
func Stat(path string, st *Stat_t) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
jsSt, err := fsCall("statSync", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setStat(st, jsSt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Lstat(path string, st *Stat_t) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
jsSt, err := fsCall("lstatSync", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setStat(st, jsSt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Fstat(fd int, st *Stat_t) error {
|
||||
jsSt, err := fsCall("fstatSync", fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setStat(st, jsSt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Unlink(path string) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("unlinkSync", path)
|
||||
return err
|
||||
}
|
||||
|
||||
func Rmdir(path string) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("rmdirSync", path)
|
||||
return err
|
||||
}
|
||||
|
||||
func Chmod(path string, mode uint32) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("chmodSync", path, mode)
|
||||
return err
|
||||
}
|
||||
|
||||
func Fchmod(fd int, mode uint32) error {
|
||||
_, err := fsCall("fchmodSync", fd, mode)
|
||||
return err
|
||||
}
|
||||
|
||||
func Chown(path string, uid, gid int) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
func Fchown(fd int, uid, gid int) error {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
func Lchown(path string, uid, gid int) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
func UtimesNano(path string, ts []Timespec) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ts) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
atime := ts[0].Sec
|
||||
mtime := ts[1].Sec
|
||||
_, err := fsCall("utimesSync", path, atime, mtime)
|
||||
return err
|
||||
}
|
||||
|
||||
func Rename(from, to string) error {
|
||||
if err := checkPath(from); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkPath(to); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("renameSync", from, to)
|
||||
return err
|
||||
}
|
||||
|
||||
func Truncate(path string, length int64) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("truncateSync", path, length)
|
||||
return err
|
||||
}
|
||||
|
||||
func Ftruncate(fd int, length int64) error {
|
||||
_, err := fsCall("ftruncateSync", fd, length)
|
||||
return err
|
||||
}
|
||||
|
||||
func Getcwd(buf []byte) (n int, err error) {
|
||||
defer recoverErr(&err)
|
||||
cwd := jsProcess.Call("cwd").String()
|
||||
n = copy(buf, cwd)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func Chdir(path string) (err error) {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
defer recoverErr(&err)
|
||||
jsProcess.Call("chdir", path)
|
||||
return
|
||||
}
|
||||
|
||||
func Fchdir(fd int) error {
|
||||
f, err := fdToFile(fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return Chdir(f.path)
|
||||
}
|
||||
|
||||
func Readlink(path string, buf []byte) (n int, err error) {
|
||||
if err := checkPath(path); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
dst, err := fsCall("readlinkSync", path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n = copy(buf, dst.String())
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func Link(path, link string) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkPath(link); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("linkSync", path, link)
|
||||
return err
|
||||
}
|
||||
|
||||
func Symlink(path, link string) error {
|
||||
if err := checkPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkPath(link); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fsCall("symlinkSync", path, link)
|
||||
return err
|
||||
}
|
||||
|
||||
func Fsync(fd int) error {
|
||||
_, err := fsCall("fsyncSync", fd)
|
||||
return err
|
||||
}
|
||||
|
||||
func Read(fd int, b []byte) (int, error) {
|
||||
f, err := fdToFile(fd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if f.seeked {
|
||||
n, err := Pread(fd, b, f.pos)
|
||||
f.pos += int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
n, err := fsCall("readSync", fd, b, 0, len(b))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n2 := n.Int()
|
||||
f.pos += int64(n2)
|
||||
return n2, err
|
||||
}
|
||||
|
||||
func Write(fd int, b []byte) (int, error) {
|
||||
f, err := fdToFile(fd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if f.seeked {
|
||||
n, err := Pwrite(fd, b, f.pos)
|
||||
f.pos += int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
n, err := fsCall("writeSync", fd, b, 0, len(b))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n2 := n.Int()
|
||||
f.pos += int64(n2)
|
||||
return n2, err
|
||||
}
|
||||
|
||||
func Pread(fd int, b []byte, offset int64) (int, error) {
|
||||
n, err := fsCall("readSync", fd, b, 0, len(b), offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return n.Int(), nil
|
||||
}
|
||||
|
||||
func Pwrite(fd int, b []byte, offset int64) (int, error) {
|
||||
n, err := fsCall("writeSync", fd, b, 0, len(b), offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return n.Int(), nil
|
||||
}
|
||||
|
||||
func Seek(fd int, offset int64, whence int) (int64, error) {
|
||||
f, err := fdToFile(fd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var newPos int64
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
newPos = offset
|
||||
case io.SeekCurrent:
|
||||
newPos = f.pos + offset
|
||||
case io.SeekEnd:
|
||||
var st Stat_t
|
||||
if err := Fstat(fd, &st); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
newPos = st.Size + offset
|
||||
default:
|
||||
return 0, errnoErr(EINVAL)
|
||||
}
|
||||
|
||||
if newPos < 0 {
|
||||
return 0, errnoErr(EINVAL)
|
||||
}
|
||||
|
||||
f.seeked = true
|
||||
f.pos = newPos
|
||||
return newPos, nil
|
||||
}
|
||||
|
||||
func Dup(fd int) (int, error) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
||||
func Dup2(fd, newfd int) error {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
func Pipe(fd []int) error {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
func fsCall(name string, args ...interface{}) (res js.Value, err error) {
|
||||
defer recoverErr(&err)
|
||||
res = jsFS.Call(name, args...)
|
||||
return
|
||||
}
|
||||
|
||||
// checkPath checks that the path is not empty and that it contains no null characters.
|
||||
func checkPath(path string) error {
|
||||
if path == "" {
|
||||
return EINVAL
|
||||
}
|
||||
for i := 0; i < len(path); i++ {
|
||||
if path[i] == '\x00' {
|
||||
return EINVAL
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func recoverErr(errPtr *error) {
|
||||
if err := recover(); err != nil {
|
||||
jsErr, ok := err.(js.Error)
|
||||
if !ok {
|
||||
panic(err)
|
||||
}
|
||||
errno, ok := errnoByCode[jsErr.Get("code").String()]
|
||||
if !ok {
|
||||
panic(err)
|
||||
}
|
||||
*errPtr = errnoErr(Errno(errno))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// +build js,wasm
|
||||
|
||||
package syscall
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const direntSize = 8 + 8 + 2 + 256
|
||||
|
||||
type Dirent struct {
|
||||
Reclen uint16
|
||||
Name [256]byte
|
||||
}
|
||||
|
||||
func direntIno(buf []byte) (uint64, bool) {
|
||||
return 1, true
|
||||
}
|
||||
|
||||
func direntReclen(buf []byte) (uint64, bool) {
|
||||
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
|
||||
}
|
||||
|
||||
func direntNamlen(buf []byte) (uint64, bool) {
|
||||
reclen, ok := direntReclen(buf)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
const (
|
||||
O_RDONLY = 0
|
||||
O_WRONLY = 1
|
||||
O_RDWR = 2
|
||||
|
||||
O_CREAT = 0100
|
||||
O_CREATE = O_CREAT
|
||||
O_TRUNC = 01000
|
||||
O_APPEND = 02000
|
||||
O_EXCL = 0200
|
||||
O_NONBLOCK = 04000
|
||||
O_SYNC = 010000
|
||||
|
||||
O_CLOEXEC = 0
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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 - 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 {
|
||||
}
|
||||
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return 0, 0, ENOSYS
|
||||
}
|
||||
|
||||
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 "js", nil
|
||||
}
|
||||
return "", ENOSYS
|
||||
}
|
||||
|
||||
const ImplementsGetwd = true
|
||||
|
||||
func Getwd() (wd string, err error) {
|
||||
var buf [PathMax]byte
|
||||
n, err := Getcwd(buf[0:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(buf[:n]), nil
|
||||
}
|
||||
|
||||
func Getegid() int { return 1 }
|
||||
func Geteuid() int { return 1 }
|
||||
func Getgid() int { return 1 }
|
||||
func Getgroups() ([]int, error) { return []int{1}, nil }
|
||||
func Getppid() int { return 2 }
|
||||
func Getpid() int { return 3 }
|
||||
func Gettimeofday(tv *Timeval) error { return ENOSYS }
|
||||
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
|
||||
}
|
||||
|
||||
type Iovec struct{} // dummy
|
||||
|
||||
type Timespec struct {
|
||||
Sec int64
|
||||
Nsec int64
|
||||
}
|
||||
|
||||
type Timeval struct {
|
||||
Sec int64
|
||||
Usec int64
|
||||
}
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: sec, Nsec: nsec}
|
||||
}
|
||||
|
||||
func setTimeval(sec, usec int64) Timeval {
|
||||
return Timeval{Sec: sec, Usec: usec}
|
||||
}
|
||||
|
|
@ -2,10 +2,12 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build nacl
|
||||
// +build nacl js,wasm
|
||||
|
||||
package syscall
|
||||
|
||||
import "runtime"
|
||||
|
||||
// TODO: generate with runtime/mknacl.sh, allow override with IRT.
|
||||
const (
|
||||
sys_null = 1
|
||||
|
|
@ -254,7 +256,7 @@ var errorstr = [...]string{
|
|||
EMLINK: "Too many links",
|
||||
EPIPE: "Broken pipe",
|
||||
ENAMETOOLONG: "File name too long",
|
||||
ENOSYS: "not implemented on Native Client",
|
||||
ENOSYS: "not implemented on " + runtime.GOOS,
|
||||
EDQUOT: "Quota exceeded",
|
||||
EDOM: "Math arg out of domain of func",
|
||||
ERANGE: "Math result not representable",
|
||||
|
|
@ -361,3 +363,128 @@ func errnoErr(e Errno) error {
|
|||
}
|
||||
return e
|
||||
}
|
||||
|
||||
var errnoByCode = map[string]Errno{
|
||||
"EPERM": EPERM,
|
||||
"ENOENT": ENOENT,
|
||||
"ESRCH": ESRCH,
|
||||
"EINTR": EINTR,
|
||||
"EIO": EIO,
|
||||
"ENXIO": ENXIO,
|
||||
"E2BIG": E2BIG,
|
||||
"ENOEXEC": ENOEXEC,
|
||||
"EBADF": EBADF,
|
||||
"ECHILD": ECHILD,
|
||||
"EAGAIN": EAGAIN,
|
||||
"ENOMEM": ENOMEM,
|
||||
"EACCES": EACCES,
|
||||
"EFAULT": EFAULT,
|
||||
"EBUSY": EBUSY,
|
||||
"EEXIST": EEXIST,
|
||||
"EXDEV": EXDEV,
|
||||
"ENODEV": ENODEV,
|
||||
"ENOTDIR": ENOTDIR,
|
||||
"EISDIR": EISDIR,
|
||||
"EINVAL": EINVAL,
|
||||
"ENFILE": ENFILE,
|
||||
"EMFILE": EMFILE,
|
||||
"ENOTTY": ENOTTY,
|
||||
"EFBIG": EFBIG,
|
||||
"ENOSPC": ENOSPC,
|
||||
"ESPIPE": ESPIPE,
|
||||
"EROFS": EROFS,
|
||||
"EMLINK": EMLINK,
|
||||
"EPIPE": EPIPE,
|
||||
"ENAMETOOLONG": ENAMETOOLONG,
|
||||
"ENOSYS": ENOSYS,
|
||||
"EDQUOT": EDQUOT,
|
||||
"EDOM": EDOM,
|
||||
"ERANGE": ERANGE,
|
||||
"EDEADLK": EDEADLK,
|
||||
"ENOLCK": ENOLCK,
|
||||
"ENOTEMPTY": ENOTEMPTY,
|
||||
"ELOOP": ELOOP,
|
||||
"ENOMSG": ENOMSG,
|
||||
"EIDRM": EIDRM,
|
||||
"ECHRNG": ECHRNG,
|
||||
"EL2NSYNC": EL2NSYNC,
|
||||
"EL3HLT": EL3HLT,
|
||||
"EL3RST": EL3RST,
|
||||
"ELNRNG": ELNRNG,
|
||||
"EUNATCH": EUNATCH,
|
||||
"ENOCSI": ENOCSI,
|
||||
"EL2HLT": EL2HLT,
|
||||
"EBADE": EBADE,
|
||||
"EBADR": EBADR,
|
||||
"EXFULL": EXFULL,
|
||||
"ENOANO": ENOANO,
|
||||
"EBADRQC": EBADRQC,
|
||||
"EBADSLT": EBADSLT,
|
||||
"EDEADLOCK": EDEADLOCK,
|
||||
"EBFONT": EBFONT,
|
||||
"ENOSTR": ENOSTR,
|
||||
"ENODATA": ENODATA,
|
||||
"ETIME": ETIME,
|
||||
"ENOSR": ENOSR,
|
||||
"ENONET": ENONET,
|
||||
"ENOPKG": ENOPKG,
|
||||
"EREMOTE": EREMOTE,
|
||||
"ENOLINK": ENOLINK,
|
||||
"EADV": EADV,
|
||||
"ESRMNT": ESRMNT,
|
||||
"ECOMM": ECOMM,
|
||||
"EPROTO": EPROTO,
|
||||
"EMULTIHOP": EMULTIHOP,
|
||||
"EDOTDOT": EDOTDOT,
|
||||
"EBADMSG": EBADMSG,
|
||||
"EOVERFLOW": EOVERFLOW,
|
||||
"ENOTUNIQ": ENOTUNIQ,
|
||||
"EBADFD": EBADFD,
|
||||
"EREMCHG": EREMCHG,
|
||||
"ELIBACC": ELIBACC,
|
||||
"ELIBBAD": ELIBBAD,
|
||||
"ELIBSCN": ELIBSCN,
|
||||
"ELIBMAX": ELIBMAX,
|
||||
"ELIBEXEC": ELIBEXEC,
|
||||
"EILSEQ": EILSEQ,
|
||||
"EUSERS": EUSERS,
|
||||
"ENOTSOCK": ENOTSOCK,
|
||||
"EDESTADDRREQ": EDESTADDRREQ,
|
||||
"EMSGSIZE": EMSGSIZE,
|
||||
"EPROTOTYPE": EPROTOTYPE,
|
||||
"ENOPROTOOPT": ENOPROTOOPT,
|
||||
"EPROTONOSUPPORT": EPROTONOSUPPORT,
|
||||
"ESOCKTNOSUPPORT": ESOCKTNOSUPPORT,
|
||||
"EOPNOTSUPP": EOPNOTSUPP,
|
||||
"EPFNOSUPPORT": EPFNOSUPPORT,
|
||||
"EAFNOSUPPORT": EAFNOSUPPORT,
|
||||
"EADDRINUSE": EADDRINUSE,
|
||||
"EADDRNOTAVAIL": EADDRNOTAVAIL,
|
||||
"ENETDOWN": ENETDOWN,
|
||||
"ENETUNREACH": ENETUNREACH,
|
||||
"ENETRESET": ENETRESET,
|
||||
"ECONNABORTED": ECONNABORTED,
|
||||
"ECONNRESET": ECONNRESET,
|
||||
"ENOBUFS": ENOBUFS,
|
||||
"EISCONN": EISCONN,
|
||||
"ENOTCONN": ENOTCONN,
|
||||
"ESHUTDOWN": ESHUTDOWN,
|
||||
"ETOOMANYREFS": ETOOMANYREFS,
|
||||
"ETIMEDOUT": ETIMEDOUT,
|
||||
"ECONNREFUSED": ECONNREFUSED,
|
||||
"EHOSTDOWN": EHOSTDOWN,
|
||||
"EHOSTUNREACH": EHOSTUNREACH,
|
||||
"EALREADY": EALREADY,
|
||||
"EINPROGRESS": EINPROGRESS,
|
||||
"ESTALE": ESTALE,
|
||||
"ENOTSUP": ENOTSUP,
|
||||
"ENOMEDIUM": ENOMEDIUM,
|
||||
"ECANCELED": ECANCELED,
|
||||
"ELBIN": ELBIN,
|
||||
"EFTYPE": EFTYPE,
|
||||
"ENMFILE": ENMFILE,
|
||||
"EPROCLIM": EPROCLIM,
|
||||
"ENOSHARE": ENOSHARE,
|
||||
"ECASECLASH": ECASECLASH,
|
||||
"EWOULDBLOCK": EWOULDBLOCK,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue