| // 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 ( | |
| errorspkg "errors" | |
| "internal/oserror" | |
| "internal/strconv" | |
| "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 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 " + strconv.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 | |
| case errorspkg.ErrUnsupported: | |
| return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP | |
| } | |
| 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 " + strconv.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_DIRECTORY = 020000 | |
| 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} | |
| } |