Source file src/syscall/syscall_js.go

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build js && wasm
     6  
     7  package syscall
     8  
     9  import (
    10  	errorspkg "errors"
    11  	"internal/itoa"
    12  	"internal/oserror"
    13  	"sync"
    14  	"unsafe"
    15  )
    16  
    17  const direntSize = 8 + 8 + 2 + 256
    18  
    19  type Dirent struct {
    20  	Reclen uint16
    21  	Name   [256]byte
    22  }
    23  
    24  func direntIno(buf []byte) (uint64, bool) {
    25  	return 1, true
    26  }
    27  
    28  func direntReclen(buf []byte) (uint64, bool) {
    29  	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
    30  }
    31  
    32  func direntNamlen(buf []byte) (uint64, bool) {
    33  	reclen, ok := direntReclen(buf)
    34  	if !ok {
    35  		return 0, false
    36  	}
    37  	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
    38  }
    39  
    40  const PathMax = 256
    41  
    42  // An Errno is an unsigned number describing an error condition.
    43  // It implements the error interface. The zero Errno is by convention
    44  // a non-error, so code to convert from Errno to error should use:
    45  //
    46  //	err = nil
    47  //	if errno != 0 {
    48  //		err = errno
    49  //	}
    50  //
    51  // Errno values can be tested against error values using [errors.Is].
    52  // For example:
    53  //
    54  //	_, _, err := syscall.Syscall(...)
    55  //	if errors.Is(err, fs.ErrNotExist) ...
    56  type Errno uintptr
    57  
    58  func (e Errno) Error() string {
    59  	if 0 <= int(e) && int(e) < len(errorstr) {
    60  		s := errorstr[e]
    61  		if s != "" {
    62  			return s
    63  		}
    64  	}
    65  	return "errno " + itoa.Itoa(int(e))
    66  }
    67  
    68  func (e Errno) Is(target error) bool {
    69  	switch target {
    70  	case oserror.ErrPermission:
    71  		return e == EACCES || e == EPERM
    72  	case oserror.ErrExist:
    73  		return e == EEXIST || e == ENOTEMPTY
    74  	case oserror.ErrNotExist:
    75  		return e == ENOENT
    76  	case errorspkg.ErrUnsupported:
    77  		return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP
    78  	}
    79  	return false
    80  }
    81  
    82  func (e Errno) Temporary() bool {
    83  	return e == EINTR || e == EMFILE || e.Timeout()
    84  }
    85  
    86  func (e Errno) Timeout() bool {
    87  	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
    88  }
    89  
    90  // A Signal is a number describing a process signal.
    91  // It implements the [os.Signal] interface.
    92  type Signal int
    93  
    94  const (
    95  	_ Signal = iota
    96  	SIGCHLD
    97  	SIGINT
    98  	SIGKILL
    99  	SIGTRAP
   100  	SIGQUIT
   101  	SIGTERM
   102  )
   103  
   104  func (s Signal) Signal() {}
   105  
   106  func (s Signal) String() string {
   107  	if 0 <= s && int(s) < len(signals) {
   108  		str := signals[s]
   109  		if str != "" {
   110  			return str
   111  		}
   112  	}
   113  	return "signal " + itoa.Itoa(int(s))
   114  }
   115  
   116  var signals = [...]string{}
   117  
   118  // File system
   119  
   120  const (
   121  	Stdin  = 0
   122  	Stdout = 1
   123  	Stderr = 2
   124  )
   125  
   126  const (
   127  	O_RDONLY = 0
   128  	O_WRONLY = 1
   129  	O_RDWR   = 2
   130  
   131  	O_CREAT     = 0100
   132  	O_CREATE    = O_CREAT
   133  	O_TRUNC     = 01000
   134  	O_APPEND    = 02000
   135  	O_EXCL      = 0200
   136  	O_SYNC      = 010000
   137  	O_DIRECTORY = 020000
   138  
   139  	O_CLOEXEC = 0
   140  )
   141  
   142  const (
   143  	F_DUPFD   = 0
   144  	F_GETFD   = 1
   145  	F_SETFD   = 2
   146  	F_GETFL   = 3
   147  	F_SETFL   = 4
   148  	F_GETOWN  = 5
   149  	F_SETOWN  = 6
   150  	F_GETLK   = 7
   151  	F_SETLK   = 8
   152  	F_SETLKW  = 9
   153  	F_RGETLK  = 10
   154  	F_RSETLK  = 11
   155  	F_CNVT    = 12
   156  	F_RSETLKW = 13
   157  
   158  	F_RDLCK   = 1
   159  	F_WRLCK   = 2
   160  	F_UNLCK   = 3
   161  	F_UNLKSYS = 4
   162  )
   163  
   164  const (
   165  	S_IFMT        = 0000370000
   166  	S_IFSHM_SYSV  = 0000300000
   167  	S_IFSEMA      = 0000270000
   168  	S_IFCOND      = 0000260000
   169  	S_IFMUTEX     = 0000250000
   170  	S_IFSHM       = 0000240000
   171  	S_IFBOUNDSOCK = 0000230000
   172  	S_IFSOCKADDR  = 0000220000
   173  	S_IFDSOCK     = 0000210000
   174  
   175  	S_IFSOCK = 0000140000
   176  	S_IFLNK  = 0000120000
   177  	S_IFREG  = 0000100000
   178  	S_IFBLK  = 0000060000
   179  	S_IFDIR  = 0000040000
   180  	S_IFCHR  = 0000020000
   181  	S_IFIFO  = 0000010000
   182  
   183  	S_UNSUP = 0000370000
   184  
   185  	S_ISUID = 0004000
   186  	S_ISGID = 0002000
   187  	S_ISVTX = 0001000
   188  
   189  	S_IREAD  = 0400
   190  	S_IWRITE = 0200
   191  	S_IEXEC  = 0100
   192  
   193  	S_IRWXU = 0700
   194  	S_IRUSR = 0400
   195  	S_IWUSR = 0200
   196  	S_IXUSR = 0100
   197  
   198  	S_IRWXG = 070
   199  	S_IRGRP = 040
   200  	S_IWGRP = 020
   201  	S_IXGRP = 010
   202  
   203  	S_IRWXO = 07
   204  	S_IROTH = 04
   205  	S_IWOTH = 02
   206  	S_IXOTH = 01
   207  )
   208  
   209  type Stat_t struct {
   210  	Dev       int64
   211  	Ino       uint64
   212  	Mode      uint32
   213  	Nlink     uint32
   214  	Uid       uint32
   215  	Gid       uint32
   216  	Rdev      int64
   217  	Size      int64
   218  	Blksize   int32
   219  	Blocks    int32
   220  	Atime     int64
   221  	AtimeNsec int64
   222  	Mtime     int64
   223  	MtimeNsec int64
   224  	Ctime     int64
   225  	CtimeNsec int64
   226  }
   227  
   228  // Processes
   229  // Not supported - just enough for package os.
   230  
   231  var ForkLock sync.RWMutex
   232  
   233  type WaitStatus uint32
   234  
   235  func (w WaitStatus) Exited() bool       { return false }
   236  func (w WaitStatus) ExitStatus() int    { return 0 }
   237  func (w WaitStatus) Signaled() bool     { return false }
   238  func (w WaitStatus) Signal() Signal     { return 0 }
   239  func (w WaitStatus) CoreDump() bool     { return false }
   240  func (w WaitStatus) Stopped() bool      { return false }
   241  func (w WaitStatus) Continued() bool    { return false }
   242  func (w WaitStatus) StopSignal() Signal { return 0 }
   243  func (w WaitStatus) TrapCause() int     { return 0 }
   244  
   245  // XXX made up
   246  type Rusage struct {
   247  	Utime Timeval
   248  	Stime Timeval
   249  }
   250  
   251  // XXX made up
   252  type ProcAttr struct {
   253  	Dir   string
   254  	Env   []string
   255  	Files []uintptr
   256  	Sys   *SysProcAttr
   257  }
   258  
   259  type SysProcAttr struct {
   260  }
   261  
   262  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
   263  	return 0, 0, ENOSYS
   264  }
   265  
   266  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
   267  	return 0, 0, ENOSYS
   268  }
   269  
   270  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
   271  	return 0, 0, ENOSYS
   272  }
   273  
   274  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
   275  	return 0, 0, ENOSYS
   276  }
   277  
   278  func Sysctl(key string) (string, error) {
   279  	if key == "kern.hostname" {
   280  		return "js", nil
   281  	}
   282  	return "", ENOSYS
   283  }
   284  
   285  const ImplementsGetwd = true
   286  
   287  func Getwd() (wd string, err error) {
   288  	var buf [PathMax]byte
   289  	n, err := Getcwd(buf[0:])
   290  	if err != nil {
   291  		return "", err
   292  	}
   293  	return string(buf[:n]), nil
   294  }
   295  
   296  func Getuid() int {
   297  	return jsProcess.Call("getuid").Int()
   298  }
   299  
   300  func Getgid() int {
   301  	return jsProcess.Call("getgid").Int()
   302  }
   303  
   304  func Geteuid() int {
   305  	return jsProcess.Call("geteuid").Int()
   306  }
   307  
   308  func Getegid() int {
   309  	return jsProcess.Call("getegid").Int()
   310  }
   311  
   312  func Getgroups() (groups []int, err error) {
   313  	defer recoverErr(&err)
   314  	array := jsProcess.Call("getgroups")
   315  	groups = make([]int, array.Length())
   316  	for i := range groups {
   317  		groups[i] = array.Index(i).Int()
   318  	}
   319  	return groups, nil
   320  }
   321  
   322  func Getpid() int {
   323  	return jsProcess.Get("pid").Int()
   324  }
   325  
   326  func Getppid() int {
   327  	return jsProcess.Get("ppid").Int()
   328  }
   329  
   330  func Umask(mask int) (oldmask int) {
   331  	return jsProcess.Call("umask", mask).Int()
   332  }
   333  
   334  func Gettimeofday(tv *Timeval) error { return ENOSYS }
   335  
   336  func Kill(pid int, signum Signal) error { return ENOSYS }
   337  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   338  	return 0, ENOSYS
   339  }
   340  func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
   341  	return 0, 0, ENOSYS
   342  }
   343  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
   344  	return 0, ENOSYS
   345  }
   346  
   347  type Iovec struct{} // dummy
   348  
   349  type Timespec struct {
   350  	Sec  int64
   351  	Nsec int64
   352  }
   353  
   354  type Timeval struct {
   355  	Sec  int64
   356  	Usec int64
   357  }
   358  
   359  func setTimespec(sec, nsec int64) Timespec {
   360  	return Timespec{Sec: sec, Nsec: nsec}
   361  }
   362  
   363  func setTimeval(sec, usec int64) Timeval {
   364  	return Timeval{Sec: sec, Usec: usec}
   365  }
   366  

View as plain text