318 lines
7.2 KiB
Go
318 lines
7.2 KiB
Go
// Copyright 2023 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 wasip1
|
|
|
|
package syscall
|
|
|
|
import (
|
|
"structs"
|
|
)
|
|
|
|
func init() {
|
|
// Try to set stdio to non-blocking mode before the os package
|
|
// calls NewFile for each fd. NewFile queries the non-blocking flag
|
|
// but doesn't change it, even if the runtime supports non-blocking
|
|
// stdio. Since WebAssembly modules are single-threaded, blocking
|
|
// system calls temporarily halt execution of the module. If the
|
|
// runtime supports non-blocking stdio, the Go runtime is able to
|
|
// use the WASI net poller to poll for read/write readiness and is
|
|
// able to schedule goroutines while waiting.
|
|
SetNonblock(0, true)
|
|
SetNonblock(1, true)
|
|
SetNonblock(2, true)
|
|
}
|
|
|
|
type uintptr32 = uint32
|
|
type size = uint32
|
|
type fdflags = uint32
|
|
type filesize = uint64
|
|
type filetype = uint8
|
|
type lookupflags = uint32
|
|
type oflags = uint32
|
|
type rights = uint64
|
|
type timestamp = uint64
|
|
type dircookie = uint64
|
|
type filedelta = int64
|
|
type fstflags = uint32
|
|
|
|
type iovec struct {
|
|
_ structs.HostLayout
|
|
buf uintptr32
|
|
bufLen size
|
|
}
|
|
|
|
const (
|
|
LOOKUP_SYMLINK_FOLLOW = 0x00000001
|
|
)
|
|
|
|
const (
|
|
OFLAG_CREATE = 0x0001
|
|
OFLAG_DIRECTORY = 0x0002
|
|
OFLAG_EXCL = 0x0004
|
|
OFLAG_TRUNC = 0x0008
|
|
)
|
|
|
|
const (
|
|
FDFLAG_APPEND = 0x0001
|
|
FDFLAG_DSYNC = 0x0002
|
|
FDFLAG_NONBLOCK = 0x0004
|
|
FDFLAG_RSYNC = 0x0008
|
|
FDFLAG_SYNC = 0x0010
|
|
)
|
|
|
|
const (
|
|
RIGHT_FD_DATASYNC = 1 << iota
|
|
RIGHT_FD_READ
|
|
RIGHT_FD_SEEK
|
|
RIGHT_FDSTAT_SET_FLAGS
|
|
RIGHT_FD_SYNC
|
|
RIGHT_FD_TELL
|
|
RIGHT_FD_WRITE
|
|
RIGHT_FD_ADVISE
|
|
RIGHT_FD_ALLOCATE
|
|
RIGHT_PATH_CREATE_DIRECTORY
|
|
RIGHT_PATH_CREATE_FILE
|
|
RIGHT_PATH_LINK_SOURCE
|
|
RIGHT_PATH_LINK_TARGET
|
|
RIGHT_PATH_OPEN
|
|
RIGHT_FD_READDIR
|
|
RIGHT_PATH_READLINK
|
|
RIGHT_PATH_RENAME_SOURCE
|
|
RIGHT_PATH_RENAME_TARGET
|
|
RIGHT_PATH_FILESTAT_GET
|
|
RIGHT_PATH_FILESTAT_SET_SIZE
|
|
RIGHT_PATH_FILESTAT_SET_TIMES
|
|
RIGHT_FD_FILESTAT_GET
|
|
RIGHT_FD_FILESTAT_SET_SIZE
|
|
RIGHT_FD_FILESTAT_SET_TIMES
|
|
RIGHT_PATH_SYMLINK
|
|
RIGHT_PATH_REMOVE_DIRECTORY
|
|
RIGHT_PATH_UNLINK_FILE
|
|
RIGHT_POLL_FD_READWRITE
|
|
RIGHT_SOCK_SHUTDOWN
|
|
RIGHT_SOCK_ACCEPT
|
|
)
|
|
|
|
const (
|
|
WHENCE_SET = 0
|
|
WHENCE_CUR = 1
|
|
WHENCE_END = 2
|
|
)
|
|
|
|
const (
|
|
FILESTAT_SET_ATIM = 0x0001
|
|
FILESTAT_SET_ATIM_NOW = 0x0002
|
|
FILESTAT_SET_MTIM = 0x0004
|
|
FILESTAT_SET_MTIM_NOW = 0x0008
|
|
)
|
|
|
|
const (
|
|
// Despite the rights being defined as a 64 bits integer in the spec,
|
|
// wasmtime crashes the program if we set any of the upper 32 bits.
|
|
fullRights = rights(^uint32(0))
|
|
readRights = rights(RIGHT_FD_READ | RIGHT_FD_READDIR)
|
|
writeRights = rights(RIGHT_FD_DATASYNC | RIGHT_FD_WRITE | RIGHT_FD_ALLOCATE | RIGHT_PATH_FILESTAT_SET_SIZE)
|
|
|
|
// Some runtimes have very strict expectations when it comes to which
|
|
// rights can be enabled on files opened by path_open. The fileRights
|
|
// constant is used as a mask to retain only bits for operations that
|
|
// are supported on files.
|
|
fileRights rights = RIGHT_FD_DATASYNC |
|
|
RIGHT_FD_READ |
|
|
RIGHT_FD_SEEK |
|
|
RIGHT_FDSTAT_SET_FLAGS |
|
|
RIGHT_FD_SYNC |
|
|
RIGHT_FD_TELL |
|
|
RIGHT_FD_WRITE |
|
|
RIGHT_FD_ADVISE |
|
|
RIGHT_FD_ALLOCATE |
|
|
RIGHT_PATH_CREATE_DIRECTORY |
|
|
RIGHT_PATH_CREATE_FILE |
|
|
RIGHT_PATH_LINK_SOURCE |
|
|
RIGHT_PATH_LINK_TARGET |
|
|
RIGHT_PATH_OPEN |
|
|
RIGHT_FD_READDIR |
|
|
RIGHT_PATH_READLINK |
|
|
RIGHT_PATH_RENAME_SOURCE |
|
|
RIGHT_PATH_RENAME_TARGET |
|
|
RIGHT_PATH_FILESTAT_GET |
|
|
RIGHT_PATH_FILESTAT_SET_SIZE |
|
|
RIGHT_PATH_FILESTAT_SET_TIMES |
|
|
RIGHT_FD_FILESTAT_GET |
|
|
RIGHT_FD_FILESTAT_SET_SIZE |
|
|
RIGHT_FD_FILESTAT_SET_TIMES |
|
|
RIGHT_PATH_SYMLINK |
|
|
RIGHT_PATH_REMOVE_DIRECTORY |
|
|
RIGHT_PATH_UNLINK_FILE |
|
|
RIGHT_POLL_FD_READWRITE
|
|
|
|
// Runtimes like wasmtime and wasmedge will refuse to open directories
|
|
// if the rights requested by the application exceed the operations that
|
|
// can be performed on a directory.
|
|
dirRights rights = RIGHT_FD_SEEK |
|
|
RIGHT_FDSTAT_SET_FLAGS |
|
|
RIGHT_FD_SYNC |
|
|
RIGHT_PATH_CREATE_DIRECTORY |
|
|
RIGHT_PATH_CREATE_FILE |
|
|
RIGHT_PATH_LINK_SOURCE |
|
|
RIGHT_PATH_LINK_TARGET |
|
|
RIGHT_PATH_OPEN |
|
|
RIGHT_FD_READDIR |
|
|
RIGHT_PATH_READLINK |
|
|
RIGHT_PATH_RENAME_SOURCE |
|
|
RIGHT_PATH_RENAME_TARGET |
|
|
RIGHT_PATH_FILESTAT_GET |
|
|
RIGHT_PATH_FILESTAT_SET_SIZE |
|
|
RIGHT_PATH_FILESTAT_SET_TIMES |
|
|
RIGHT_FD_FILESTAT_GET |
|
|
RIGHT_FD_FILESTAT_SET_TIMES |
|
|
RIGHT_PATH_SYMLINK |
|
|
RIGHT_PATH_REMOVE_DIRECTORY |
|
|
RIGHT_PATH_UNLINK_FILE
|
|
)
|
|
|
|
type preopentype = uint8
|
|
|
|
const (
|
|
preopentypeDir preopentype = iota
|
|
)
|
|
|
|
type prestatDir struct {
|
|
_ structs.HostLayout
|
|
prNameLen size
|
|
}
|
|
|
|
type prestat struct {
|
|
_ structs.HostLayout
|
|
typ preopentype
|
|
dir prestatDir
|
|
}
|
|
|
|
type opendir struct {
|
|
fd int32
|
|
name string
|
|
}
|
|
|
|
// List of preopen directories that were exposed by the runtime. The first one
|
|
// is assumed to the be root directory of the file system, and others are seen
|
|
// as mount points at sub paths of the root.
|
|
var preopens []opendir
|
|
|
|
// Current working directory. We maintain this as a string and resolve paths in
|
|
// the code because wasmtime does not allow relative path lookups outside of the
|
|
// scope of a directory; a previous approach we tried consisted in maintaining
|
|
// open a file descriptor to the current directory so we could perform relative
|
|
// path lookups from that location, but it resulted in breaking path resolution
|
|
// from the current directory to its parent.
|
|
var cwd string
|
|
|
|
func Openat(dirFd int, path string, openmode int, perm uint32) (int, error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func CloseOnExec(fd int) {
|
|
// nothing to do - no exec
|
|
}
|
|
|
|
func Mkdir(path string, perm uint32) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func ReadDir(fd int, buf []byte, cookie dircookie) (int, error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Fstat(fd int, st *Stat_t) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Unlink(path string) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Rmdir(path string) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Chmod(path string, mode uint32) error {
|
|
var stat Stat_t
|
|
return Stat(path, &stat)
|
|
}
|
|
|
|
func Fchmod(fd int, mode uint32) error {
|
|
var stat Stat_t
|
|
return Fstat(fd, &stat)
|
|
}
|
|
|
|
func Chown(path string, uid, gid int) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Fchown(fd int, uid, gid int) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Lchown(path string, uid, gid int) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func UtimesNano(path string, ts []Timespec) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Rename(from, to string) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Truncate(path string, length int64) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Ftruncate(fd int, length int64) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
const ImplementsGetwd = true
|
|
|
|
func Chdir(path string) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Readlink(path string, buf []byte) (n int, err error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Link(path, link string) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Symlink(path, link string) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Fsync(fd int) error {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Write(fd int, b []byte) (int, error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Pread(fd int, b []byte, offset int64) (int, error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Pwrite(fd int, b []byte, offset int64) (int, error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Dup(fd int) (int, error) {
|
|
panic("not implemented")
|
|
}
|
|
|
|
func Dup2(fd, newfd int) error {
|
|
panic("not implemented")
|
|
}
|