github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/compiler/natives/src/syscall/syscall_unix.go (about)

     1  // +build js,!windows
     2  
     3  package syscall
     4  
     5  import (
     6  	"runtime"
     7  	"unsafe"
     8  
     9  	"github.com/gopherjs/gopherjs/js"
    10  )
    11  
    12  func runtime_envs() []string {
    13  	process := js.Global.Get("process")
    14  	if process == js.Undefined {
    15  		return nil
    16  	}
    17  	jsEnv := process.Get("env")
    18  	envkeys := js.Global.Get("Object").Call("keys", jsEnv)
    19  	envs := make([]string, envkeys.Length())
    20  	for i := 0; i < envkeys.Length(); i++ {
    21  		key := envkeys.Index(i).String()
    22  		envs[i] = key + "=" + jsEnv.Get(key).String()
    23  	}
    24  	return envs
    25  }
    26  
    27  func setenv_c(k, v string) {
    28  	process := js.Global.Get("process")
    29  	if process == js.Undefined {
    30  		return
    31  	}
    32  	process.Get("env").Set(k, v)
    33  }
    34  
    35  func unsetenv_c(k string) {
    36  	process := js.Global.Get("process")
    37  	if process == js.Undefined {
    38  		return
    39  	}
    40  	process.Get("env").Delete(k)
    41  }
    42  
    43  var syscallModule *js.Object
    44  var alreadyTriedToLoad = false
    45  var minusOne = -1
    46  
    47  func syscallByName(name string) *js.Object {
    48  	defer func() {
    49  		recover()
    50  		// return nil if recovered
    51  	}()
    52  	if syscallModule == nil {
    53  		if alreadyTriedToLoad {
    54  			return nil
    55  		}
    56  		alreadyTriedToLoad = true
    57  		require := js.Global.Get("require")
    58  		if require == js.Undefined {
    59  			panic("")
    60  		}
    61  		syscallModule = require.Invoke("syscall")
    62  	}
    63  	return syscallModule.Get(name)
    64  }
    65  
    66  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
    67  	if f := syscallByName("Syscall"); f != nil {
    68  		r := f.Invoke(trap, a1, a2, a3)
    69  		return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
    70  	}
    71  	if trap == SYS_WRITE && (a1 == 1 || a1 == 2) {
    72  		array := js.InternalObject(a2)
    73  		slice := make([]byte, array.Length())
    74  		js.InternalObject(slice).Set("$array", array)
    75  		printToConsole(slice)
    76  		return uintptr(array.Length()), 0, 0
    77  	}
    78  	if trap == exitTrap {
    79  		runtime.Goexit()
    80  	}
    81  	printWarning()
    82  	return uintptr(minusOne), 0, EACCES
    83  }
    84  
    85  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
    86  	if f := syscallByName("Syscall6"); f != nil {
    87  		r := f.Invoke(trap, a1, a2, a3, a4, a5, a6)
    88  		return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
    89  	}
    90  	if trap != 202 { // kern.osrelease on OS X, happens in init of "os" package
    91  		printWarning()
    92  	}
    93  	return uintptr(minusOne), 0, EACCES
    94  }
    95  
    96  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
    97  	if f := syscallByName("Syscall"); f != nil {
    98  		r := f.Invoke(trap, a1, a2, a3)
    99  		return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
   100  	}
   101  	printWarning()
   102  	return uintptr(minusOne), 0, EACCES
   103  }
   104  
   105  func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
   106  	if f := syscallByName("Syscall"); f != nil {
   107  		r := f.Invoke(trap, a1, a2, a3)
   108  		return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int())
   109  	}
   110  	printWarning()
   111  	return uintptr(minusOne), 0
   112  }
   113  
   114  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
   115  	if f := syscallByName("Syscall6"); f != nil {
   116  		r := f.Invoke(trap, a1, a2, a3, a4, a5, a6)
   117  		return uintptr(r.Index(0).Int()), uintptr(r.Index(1).Int()), Errno(r.Index(2).Int())
   118  	}
   119  	printWarning()
   120  	return uintptr(minusOne), 0, EACCES
   121  }
   122  
   123  func BytePtrFromString(s string) (*byte, error) {
   124  	array := js.Global.Get("Uint8Array").New(len(s) + 1)
   125  	for i, b := range []byte(s) {
   126  		if b == 0 {
   127  			return nil, EINVAL
   128  		}
   129  		array.SetIndex(i, b)
   130  	}
   131  	array.SetIndex(len(s), 0)
   132  	return (*byte)(unsafe.Pointer(array.Unsafe())), nil
   133  }