summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/sysfs/adapter.go
blob: 51a9a5480469b38eeda50c630618c3c35e259e2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package sysfs

import (
	"fmt"
	"io/fs"
	"path"

	experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
	"github.com/tetratelabs/wazero/sys"
)

type AdaptFS struct {
	FS fs.FS
}

// String implements fmt.Stringer
func (a *AdaptFS) String() string {
	return fmt.Sprintf("%v", a.FS)
}

// OpenFile implements the same method as documented on sys.FS
func (a *AdaptFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
	return OpenFSFile(a.FS, cleanPath(path), flag, perm)
}

// Lstat implements the same method as documented on sys.FS
func (a *AdaptFS) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) {
	// At this time, we make the assumption sys.FS instances do not support
	// symbolic links, therefore Lstat is the same as Stat. This is obviously
	// not true, but until FS.FS has a solid story for how to handle symlinks,
	// we are better off not making a decision that would be difficult to
	// revert later on.
	//
	// For further discussions on the topic, see:
	// https://github.com/golang/go/issues/49580
	return a.Stat(path)
}

// Stat implements the same method as documented on sys.FS
func (a *AdaptFS) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
	f, errno := a.OpenFile(path, experimentalsys.O_RDONLY, 0)
	if errno != 0 {
		return sys.Stat_t{}, errno
	}
	defer f.Close()
	return f.Stat()
}

// Readlink implements the same method as documented on sys.FS
func (a *AdaptFS) Readlink(string) (string, experimentalsys.Errno) {
	return "", experimentalsys.ENOSYS
}

// Mkdir implements the same method as documented on sys.FS
func (a *AdaptFS) Mkdir(string, fs.FileMode) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Chmod implements the same method as documented on sys.FS
func (a *AdaptFS) Chmod(string, fs.FileMode) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Rename implements the same method as documented on sys.FS
func (a *AdaptFS) Rename(string, string) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Rmdir implements the same method as documented on sys.FS
func (a *AdaptFS) Rmdir(string) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Link implements the same method as documented on sys.FS
func (a *AdaptFS) Link(string, string) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Symlink implements the same method as documented on sys.FS
func (a *AdaptFS) Symlink(string, string) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Unlink implements the same method as documented on sys.FS
func (a *AdaptFS) Unlink(string) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

// Utimens implements the same method as documented on sys.FS
func (a *AdaptFS) Utimens(string, int64, int64) experimentalsys.Errno {
	return experimentalsys.ENOSYS
}

func cleanPath(name string) string {
	if len(name) == 0 {
		return name
	}
	// fs.ValidFile cannot be rooted (start with '/')
	cleaned := name
	if name[0] == '/' {
		cleaned = name[1:]
	}
	cleaned = path.Clean(cleaned) // e.g. "sub/." -> "sub"
	return cleaned
}