|  | // Copyright 2018 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | //go:build js && wasm | 
|  |  | 
|  | package syscall | 
|  |  | 
|  | import ( | 
|  | "internal/itoa" | 
|  | "internal/oserror" | 
|  | "sync" | 
|  | "unsafe" | 
|  | ) | 
|  |  | 
|  | const direntSize = 8 + 8 + 2 + 256 | 
|  |  | 
|  | type Dirent struct { | 
|  | Reclen uint16 | 
|  | Name   [256]byte | 
|  | } | 
|  |  | 
|  | func direntIno(buf []byte) (uint64, bool) { | 
|  | return 1, true | 
|  | } | 
|  |  | 
|  | func direntReclen(buf []byte) (uint64, bool) { | 
|  | return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) | 
|  | } | 
|  |  | 
|  | func direntNamlen(buf []byte) (uint64, bool) { | 
|  | reclen, ok := direntReclen(buf) | 
|  | if !ok { | 
|  | return 0, false | 
|  | } | 
|  | return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true | 
|  | } | 
|  |  | 
|  | const PathMax = 256 | 
|  |  | 
|  | // An Errno is an unsigned number describing an error condition. | 
|  | // It implements the error interface. The zero Errno is by convention | 
|  | // a non-error, so code to convert from Errno to error should use: | 
|  | // | 
|  | //	err = nil | 
|  | //	if errno != 0 { | 
|  | //		err = errno | 
|  | //	} | 
|  | // | 
|  | // Errno values can be tested against error values from the os package | 
|  | // using errors.Is. For example: | 
|  | // | 
|  | //	_, _, err := syscall.Syscall(...) | 
|  | //	if errors.Is(err, fs.ErrNotExist) ... | 
|  | type Errno uintptr | 
|  |  | 
|  | func (e Errno) Error() string { | 
|  | if 0 <= int(e) && int(e) < len(errorstr) { | 
|  | s := errorstr[e] | 
|  | if s != "" { | 
|  | return s | 
|  | } | 
|  | } | 
|  | return "errno " + itoa.Itoa(int(e)) | 
|  | } | 
|  |  | 
|  | func (e Errno) Is(target error) bool { | 
|  | switch target { | 
|  | case oserror.ErrPermission: | 
|  | return e == EACCES || e == EPERM | 
|  | case oserror.ErrExist: | 
|  | return e == EEXIST || e == ENOTEMPTY | 
|  | case oserror.ErrNotExist: | 
|  | return e == ENOENT | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (e Errno) Temporary() bool { | 
|  | return e == EINTR || e == EMFILE || e.Timeout() | 
|  | } | 
|  |  | 
|  | func (e Errno) Timeout() bool { | 
|  | return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT | 
|  | } | 
|  |  | 
|  | // A Signal is a number describing a process signal. | 
|  | // It implements the os.Signal interface. | 
|  | type Signal int | 
|  |  | 
|  | const ( | 
|  | _ Signal = iota | 
|  | SIGCHLD | 
|  | SIGINT | 
|  | SIGKILL | 
|  | SIGTRAP | 
|  | SIGQUIT | 
|  | SIGTERM | 
|  | ) | 
|  |  | 
|  | func (s Signal) Signal() {} | 
|  |  | 
|  | func (s Signal) String() string { | 
|  | if 0 <= s && int(s) < len(signals) { | 
|  | str := signals[s] | 
|  | if str != "" { | 
|  | return str | 
|  | } | 
|  | } | 
|  | return "signal " + itoa.Itoa(int(s)) | 
|  | } | 
|  |  | 
|  | var signals = [...]string{} | 
|  |  | 
|  | // File system | 
|  |  | 
|  | const ( | 
|  | Stdin  = 0 | 
|  | Stdout = 1 | 
|  | Stderr = 2 | 
|  | ) | 
|  |  | 
|  | const ( | 
|  | O_RDONLY = 0 | 
|  | O_WRONLY = 1 | 
|  | O_RDWR   = 2 | 
|  |  | 
|  | O_CREAT  = 0100 | 
|  | O_CREATE = O_CREAT | 
|  | O_TRUNC  = 01000 | 
|  | O_APPEND = 02000 | 
|  | O_EXCL   = 0200 | 
|  | O_SYNC   = 010000 | 
|  |  | 
|  | O_CLOEXEC = 0 | 
|  | ) | 
|  |  | 
|  | const ( | 
|  | F_DUPFD   = 0 | 
|  | F_GETFD   = 1 | 
|  | F_SETFD   = 2 | 
|  | F_GETFL   = 3 | 
|  | F_SETFL   = 4 | 
|  | F_GETOWN  = 5 | 
|  | F_SETOWN  = 6 | 
|  | F_GETLK   = 7 | 
|  | F_SETLK   = 8 | 
|  | F_SETLKW  = 9 | 
|  | F_RGETLK  = 10 | 
|  | F_RSETLK  = 11 | 
|  | F_CNVT    = 12 | 
|  | F_RSETLKW = 13 | 
|  |  | 
|  | F_RDLCK   = 1 | 
|  | F_WRLCK   = 2 | 
|  | F_UNLCK   = 3 | 
|  | F_UNLKSYS = 4 | 
|  | ) | 
|  |  | 
|  | const ( | 
|  | S_IFMT        = 0000370000 | 
|  | S_IFSHM_SYSV  = 0000300000 | 
|  | S_IFSEMA      = 0000270000 | 
|  | S_IFCOND      = 0000260000 | 
|  | S_IFMUTEX     = 0000250000 | 
|  | S_IFSHM       = 0000240000 | 
|  | S_IFBOUNDSOCK = 0000230000 | 
|  | S_IFSOCKADDR  = 0000220000 | 
|  | S_IFDSOCK     = 0000210000 | 
|  |  | 
|  | S_IFSOCK = 0000140000 | 
|  | S_IFLNK  = 0000120000 | 
|  | S_IFREG  = 0000100000 | 
|  | S_IFBLK  = 0000060000 | 
|  | S_IFDIR  = 0000040000 | 
|  | S_IFCHR  = 0000020000 | 
|  | S_IFIFO  = 0000010000 | 
|  |  | 
|  | S_UNSUP = 0000370000 | 
|  |  | 
|  | S_ISUID = 0004000 | 
|  | S_ISGID = 0002000 | 
|  | S_ISVTX = 0001000 | 
|  |  | 
|  | S_IREAD  = 0400 | 
|  | S_IWRITE = 0200 | 
|  | S_IEXEC  = 0100 | 
|  |  | 
|  | S_IRWXU = 0700 | 
|  | S_IRUSR = 0400 | 
|  | S_IWUSR = 0200 | 
|  | S_IXUSR = 0100 | 
|  |  | 
|  | S_IRWXG = 070 | 
|  | S_IRGRP = 040 | 
|  | S_IWGRP = 020 | 
|  | S_IXGRP = 010 | 
|  |  | 
|  | S_IRWXO = 07 | 
|  | S_IROTH = 04 | 
|  | S_IWOTH = 02 | 
|  | S_IXOTH = 01 | 
|  | ) | 
|  |  | 
|  | type Stat_t struct { | 
|  | Dev       int64 | 
|  | Ino       uint64 | 
|  | Mode      uint32 | 
|  | Nlink     uint32 | 
|  | Uid       uint32 | 
|  | Gid       uint32 | 
|  | Rdev      int64 | 
|  | Size      int64 | 
|  | Blksize   int32 | 
|  | Blocks    int32 | 
|  | Atime     int64 | 
|  | AtimeNsec int64 | 
|  | Mtime     int64 | 
|  | MtimeNsec int64 | 
|  | Ctime     int64 | 
|  | CtimeNsec int64 | 
|  | } | 
|  |  | 
|  | // Processes | 
|  | // Not supported - just enough for package os. | 
|  |  | 
|  | var ForkLock sync.RWMutex | 
|  |  | 
|  | type WaitStatus uint32 | 
|  |  | 
|  | func (w WaitStatus) Exited() bool       { return false } | 
|  | func (w WaitStatus) ExitStatus() int    { return 0 } | 
|  | func (w WaitStatus) Signaled() bool     { return false } | 
|  | func (w WaitStatus) Signal() Signal     { return 0 } | 
|  | func (w WaitStatus) CoreDump() bool     { return false } | 
|  | func (w WaitStatus) Stopped() bool      { return false } | 
|  | func (w WaitStatus) Continued() bool    { return false } | 
|  | func (w WaitStatus) StopSignal() Signal { return 0 } | 
|  | func (w WaitStatus) TrapCause() int     { return 0 } | 
|  |  | 
|  | // XXX made up | 
|  | type Rusage struct { | 
|  | Utime Timeval | 
|  | Stime Timeval | 
|  | } | 
|  |  | 
|  | // XXX made up | 
|  | type ProcAttr struct { | 
|  | Dir   string | 
|  | Env   []string | 
|  | Files []uintptr | 
|  | Sys   *SysProcAttr | 
|  | } | 
|  |  | 
|  | type SysProcAttr struct { | 
|  | } | 
|  |  | 
|  | func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { | 
|  | return 0, 0, ENOSYS | 
|  | } | 
|  |  | 
|  | func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { | 
|  | return 0, 0, ENOSYS | 
|  | } | 
|  |  | 
|  | func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { | 
|  | return 0, 0, ENOSYS | 
|  | } | 
|  |  | 
|  | func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { | 
|  | return 0, 0, ENOSYS | 
|  | } | 
|  |  | 
|  | func Sysctl(key string) (string, error) { | 
|  | if key == "kern.hostname" { | 
|  | return "js", nil | 
|  | } | 
|  | return "", ENOSYS | 
|  | } | 
|  |  | 
|  | const ImplementsGetwd = true | 
|  |  | 
|  | func Getwd() (wd string, err error) { | 
|  | var buf [PathMax]byte | 
|  | n, err := Getcwd(buf[0:]) | 
|  | if err != nil { | 
|  | return "", err | 
|  | } | 
|  | return string(buf[:n]), nil | 
|  | } | 
|  |  | 
|  | func Getuid() int { | 
|  | return jsProcess.Call("getuid").Int() | 
|  | } | 
|  |  | 
|  | func Getgid() int { | 
|  | return jsProcess.Call("getgid").Int() | 
|  | } | 
|  |  | 
|  | func Geteuid() int { | 
|  | return jsProcess.Call("geteuid").Int() | 
|  | } | 
|  |  | 
|  | func Getegid() int { | 
|  | return jsProcess.Call("getegid").Int() | 
|  | } | 
|  |  | 
|  | func Getgroups() (groups []int, err error) { | 
|  | defer recoverErr(&err) | 
|  | array := jsProcess.Call("getgroups") | 
|  | groups = make([]int, array.Length()) | 
|  | for i := range groups { | 
|  | groups[i] = array.Index(i).Int() | 
|  | } | 
|  | return groups, nil | 
|  | } | 
|  |  | 
|  | func Getpid() int { | 
|  | return jsProcess.Get("pid").Int() | 
|  | } | 
|  |  | 
|  | func Getppid() int { | 
|  | return jsProcess.Get("ppid").Int() | 
|  | } | 
|  |  | 
|  | func Umask(mask int) (oldmask int) { | 
|  | return jsProcess.Call("umask", mask).Int() | 
|  | } | 
|  |  | 
|  | func Gettimeofday(tv *Timeval) error { return ENOSYS } | 
|  |  | 
|  | func Kill(pid int, signum Signal) error { return ENOSYS } | 
|  | func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | 
|  | return 0, ENOSYS | 
|  | } | 
|  | func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { | 
|  | return 0, 0, ENOSYS | 
|  | } | 
|  | func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { | 
|  | return 0, ENOSYS | 
|  | } | 
|  |  | 
|  | type Iovec struct{} // dummy | 
|  |  | 
|  | type Timespec struct { | 
|  | Sec  int64 | 
|  | Nsec int64 | 
|  | } | 
|  |  | 
|  | type Timeval struct { | 
|  | Sec  int64 | 
|  | Usec int64 | 
|  | } | 
|  |  | 
|  | func setTimespec(sec, nsec int64) Timespec { | 
|  | return Timespec{Sec: sec, Nsec: nsec} | 
|  | } | 
|  |  | 
|  | func setTimeval(sec, usec int64) Timeval { | 
|  | return Timeval{Sec: sec, Usec: usec} | 
|  | } |