make runtime compatible with wasm
This commit is contained in:
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
c "github.com/goplus/llgo/runtime/internal/clite"
|
||||
"github.com/goplus/llgo/runtime/internal/clite/os"
|
||||
"github.com/goplus/llgo/runtime/internal/clite/syscall"
|
||||
"github.com/goplus/llgo/runtime/internal/lib/internal/bytealg"
|
||||
"github.com/goplus/llgo/runtime/internal/lib/syscall"
|
||||
)
|
||||
|
||||
type readdirMode int
|
||||
@@ -39,7 +39,7 @@ func (f *File) Readdirnames(n int) (names []string, err error) {
|
||||
}
|
||||
|
||||
func open(path string, flag int, perm uint32) (int, error) {
|
||||
fd, err := syscall.Open(path, flag, perm)
|
||||
fd, err := origSyscall.Open(path, flag, perm)
|
||||
return fd, err
|
||||
}
|
||||
|
||||
@@ -100,10 +100,29 @@ func closedir(dir uintptr) error {
|
||||
}
|
||||
|
||||
//go:linkname c_readdir C.readdir
|
||||
func c_readdir(dir uintptr) ([]syscall.Dirent, error)
|
||||
func c_readdir(dir uintptr) *syscall.Dirent
|
||||
|
||||
func readdir(dir uintptr) ([]syscall.Dirent, error) {
|
||||
return c_readdir(dir)
|
||||
var entries []syscall.Dirent
|
||||
for {
|
||||
dirent := c_readdir(dir)
|
||||
if dirent == nil {
|
||||
break
|
||||
}
|
||||
entries = append(entries, *dirent)
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func direntNamePtr(name any) *byte {
|
||||
switch name := name.(type) {
|
||||
case *byte:
|
||||
return name
|
||||
case []byte:
|
||||
return &name[0]
|
||||
default:
|
||||
panic("invalid type")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *File) ReadDir(n int) (dirents []DirEntry, err error) {
|
||||
@@ -133,26 +152,26 @@ func (f *File) ReadDir(n int) (dirents []DirEntry, err error) {
|
||||
|
||||
for _, entry := range entries {
|
||||
// Convert syscall.Dirent to fs.DirEntry
|
||||
name := bytesToString((*[1024]byte)(unsafe.Pointer(&entry.Name[0]))[:])
|
||||
name := bytesToString((*[1024]byte)(unsafe.Pointer(direntNamePtr(entry.Name)))[:])
|
||||
if name == "." || name == ".." {
|
||||
continue
|
||||
}
|
||||
|
||||
typ := fs.FileMode(0)
|
||||
switch entry.Type {
|
||||
case origSyscall.DT_REG:
|
||||
case syscall.DT_REG:
|
||||
typ = 0
|
||||
case origSyscall.DT_DIR:
|
||||
case syscall.DT_DIR:
|
||||
typ = fs.ModeDir
|
||||
case origSyscall.DT_LNK:
|
||||
case syscall.DT_LNK:
|
||||
typ = fs.ModeSymlink
|
||||
case origSyscall.DT_SOCK:
|
||||
case syscall.DT_SOCK:
|
||||
typ = fs.ModeSocket
|
||||
case origSyscall.DT_FIFO:
|
||||
case syscall.DT_FIFO:
|
||||
typ = fs.ModeNamedPipe
|
||||
case origSyscall.DT_CHR:
|
||||
case syscall.DT_CHR:
|
||||
typ = fs.ModeCharDevice
|
||||
case origSyscall.DT_BLK:
|
||||
case syscall.DT_BLK:
|
||||
typ = fs.ModeDevice
|
||||
}
|
||||
|
||||
|
||||
@@ -208,15 +208,6 @@ func (f *File) WriteString(s string) (n int, err error) {
|
||||
panic("todo: os.(*File).WriteString")
|
||||
}
|
||||
|
||||
// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
|
||||
func setStickyBit(name string) error {
|
||||
fi, err := Stat(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return Chmod(name, fi.Mode()|ModeSticky)
|
||||
}
|
||||
|
||||
// Open opens the named file for reading. If successful, methods on
|
||||
// the returned file can be used for reading; the associated file
|
||||
// descriptor has mode O_RDONLY.
|
||||
@@ -476,7 +467,6 @@ func ReadFile(name string) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var size int
|
||||
if info, err := f.Stat(); err == nil {
|
||||
@@ -507,6 +497,7 @@ func ReadFile(name string) ([]byte, error) {
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
f.Close()
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,44 +80,6 @@ func Chdir(dir string) error {
|
||||
}
|
||||
*/
|
||||
|
||||
func Chmod(name string, mode FileMode) error {
|
||||
ret := os.Chmod(c.AllocaCStr(name), os.ModeT(syscallMode(mode)))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return toPathErr("chmod", name, ret)
|
||||
}
|
||||
|
||||
/* TODO(xsw):
|
||||
// Chmod changes the mode of the named file to mode.
|
||||
// If the file is a symbolic link, it changes the mode of the link's target.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
//
|
||||
// A different subset of the mode bits are used, depending on the
|
||||
// operating system.
|
||||
//
|
||||
// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
|
||||
// ModeSticky are used.
|
||||
//
|
||||
// On Windows, only the 0200 bit (owner writable) of mode is used; it
|
||||
// controls whether the file's read-only attribute is set or cleared.
|
||||
// The other bits are currently unused. For compatibility with Go 1.12
|
||||
// and earlier, use a non-zero mode. Use mode 0400 for a read-only
|
||||
// file and 0600 for a readable+writable file.
|
||||
//
|
||||
// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
|
||||
// and ModeTemporary are used.
|
||||
func Chmod(name string, mode FileMode) error { return chmod(name, mode) }
|
||||
*/
|
||||
|
||||
func Chown(name string, uid, gid int) error {
|
||||
ret := os.Chown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return toPathErr("chown", name, ret)
|
||||
}
|
||||
|
||||
/* TODO(xsw):
|
||||
// Chown changes the numeric uid and gid of the named file.
|
||||
// If the file is a symbolic link, it changes the uid and gid of the link's target.
|
||||
@@ -152,34 +114,6 @@ func Clearenv()
|
||||
// func Expand(s string, mapping func(string) string) string
|
||||
// func ExpandEnv(s string) string
|
||||
|
||||
func Getegid() int {
|
||||
return int(os.Getegid())
|
||||
}
|
||||
|
||||
func Geteuid() int {
|
||||
return int(os.Geteuid())
|
||||
}
|
||||
|
||||
func Getgid() int {
|
||||
return int(os.Getgid())
|
||||
}
|
||||
|
||||
// TODO(xsw):
|
||||
// func Getgroups() ([]int, error)
|
||||
// func Getpagesize() int
|
||||
|
||||
func Getpid() int {
|
||||
return int(os.Getpid())
|
||||
}
|
||||
|
||||
func Getppid() int {
|
||||
return int(os.Getppid())
|
||||
}
|
||||
|
||||
func Getuid() int {
|
||||
return int(os.Getuid())
|
||||
}
|
||||
|
||||
func Getwd() (dir string, err error) {
|
||||
wd := os.Getcwd(c.Alloca(os.PATH_MAX), os.PATH_MAX)
|
||||
if wd != nil {
|
||||
@@ -195,32 +129,6 @@ func Getwd() (dir string, err error) {
|
||||
// func IsPermission(err error) bool
|
||||
// func IsTimeout(err error) bool
|
||||
|
||||
func Lchown(name string, uid, gid int) error {
|
||||
ret := os.Lchown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return toPathErr("lchown", name, ret)
|
||||
}
|
||||
|
||||
/* TODO(xsw):
|
||||
// Lchown changes the numeric uid and gid of the named file.
|
||||
// If the file is a symbolic link, it changes the uid and gid of the link itself.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
//
|
||||
// On Windows, it always returns the syscall.EWINDOWS error, wrapped
|
||||
// in *PathError.
|
||||
func Lchown(name string, uid, gid int) error {
|
||||
e := ignoringEINTR(func() error {
|
||||
return syscall.Lchown(name, uid, gid)
|
||||
})
|
||||
if e != nil {
|
||||
return &PathError{Op: "lchown", Path: name, Err: e}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
func Link(oldname, newname string) error {
|
||||
ret := os.Link(c.AllocaCStr(oldname), c.AllocaCStr(newname))
|
||||
if ret == 0 {
|
||||
|
||||
109
runtime/internal/lib/os/os_nonwasm.go
Normal file
109
runtime/internal/lib/os/os_nonwasm.go
Normal file
@@ -0,0 +1,109 @@
|
||||
//go:build !wasm
|
||||
|
||||
package os
|
||||
|
||||
import (
|
||||
c "github.com/goplus/llgo/runtime/internal/clite"
|
||||
"github.com/goplus/llgo/runtime/internal/clite/os"
|
||||
)
|
||||
|
||||
// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
|
||||
func setStickyBit(name string) error {
|
||||
fi, err := Stat(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return Chmod(name, fi.Mode()|ModeSticky)
|
||||
}
|
||||
|
||||
func Chmod(name string, mode FileMode) error {
|
||||
ret := os.Chmod(c.AllocaCStr(name), os.ModeT(syscallMode(mode)))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return toPathErr("chmod", name, ret)
|
||||
}
|
||||
|
||||
/* TODO(xsw):
|
||||
// Chmod changes the mode of the named file to mode.
|
||||
// If the file is a symbolic link, it changes the mode of the link's target.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
//
|
||||
// A different subset of the mode bits are used, depending on the
|
||||
// operating system.
|
||||
//
|
||||
// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
|
||||
// ModeSticky are used.
|
||||
//
|
||||
// On Windows, only the 0200 bit (owner writable) of mode is used; it
|
||||
// controls whether the file's read-only attribute is set or cleared.
|
||||
// The other bits are currently unused. For compatibility with Go 1.12
|
||||
// and earlier, use a non-zero mode. Use mode 0400 for a read-only
|
||||
// file and 0600 for a readable+writable file.
|
||||
//
|
||||
// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
|
||||
// and ModeTemporary are used.
|
||||
func Chmod(name string, mode FileMode) error { return chmod(name, mode) }
|
||||
*/
|
||||
|
||||
func Chown(name string, uid, gid int) error {
|
||||
ret := os.Chown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return toPathErr("chown", name, ret)
|
||||
}
|
||||
|
||||
func Getegid() int {
|
||||
return int(os.Getegid())
|
||||
}
|
||||
|
||||
func Geteuid() int {
|
||||
return int(os.Geteuid())
|
||||
}
|
||||
|
||||
func Getgid() int {
|
||||
return int(os.Getgid())
|
||||
}
|
||||
|
||||
// TODO(xsw):
|
||||
// func Getgroups() ([]int, error)
|
||||
// func Getpagesize() int
|
||||
|
||||
func Getpid() int {
|
||||
return int(os.Getpid())
|
||||
}
|
||||
|
||||
func Getppid() int {
|
||||
return int(os.Getppid())
|
||||
}
|
||||
|
||||
func Getuid() int {
|
||||
return int(os.Getuid())
|
||||
}
|
||||
|
||||
func Lchown(name string, uid, gid int) error {
|
||||
ret := os.Lchown(c.AllocaCStr(name), os.UidT(uid), os.GidT(gid))
|
||||
if ret == 0 {
|
||||
return nil
|
||||
}
|
||||
return toPathErr("lchown", name, ret)
|
||||
}
|
||||
|
||||
/* TODO(xsw):
|
||||
// Lchown changes the numeric uid and gid of the named file.
|
||||
// If the file is a symbolic link, it changes the uid and gid of the link itself.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
//
|
||||
// On Windows, it always returns the syscall.EWINDOWS error, wrapped
|
||||
// in *PathError.
|
||||
func Lchown(name string, uid, gid int) error {
|
||||
e := ignoringEINTR(func() error {
|
||||
return syscall.Lchown(name, uid, gid)
|
||||
})
|
||||
if e != nil {
|
||||
return &PathError{Op: "lchown", Path: name, Err: e}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
10
runtime/internal/lib/os/os_wasm.go
Normal file
10
runtime/internal/lib/os/os_wasm.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package os
|
||||
|
||||
// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
|
||||
func setStickyBit(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Chmod(name string, mode FileMode) error {
|
||||
return nil
|
||||
}
|
||||
@@ -57,3 +57,14 @@ func MkdirAll(path string, perm FileMode) error {
|
||||
func RemoveAll(path string) error {
|
||||
return removeAll(path)
|
||||
}
|
||||
|
||||
// endsWithDot reports whether the final component of path is ".".
|
||||
func endsWithDot(path string) bool {
|
||||
if path == "." {
|
||||
return true
|
||||
}
|
||||
if len(path) >= 2 && path[len(path)-1] == '.' && IsPathSeparator(path[len(path)-2]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -209,14 +209,3 @@ func openDirAt(dirfd int, name string) (*File, error) {
|
||||
// We use kindNoPoll because we know that this is a directory.
|
||||
return newFile(r, name, kindNoPoll), nil
|
||||
}
|
||||
|
||||
// endsWithDot reports whether the final component of path is ".".
|
||||
func endsWithDot(path string) bool {
|
||||
if path == "." {
|
||||
return true
|
||||
}
|
||||
if len(path) >= 2 && path[len(path)-1] == '.' && IsPathSeparator(path[len(path)-2]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build unix || (js && wasm) || wasip1
|
||||
//go:build unix || wasm
|
||||
|
||||
package os
|
||||
|
||||
@@ -23,7 +23,6 @@ func (f *File) Stat() (FileInfo, error) {
|
||||
if err != 0 {
|
||||
return nil, &PathError{Op: "stat", Path: f.name, Err: syscall.Errno(err)}
|
||||
}
|
||||
fillFileStatFromSys(&fs, f.name)
|
||||
return &fs, nil
|
||||
}
|
||||
|
||||
@@ -36,7 +35,6 @@ func statNolog(name string) (FileInfo, error) {
|
||||
if err != nil {
|
||||
return nil, &PathError{Op: "stat", Path: name, Err: err}
|
||||
}
|
||||
fillFileStatFromSys(&fs, name)
|
||||
return &fs, nil
|
||||
}
|
||||
|
||||
@@ -49,6 +47,5 @@ func lstatNolog(name string) (FileInfo, error) {
|
||||
if err != nil {
|
||||
return nil, &PathError{Op: "lstat", Path: name, Err: err}
|
||||
}
|
||||
fillFileStatFromSys(&fs, name)
|
||||
return &fs, nil
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build js && wasm
|
||||
//go:build js && !wasm
|
||||
|
||||
package os
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build wasip1
|
||||
|
||||
package os
|
||||
|
||||
// supportsCloseOnExec reports whether the platform supports the
|
||||
Reference in New Issue
Block a user