github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/syscall/syscall_wasip1.go (about) 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 }