• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
7package syscall
8
9import (
10	errorspkg "errors"
11	"internal/itoa"
12	"internal/oserror"
13	"sync"
14	"unsafe"
15)
16
17const direntSize = 8 + 8 + 2 + 256
18
19type Dirent struct {
20	Reclen uint16
21	Name   [256]byte
22}
23
24func direntIno(buf []byte) (uint64, bool) {
25	return 1, true
26}
27
28func direntReclen(buf []byte) (uint64, bool) {
29	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
30}
31
32func 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
40const 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) ...
56type Errno uintptr
57
58func (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
68func (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
82func (e Errno) Temporary() bool {
83	return e == EINTR || e == EMFILE || e.Timeout()
84}
85
86func (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.
92type Signal int
93
94const (
95	_ Signal = iota
96	SIGCHLD
97	SIGINT
98	SIGKILL
99	SIGTRAP
100	SIGQUIT
101	SIGTERM
102)
103
104func (s Signal) Signal() {}
105
106func (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
116var signals = [...]string{}
117
118// File system
119
120const (
121	Stdin  = 0
122	Stdout = 1
123	Stderr = 2
124)
125
126const (
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
141const (
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
163const (
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
208type 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
230var ForkLock sync.RWMutex
231
232type WaitStatus uint32
233
234func (w WaitStatus) Exited() bool       { return false }
235func (w WaitStatus) ExitStatus() int    { return 0 }
236func (w WaitStatus) Signaled() bool     { return false }
237func (w WaitStatus) Signal() Signal     { return 0 }
238func (w WaitStatus) CoreDump() bool     { return false }
239func (w WaitStatus) Stopped() bool      { return false }
240func (w WaitStatus) Continued() bool    { return false }
241func (w WaitStatus) StopSignal() Signal { return 0 }
242func (w WaitStatus) TrapCause() int     { return 0 }
243
244// XXX made up
245type Rusage struct {
246	Utime Timeval
247	Stime Timeval
248}
249
250// XXX made up
251type ProcAttr struct {
252	Dir   string
253	Env   []string
254	Files []uintptr
255	Sys   *SysProcAttr
256}
257
258type SysProcAttr struct {
259}
260
261func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
262	return 0, 0, ENOSYS
263}
264
265func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
266	return 0, 0, ENOSYS
267}
268
269func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
270	return 0, 0, ENOSYS
271}
272
273func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
274	return 0, 0, ENOSYS
275}
276
277func Sysctl(key string) (string, error) {
278	if key == "kern.hostname" {
279		return "js", nil
280	}
281	return "", ENOSYS
282}
283
284const ImplementsGetwd = true
285
286func 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
295func Getuid() int {
296	return jsProcess.Call("getuid").Int()
297}
298
299func Getgid() int {
300	return jsProcess.Call("getgid").Int()
301}
302
303func Geteuid() int {
304	return jsProcess.Call("geteuid").Int()
305}
306
307func Getegid() int {
308	return jsProcess.Call("getegid").Int()
309}
310
311func 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
321func Getpid() int {
322	return jsProcess.Get("pid").Int()
323}
324
325func Getppid() int {
326	return jsProcess.Get("ppid").Int()
327}
328
329func Umask(mask int) (oldmask int) {
330	return jsProcess.Call("umask", mask).Int()
331}
332
333func Gettimeofday(tv *Timeval) error { return ENOSYS }
334
335func Kill(pid int, signum Signal) error { return ENOSYS }
336func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
337	return 0, ENOSYS
338}
339func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
340	return 0, 0, ENOSYS
341}
342func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
343	return 0, ENOSYS
344}
345
346type Iovec struct{} // dummy
347
348type Timespec struct {
349	Sec  int64
350	Nsec int64
351}
352
353type Timeval struct {
354	Sec  int64
355	Usec int64
356}
357
358func setTimespec(sec, nsec int64) Timespec {
359	return Timespec{Sec: sec, Nsec: nsec}
360}
361
362func setTimeval(sec, usec int64) Timeval {
363	return Timeval{Sec: sec, Usec: usec}
364}
365