github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/gojs/process.go (about)

     1  package gojs
     2  
     3  import (
     4  	"context"
     5  	"path"
     6  
     7  	"github.com/bananabytelabs/wazero/api"
     8  	"github.com/bananabytelabs/wazero/experimental/sys"
     9  	"github.com/bananabytelabs/wazero/internal/gojs/custom"
    10  	"github.com/bananabytelabs/wazero/internal/gojs/goos"
    11  	"github.com/bananabytelabs/wazero/internal/gojs/util"
    12  )
    13  
    14  // processState are the mutable fields of the current process.
    15  type processState struct {
    16  	cwd   string
    17  	umask uint32
    18  }
    19  
    20  func newJsProcess(proc *processState) *jsVal {
    21  	// Fill fake values for user/group info as we don't support it.
    22  	uidRef := goos.RefValueZero
    23  	gidRef := goos.RefValueZero
    24  	euidRef := goos.RefValueZero
    25  	groupSlice := []interface{}{goos.RefValueZero}
    26  
    27  	// jsProcess = js.Global().Get("process") // fs_js.go init
    28  	return newJsVal(goos.RefJsProcess, custom.NameProcess).
    29  		addProperties(map[string]interface{}{
    30  			"pid":  float64(1),        // Get("pid").Int() in syscall_js.go for syscall.Getpid
    31  			"ppid": goos.RefValueZero, // Get("ppid").Int() in syscall_js.go for syscall.Getppid
    32  		}).
    33  		addFunction(custom.NameProcessCwd, &processCwd{proc: proc}).       // syscall.Cwd in fs_js.go
    34  		addFunction(custom.NameProcessChdir, &processChdir{proc: proc}).   // syscall.Chdir in fs_js.go
    35  		addFunction(custom.NameProcessGetuid, getId(uidRef)).              // syscall.Getuid in syscall_js.go
    36  		addFunction(custom.NameProcessGetgid, getId(gidRef)).              // syscall.Getgid in syscall_js.go
    37  		addFunction(custom.NameProcessGeteuid, getId(euidRef)).            // syscall.Geteuid in syscall_js.go
    38  		addFunction(custom.NameProcessGetgroups, returnSlice(groupSlice)). // syscall.Getgroups in syscall_js.go
    39  		addFunction(custom.NameProcessUmask, &processUmask{proc: proc})    // syscall.Umask in syscall_js.go
    40  }
    41  
    42  // processCwd implements jsFn for fs.Open syscall.Getcwd in fs_js.go
    43  type processCwd struct {
    44  	proc *processState
    45  }
    46  
    47  func (p *processCwd) invoke(_ context.Context, _ api.Module, _ ...interface{}) (interface{}, error) {
    48  	return p.proc.cwd, nil
    49  }
    50  
    51  // processChdir implements jsFn for fs.Open syscall.Chdir in fs_js.go
    52  type processChdir struct {
    53  	proc *processState
    54  }
    55  
    56  func (p *processChdir) invoke(_ context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
    57  	oldWd := p.proc.cwd
    58  	newWd := util.ResolvePath(oldWd, args[0].(string))
    59  
    60  	newWd = path.Clean(newWd)
    61  	if newWd == oldWd { // handle .
    62  		return nil, nil
    63  	}
    64  
    65  	if s, err := syscallStat(mod, newWd); err != nil {
    66  		return nil, err
    67  	} else if !s.isDir {
    68  		return nil, sys.ENOTDIR
    69  	} else {
    70  		p.proc.cwd = newWd
    71  		return nil, nil
    72  	}
    73  }
    74  
    75  // processUmask implements jsFn for fs.Open syscall.Umask in fs_js.go
    76  type processUmask struct {
    77  	proc *processState
    78  }
    79  
    80  func (p *processUmask) invoke(_ context.Context, _ api.Module, args ...interface{}) (interface{}, error) {
    81  	newUmask := goos.ValueToUint32(args[0])
    82  
    83  	oldUmask := p.proc.umask
    84  	p.proc.umask = newUmask
    85  
    86  	return oldUmask, nil
    87  }
    88  
    89  // getId implements jsFn for syscall.Getuid, syscall.Getgid and syscall.Geteuid in syscall_js.go
    90  type getId goos.Ref
    91  
    92  func (i getId) invoke(_ context.Context, _ api.Module, _ ...interface{}) (interface{}, error) {
    93  	return goos.Ref(i), nil
    94  }
    95  
    96  // returnSlice implements jsFn for syscall.Getgroups in syscall_js.go
    97  type returnSlice []interface{}
    98  
    99  func (s returnSlice) invoke(context.Context, api.Module, ...interface{}) (interface{}, error) {
   100  	return &objectArray{slice: s}, nil
   101  }