]> Cypherpunks.ru repositories - gostls13.git/blob - src/syscall/syscall_wasip1.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / syscall / syscall_wasip1.go
1 // Copyright 2023 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 wasip1
6
7 package syscall
8
9 import (
10         "errors"
11         "internal/itoa"
12         "internal/oserror"
13         "unsafe"
14 )
15
16 type Dircookie = uint64
17
18 type Filetype = uint8
19
20 const (
21         FILETYPE_UNKNOWN Filetype = iota
22         FILETYPE_BLOCK_DEVICE
23         FILETYPE_CHARACTER_DEVICE
24         FILETYPE_DIRECTORY
25         FILETYPE_REGULAR_FILE
26         FILETYPE_SOCKET_DGRAM
27         FILETYPE_SOCKET_STREAM
28         FILETYPE_SYMBOLIC_LINK
29 )
30
31 type Dirent struct {
32         // The offset of the next directory entry stored in this directory.
33         Next Dircookie
34         // The serial number of the file referred to by this directory entry.
35         Ino uint64
36         // The length of the name of the directory entry.
37         Namlen uint32
38         // The type of the file referred to by this directory entry.
39         Type Filetype
40         // Name of the directory entry.
41         Name *byte
42 }
43
44 func direntIno(buf []byte) (uint64, bool) {
45         return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
46 }
47
48 func direntReclen(buf []byte) (uint64, bool) {
49         namelen, ok := direntNamlen(buf)
50         return 24 + namelen, ok
51 }
52
53 func direntNamlen(buf []byte) (uint64, bool) {
54         return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
55 }
56
57 // An Errno is an unsigned number describing an error condition.
58 // It implements the error interface. The zero Errno is by convention
59 // a non-error, so code to convert from Errno to error should use:
60 //
61 //      var err = nil
62 //      if errno != 0 {
63 //              err = errno
64 //      }
65 type Errno uint32
66
67 func (e Errno) Error() string {
68         if 0 <= int(e) && int(e) < len(errorstr) {
69                 s := errorstr[e]
70                 if s != "" {
71                         return s
72                 }
73         }
74         return "errno " + itoa.Itoa(int(e))
75 }
76
77 func (e Errno) Is(target error) bool {
78         switch target {
79         case oserror.ErrPermission:
80                 return e == EACCES || e == EPERM
81         case oserror.ErrExist:
82                 return e == EEXIST || e == ENOTEMPTY
83         case oserror.ErrNotExist:
84                 return e == ENOENT
85         case errors.ErrUnsupported:
86                 return e == ENOSYS
87         }
88         return false
89 }
90
91 func (e Errno) Temporary() bool {
92         return e == EINTR || e == EMFILE || e.Timeout()
93 }
94
95 func (e Errno) Timeout() bool {
96         return e == EAGAIN || e == ETIMEDOUT
97 }
98
99 // A Signal is a number describing a process signal.
100 // It implements the os.Signal interface.
101 type Signal uint8
102
103 const (
104         SIGNONE Signal = iota
105         SIGHUP
106         SIGINT
107         SIGQUIT
108         SIGILL
109         SIGTRAP
110         SIGABRT
111         SIGBUS
112         SIGFPE
113         SIGKILL
114         SIGUSR1
115         SIGSEGV
116         SIGUSR2
117         SIGPIPE
118         SIGALRM
119         SIGTERM
120         SIGCHLD
121         SIGCONT
122         SIGSTOP
123         SIGTSTP
124         SIGTTIN
125         SIGTTOU
126         SIGURG
127         SIGXCPU
128         SIGXFSZ
129         SIGVTARLM
130         SIGPROF
131         SIGWINCH
132         SIGPOLL
133         SIGPWR
134         SIGSYS
135 )
136
137 func (s Signal) Signal() {}
138
139 func (s Signal) String() string {
140         switch s {
141         case SIGNONE:
142                 return "no signal"
143         case SIGHUP:
144                 return "hangup"
145         case SIGINT:
146                 return "interrupt"
147         case SIGQUIT:
148                 return "quit"
149         case SIGILL:
150                 return "illegal instruction"
151         case SIGTRAP:
152                 return "trace/breakpoint trap"
153         case SIGABRT:
154                 return "abort"
155         case SIGBUS:
156                 return "bus error"
157         case SIGFPE:
158                 return "floating point exception"
159         case SIGKILL:
160                 return "killed"
161         case SIGUSR1:
162                 return "user defined signal 1"
163         case SIGSEGV:
164                 return "segmentation fault"
165         case SIGUSR2:
166                 return "user defined signal 2"
167         case SIGPIPE:
168                 return "broken pipe"
169         case SIGALRM:
170                 return "alarm clock"
171         case SIGTERM:
172                 return "terminated"
173         case SIGCHLD:
174                 return "child exited"
175         case SIGCONT:
176                 return "continued"
177         case SIGSTOP:
178                 return "stopped (signal)"
179         case SIGTSTP:
180                 return "stopped"
181         case SIGTTIN:
182                 return "stopped (tty input)"
183         case SIGTTOU:
184                 return "stopped (tty output)"
185         case SIGURG:
186                 return "urgent I/O condition"
187         case SIGXCPU:
188                 return "CPU time limit exceeded"
189         case SIGXFSZ:
190                 return "file size limit exceeded"
191         case SIGVTARLM:
192                 return "virtual timer expired"
193         case SIGPROF:
194                 return "profiling timer expired"
195         case SIGWINCH:
196                 return "window changed"
197         case SIGPOLL:
198                 return "I/O possible"
199         case SIGPWR:
200                 return "power failure"
201         case SIGSYS:
202                 return "bad system call"
203         default:
204                 return "signal " + itoa.Itoa(int(s))
205         }
206 }
207
208 const (
209         Stdin  = 0
210         Stdout = 1
211         Stderr = 2
212 )
213
214 const (
215         O_RDONLY = 0
216         O_WRONLY = 1
217         O_RDWR   = 2
218
219         O_CREAT  = 0100
220         O_CREATE = O_CREAT
221         O_TRUNC  = 01000
222         O_APPEND = 02000
223         O_EXCL   = 0200
224         O_SYNC   = 010000
225
226         O_CLOEXEC = 0
227 )
228
229 const (
230         F_DUPFD   = 0
231         F_GETFD   = 1
232         F_SETFD   = 2
233         F_GETFL   = 3
234         F_SETFL   = 4
235         F_GETOWN  = 5
236         F_SETOWN  = 6
237         F_GETLK   = 7
238         F_SETLK   = 8
239         F_SETLKW  = 9
240         F_RGETLK  = 10
241         F_RSETLK  = 11
242         F_CNVT    = 12
243         F_RSETLKW = 13
244
245         F_RDLCK   = 1
246         F_WRLCK   = 2
247         F_UNLCK   = 3
248         F_UNLKSYS = 4
249 )
250
251 const (
252         S_IFMT        = 0000370000
253         S_IFSHM_SYSV  = 0000300000
254         S_IFSEMA      = 0000270000
255         S_IFCOND      = 0000260000
256         S_IFMUTEX     = 0000250000
257         S_IFSHM       = 0000240000
258         S_IFBOUNDSOCK = 0000230000
259         S_IFSOCKADDR  = 0000220000
260         S_IFDSOCK     = 0000210000
261
262         S_IFSOCK = 0000140000
263         S_IFLNK  = 0000120000
264         S_IFREG  = 0000100000
265         S_IFBLK  = 0000060000
266         S_IFDIR  = 0000040000
267         S_IFCHR  = 0000020000
268         S_IFIFO  = 0000010000
269
270         S_UNSUP = 0000370000
271
272         S_ISUID = 0004000
273         S_ISGID = 0002000
274         S_ISVTX = 0001000
275
276         S_IREAD  = 0400
277         S_IWRITE = 0200
278         S_IEXEC  = 0100
279
280         S_IRWXU = 0700
281         S_IRUSR = 0400
282         S_IWUSR = 0200
283         S_IXUSR = 0100
284
285         S_IRWXG = 070
286         S_IRGRP = 040
287         S_IWGRP = 020
288         S_IXGRP = 010
289
290         S_IRWXO = 07
291         S_IROTH = 04
292         S_IWOTH = 02
293         S_IXOTH = 01
294 )
295
296 type WaitStatus uint32
297
298 func (w WaitStatus) Exited() bool       { return false }
299 func (w WaitStatus) ExitStatus() int    { return 0 }
300 func (w WaitStatus) Signaled() bool     { return false }
301 func (w WaitStatus) Signal() Signal     { return 0 }
302 func (w WaitStatus) CoreDump() bool     { return false }
303 func (w WaitStatus) Stopped() bool      { return false }
304 func (w WaitStatus) Continued() bool    { return false }
305 func (w WaitStatus) StopSignal() Signal { return 0 }
306 func (w WaitStatus) TrapCause() int     { return 0 }
307
308 // Rusage is a placeholder to allow compilation of the os/exec package
309 // because we need Go programs to be portable across platforms. WASI does
310 // not have a mechanism to to spawn processes so there is no reason for an
311 // application to take a dependency on this type.
312 type Rusage struct {
313         Utime Timeval
314         Stime Timeval
315 }
316
317 // ProcAttr is a placeholder to allow compilation of the os/exec package
318 // because we need Go programs to be portable across platforms. WASI does
319 // not have a mechanism to to spawn processes so there is no reason for an
320 // application to take a dependency on this type.
321 type ProcAttr struct {
322         Dir   string
323         Env   []string
324         Files []uintptr
325         Sys   *SysProcAttr
326 }
327
328 type SysProcAttr struct {
329 }
330
331 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
332         return 0, 0, ENOSYS
333 }
334
335 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
336         return 0, 0, ENOSYS
337 }
338
339 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
340         return 0, 0, ENOSYS
341 }
342
343 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
344         return 0, 0, ENOSYS
345 }
346
347 func Sysctl(key string) (string, error) {
348         if key == "kern.hostname" {
349                 return "wasip1", nil
350         }
351         return "", ENOSYS
352 }
353
354 func Getuid() int {
355         return 1
356 }
357
358 func Getgid() int {
359         return 1
360 }
361
362 func Geteuid() int {
363         return 1
364 }
365
366 func Getegid() int {
367         return 1
368 }
369
370 func Getgroups() ([]int, error) {
371         return []int{1}, nil
372 }
373
374 func Getpid() int {
375         return 3
376 }
377
378 func Getppid() int {
379         return 2
380 }
381
382 func Gettimeofday(tv *Timeval) error {
383         var time timestamp
384         if errno := clock_time_get(clockRealtime, 1e3, unsafe.Pointer(&time)); errno != 0 {
385                 return errno
386         }
387         tv.setTimestamp(time)
388         return nil
389 }
390
391 func Kill(pid int, signum Signal) error {
392         // WASI does not have the notion of processes nor signal handlers.
393         //
394         // Any signal that the application raises to the process itself will
395         // be interpreted as being cause for termination.
396         if pid > 0 && pid != Getpid() {
397                 return ESRCH
398         }
399         ProcExit(128 + int32(signum))
400         return nil
401 }
402
403 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
404         return 0, ENOSYS
405 }
406
407 func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
408         return 0, 0, ENOSYS
409 }
410
411 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
412         return 0, ENOSYS
413 }
414
415 func Umask(mask int) int {
416         return 0
417 }
418
419 type Timespec struct {
420         Sec  int64
421         Nsec int64
422 }
423
424 func (ts *Timespec) timestamp() timestamp {
425         return timestamp(ts.Sec*1e9) + timestamp(ts.Nsec)
426 }
427
428 func (ts *Timespec) setTimestamp(t timestamp) {
429         ts.Sec = int64(t / 1e9)
430         ts.Nsec = int64(t % 1e9)
431 }
432
433 type Timeval struct {
434         Sec  int64
435         Usec int64
436 }
437
438 func (tv *Timeval) timestamp() timestamp {
439         return timestamp(tv.Sec*1e9) + timestamp(tv.Usec*1e3)
440 }
441
442 func (tv *Timeval) setTimestamp(t timestamp) {
443         tv.Sec = int64(t / 1e9)
444         tv.Usec = int64((t % 1e9) / 1e3)
445 }
446
447 func setTimespec(sec, nsec int64) Timespec {
448         return Timespec{Sec: sec, Nsec: nsec}
449 }
450
451 func setTimeval(sec, usec int64) Timeval {
452         return Timeval{Sec: sec, Usec: usec}
453 }
454
455 type clockid = uint32
456
457 const (
458         clockRealtime clockid = iota
459         clockMonotonic
460         clockProcessCPUTimeID
461         clockThreadCPUTimeID
462 )
463
464 //go:wasmimport wasi_snapshot_preview1 clock_time_get
465 //go:noescape
466 func clock_time_get(id clockid, precision timestamp, time unsafe.Pointer) Errno
467
468 func SetNonblock(fd int, nonblocking bool) error {
469         flags, err := fd_fdstat_get_flags(fd)
470         if err != nil {
471                 return err
472         }
473         if nonblocking {
474                 flags |= FDFLAG_NONBLOCK
475         } else {
476                 flags &^= FDFLAG_NONBLOCK
477         }
478         errno := fd_fdstat_set_flags(int32(fd), flags)
479         return errnoErr(errno)
480 }
481
482 type Rlimit struct {
483         Cur uint64
484         Max uint64
485 }
486
487 const (
488         RLIMIT_NOFILE = iota
489 )
490
491 func Getrlimit(which int, lim *Rlimit) error {
492         return ENOSYS
493 }