forked from gopherjs/gopherjs
/
syscall_unix.go
111 lines (99 loc) · 2.8 KB
/
syscall_unix.go
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
// +build js,!windows
package syscall
import (
"unsafe"
"github.com/gopherjs/gopherjs/js"
)
func runtime_envs() []string {
process := js.Global.Get("process")
if process == js.Undefined {
return nil
}
jsEnv := process.Get("env")
envkeys := js.Global.Get("Object").Call("keys", jsEnv)
envs := make([]string, envkeys.Length())
for i := 0; i < envkeys.Length(); i++ {
key := envkeys.Index(i).Str()
envs[i] = key + "=" + jsEnv.Get(key).Str()
}
return envs
}
func setenv_c(k, v string) {
process := js.Global.Get("process")
if process != js.Undefined {
process.Get("env").Set(k, v)
}
}
var syscallModule js.Object
var alreadyTriedToLoad = false
var minusOne = -1
func syscall(name string) js.Object {
defer func() {
recover()
// return nil if recovered
}()
if syscallModule == nil {
if alreadyTriedToLoad {
return nil
}
alreadyTriedToLoad = true
require := js.Global.Get("require")
if require == js.Undefined {
panic("")
}
syscallModule = require.Invoke("syscall")
}
return syscallModule.Get(name)
}
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
if f := syscall("Syscall"); f != nil {
r := f.Invoke(trap, a1, a2, a3)
return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
}
if trap == SYS_WRITE && (a1 == 1 || a1 == 2) {
array := js.InternalObject(a2)
slice := make([]byte, array.Length())
js.InternalObject(slice).Set("$array", array)
printToConsole(slice)
return uintptr(array.Length()), 0, 0
}
printWarning()
return uintptr(minusOne), 0, EACCES
}
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
if f := syscall("Syscall6"); f != nil {
r := f.Invoke(trap, a1, a2, a3, a4, a5, a6)
return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
}
if trap != 202 { // kern.osrelease on OS X, happens in init of "os" package
printWarning()
}
return uintptr(minusOne), 0, EACCES
}
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
if f := syscall("Syscall"); f != nil {
r := f.Invoke(trap, a1, a2, a3)
return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
}
printWarning()
return uintptr(minusOne), 0, EACCES
}
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
if f := syscall("Syscall6"); f != nil {
r := f.Invoke(trap, a1, a2, a3, a4, a5, a6)
return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
}
printWarning()
return uintptr(minusOne), 0, EACCES
}
func BytePtrFromString(s string) (*byte, error) {
array := js.Global.Get("Uint8Array").New(len(s) + 1)
for i, b := range []byte(s) {
if b == 0 {
return nil, EINVAL
}
array.SetIndex(i, b)
}
array.SetIndex(len(s), 0)
return (*byte)(unsafe.Pointer(array.Unsafe())), nil
}