github.com/tetratelabs/wazero@v1.2.1/internal/gojs/process.go (about)

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