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  
   138  	O_CLOEXEC = 0
   139  )
   140  
   141  const (
   142  	F_DUPFD   = 0
   143  	F_GETFD   = 1
   144  	F_SETFD   = 2
   145  	F_GETFL   = 3
   146  	F_SETFL   = 4
   147  	F_GETOWN  = 5
   148  	F_SETOWN  = 6
   149  	F_GETLK   = 7
   150  	F_SETLK   = 8
   151  	F_SETLKW  = 9
   152  	F_RGETLK  = 10
   153  	F_RSETLK  = 11
   154  	F_CNVT    = 12
   155  	F_RSETLKW = 13
   156  
   157  	F_RDLCK   = 1
   158  	F_WRLCK   = 2
   159  	F_UNLCK   = 3
   160  	F_UNLKSYS = 4
   161  )
   162  
   163  const (
   164  	S_IFMT        = 0000370000
   165  	S_IFSHM_SYSV  = 0000300000
   166  	S_IFSEMA      = 0000270000
   167  	S_IFCOND      = 0000260000
   168  	S_IFMUTEX     = 0000250000
   169  	S_IFSHM       = 0000240000
   170  	S_IFBOUNDSOCK = 0000230000
   171  	S_IFSOCKADDR  = 0000220000
   172  	S_IFDSOCK     = 0000210000
   173  
   174  	S_IFSOCK = 0000140000
   175  	S_IFLNK  = 0000120000
   176  	S_IFREG  = 0000100000
   177  	S_IFBLK  = 0000060000
   178  	S_IFDIR  = 0000040000
   179  	S_IFCHR  = 0000020000
   180  	S_IFIFO  = 0000010000
   181  
   182  	S_UNSUP = 0000370000
   183  
   184  	S_ISUID = 0004000
   185  	S_ISGID = 0002000
   186  	S_ISVTX = 0001000
   187  
   188  	S_IREAD  = 0400
   189  	S_IWRITE = 0200
   190  	S_IEXEC  = 0100
   191  
   192  	S_IRWXU = 0700
   193  	S_IRUSR = 0400
   194  	S_IWUSR = 0200
   195  	S_IXUSR = 0100
   196  
   197  	S_IRWXG = 070
   198  	S_IRGRP = 040
   199  	S_IWGRP = 020
   200  	S_IXGRP = 010
   201  
   202  	S_IRWXO = 07
   203  	S_IROTH = 04
   204  	S_IWOTH = 02
   205  	S_IXOTH = 01
   206  )
   207  
   208  type Stat_t struct {
   209  	Dev       int64
   210  	Ino       uint64
   211  	Mode      uint32
   212  	Nlink     uint32
   213  	Uid       uint32
   214  	Gid       uint32
   215  	Rdev      int64
   216  	Size      int64
   217  	Blksize   int32
   218  	Blocks    int32
   219  	Atime     int64
   220  	AtimeNsec int64
   221  	Mtime     int64
   222  	MtimeNsec int64
   223  	Ctime     int64
   224  	CtimeNsec int64
   225  }
   226  
   227  // Processes
   228  // Not supported - just enough for package os.
   229  
   230  var ForkLock sync.RWMutex
   231  
   232  type WaitStatus uint32
   233  
   234  func (w WaitStatus) Exited() bool       { return false }
   235  func (w WaitStatus) ExitStatus() int    { return 0 }
   236  func (w WaitStatus) Signaled() bool     { return false }
   237  func (w WaitStatus) Signal() Signal     { return 0 }
   238  func (w WaitStatus) CoreDump() bool     { return false }
   239  func (w WaitStatus) Stopped() bool      { return false }
   240  func (w WaitStatus) Continued() bool    { return false }
   241  func (w WaitStatus) StopSignal() Signal { return 0 }
   242  func (w WaitStatus) TrapCause() int     { return 0 }
   243  
   244  // XXX made up
   245  type Rusage struct {
   246  	Utime Timeval
   247  	Stime Timeval
   248  }
   249  
   250  // XXX made up
   251  type ProcAttr struct {
   252  	Dir   string
   253  	Env   []string
   254  	Files []uintptr
   255  	Sys   *SysProcAttr
   256  }
   257  
   258  type SysProcAttr struct {
   259  }
   260  
   261  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
   262  	return 0, 0, ENOSYS
   263  }
   264  
   265  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
   266  	return 0, 0, ENOSYS
   267  }
   268  
   269  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
   270  	return 0, 0, ENOSYS
   271  }
   272  
   273  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
   274  	return 0, 0, ENOSYS
   275  }
   276  
   277  func Sysctl(key string) (string, error) {
   278  	if key == "kern.hostname" {
   279  		return "js", nil
   280  	}
   281  	return "", ENOSYS
   282  }
   283  
   284  const ImplementsGetwd = true
   285  
   286  func Getwd() (wd string, err error) {
   287  	var buf [PathMax]byte
   288  	n, err := Getcwd(buf[0:])
   289  	if err != nil {
   290  		return "", err
   291  	}
   292  	return string(buf[:n]), nil
   293  }
   294  
   295  func Getuid() int {
   296  	return jsProcess.Call("getuid").Int()
   297  }
   298  
   299  func Getgid() int {
   300  	return jsProcess.Call("getgid").Int()
   301  }
   302  
   303  func Geteuid() int {
   304  	return jsProcess.Call("geteuid").Int()
   305  }
   306  
   307  func Getegid() int {
   308  	return jsProcess.Call("getegid").Int()
   309  }
   310  
   311  func Getgroups() (groups []int, err error) {
   312  	defer recoverErr(&err)
   313  	array := jsProcess.Call("getgroups")
   314  	groups = make([]int, array.Length())
   315  	for i := range groups {
   316  		groups[i] = array.Index(i).Int()
   317  	}
   318  	return groups, nil
   319  }
   320  
   321  func Getpid() int {
   322  	return jsProcess.Get("pid").Int()
   323  }
   324  
   325  func Getppid() int {
   326  	return jsProcess.Get("ppid").Int()
   327  }
   328  
   329  func Umask(mask int) (oldmask int) {
   330  	return jsProcess.Call("umask", mask).Int()
   331  }
   332  
   333  func Gettimeofday(tv *Timeval) error { return ENOSYS }
   334  
   335  func Kill(pid int, signum Signal) error { return ENOSYS }
   336  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   337  	return 0, ENOSYS
   338  }
   339  func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
   340  	return 0, 0, ENOSYS
   341  }
   342  func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
   343  	return 0, ENOSYS
   344  }
   345  
   346  type Iovec struct{} // dummy
   347  
   348  type Timespec struct {
   349  	Sec  int64
   350  	Nsec int64
   351  }
   352  
   353  type Timeval struct {
   354  	Sec  int64
   355  	Usec int64
   356  }
   357  
   358  func setTimespec(sec, nsec int64) Timespec {
   359  	return Timespec{Sec: sec, Nsec: nsec}
   360  }
   361  
   362  func setTimeval(sec, usec int64) Timeval {
   363  	return Timeval{Sec: sec, Usec: usec}
   364  }
   365  

View as plain text