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

View as plain text