Files
wazero/internal/gojs/process.go
2023-07-17 08:13:29 +08:00

102 lines
3.3 KiB
Go

package gojs
import (
"context"
"path"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/gojs/custom"
"github.com/tetratelabs/wazero/internal/gojs/goos"
"github.com/tetratelabs/wazero/internal/gojs/util"
)
// processState are the mutable fields of the current process.
type processState struct {
cwd string
umask uint32
}
func newJsProcess(proc *processState) *jsVal {
// Fill fake values for user/group info as we don't support it.
uidRef := goos.RefValueZero
gidRef := goos.RefValueZero
euidRef := goos.RefValueZero
groupSlice := []interface{}{goos.RefValueZero}
// jsProcess = js.Global().Get("process") // fs_js.go init
return newJsVal(goos.RefJsProcess, custom.NameProcess).
addProperties(map[string]interface{}{
"pid": float64(1), // Get("pid").Int() in syscall_js.go for syscall.Getpid
"ppid": goos.RefValueZero, // Get("ppid").Int() in syscall_js.go for syscall.Getppid
}).
addFunction(custom.NameProcessCwd, &processCwd{proc: proc}). // syscall.Cwd in fs_js.go
addFunction(custom.NameProcessChdir, &processChdir{proc: proc}). // syscall.Chdir in fs_js.go
addFunction(custom.NameProcessGetuid, getId(uidRef)). // syscall.Getuid in syscall_js.go
addFunction(custom.NameProcessGetgid, getId(gidRef)). // syscall.Getgid in syscall_js.go
addFunction(custom.NameProcessGeteuid, getId(euidRef)). // syscall.Geteuid in syscall_js.go
addFunction(custom.NameProcessGetgroups, returnSlice(groupSlice)). // syscall.Getgroups in syscall_js.go
addFunction(custom.NameProcessUmask, &processUmask{proc: proc}) // syscall.Umask in syscall_js.go
}
// processCwd implements jsFn for fs.Open syscall.Getcwd in fs_js.go
type processCwd struct {
proc *processState
}
func (p *processCwd) invoke(_ context.Context, _ api.Module, _ ...interface{}) (interface{}, error) {
return p.proc.cwd, nil
}
// processChdir implements jsFn for fs.Open syscall.Chdir in fs_js.go
type processChdir struct {
proc *processState
}
func (p *processChdir) invoke(_ context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
oldWd := p.proc.cwd
newWd := util.ResolvePath(oldWd, args[0].(string))
newWd = path.Clean(newWd)
if newWd == oldWd { // handle .
return nil, nil
}
if s, err := syscallStat(mod, newWd); err != nil {
return nil, err
} else if !s.isDir {
return nil, sys.ENOTDIR
} else {
p.proc.cwd = newWd
return nil, nil
}
}
// processUmask implements jsFn for fs.Open syscall.Umask in fs_js.go
type processUmask struct {
proc *processState
}
func (p *processUmask) invoke(_ context.Context, _ api.Module, args ...interface{}) (interface{}, error) {
newUmask := goos.ValueToUint32(args[0])
oldUmask := p.proc.umask
p.proc.umask = newUmask
return oldUmask, nil
}
// getId implements jsFn for syscall.Getuid, syscall.Getgid and syscall.Geteuid in syscall_js.go
type getId goos.Ref
func (i getId) invoke(_ context.Context, _ api.Module, _ ...interface{}) (interface{}, error) {
return goos.Ref(i), nil
}
// returnSlice implements jsFn for syscall.Getgroups in syscall_js.go
type returnSlice []interface{}
func (s returnSlice) invoke(context.Context, api.Module, ...interface{}) (interface{}, error) {
return &objectArray{slice: s}, nil
}