github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/sysfs/adapter.go (about) 1 package sysfs 2 3 import ( 4 "fmt" 5 "io/fs" 6 "path" 7 8 experimentalsys "github.com/wasilibs/wazerox/experimental/sys" 9 "github.com/wasilibs/wazerox/sys" 10 ) 11 12 type AdaptFS struct { 13 FS fs.FS 14 } 15 16 // String implements fmt.Stringer 17 func (a *AdaptFS) String() string { 18 return fmt.Sprintf("%v", a.FS) 19 } 20 21 // OpenFile implements the same method as documented on sys.FS 22 func (a *AdaptFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) { 23 return OpenFSFile(a.FS, cleanPath(path), flag, perm) 24 } 25 26 // Lstat implements the same method as documented on sys.FS 27 func (a *AdaptFS) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) { 28 // At this time, we make the assumption sys.FS instances do not support 29 // symbolic links, therefore Lstat is the same as Stat. This is obviously 30 // not true, but until FS.FS has a solid story for how to handle symlinks, 31 // we are better off not making a decision that would be difficult to 32 // revert later on. 33 // 34 // For further discussions on the topic, see: 35 // https://github.com/golang/go/issues/49580 36 return a.Stat(path) 37 } 38 39 // Stat implements the same method as documented on sys.FS 40 func (a *AdaptFS) Stat(path string) (sys.Stat_t, experimentalsys.Errno) { 41 f, errno := a.OpenFile(path, experimentalsys.O_RDONLY, 0) 42 if errno != 0 { 43 return sys.Stat_t{}, errno 44 } 45 defer f.Close() 46 return f.Stat() 47 } 48 49 // Readlink implements the same method as documented on sys.FS 50 func (a *AdaptFS) Readlink(string) (string, experimentalsys.Errno) { 51 return "", experimentalsys.ENOSYS 52 } 53 54 // Mkdir implements the same method as documented on sys.FS 55 func (a *AdaptFS) Mkdir(string, fs.FileMode) experimentalsys.Errno { 56 return experimentalsys.ENOSYS 57 } 58 59 // Chmod implements the same method as documented on sys.FS 60 func (a *AdaptFS) Chmod(string, fs.FileMode) experimentalsys.Errno { 61 return experimentalsys.ENOSYS 62 } 63 64 // Rename implements the same method as documented on sys.FS 65 func (a *AdaptFS) Rename(string, string) experimentalsys.Errno { 66 return experimentalsys.ENOSYS 67 } 68 69 // Rmdir implements the same method as documented on sys.FS 70 func (a *AdaptFS) Rmdir(string) experimentalsys.Errno { 71 return experimentalsys.ENOSYS 72 } 73 74 // Link implements the same method as documented on sys.FS 75 func (a *AdaptFS) Link(string, string) experimentalsys.Errno { 76 return experimentalsys.ENOSYS 77 } 78 79 // Symlink implements the same method as documented on sys.FS 80 func (a *AdaptFS) Symlink(string, string) experimentalsys.Errno { 81 return experimentalsys.ENOSYS 82 } 83 84 // Unlink implements the same method as documented on sys.FS 85 func (a *AdaptFS) Unlink(string) experimentalsys.Errno { 86 return experimentalsys.ENOSYS 87 } 88 89 // Utimens implements the same method as documented on sys.FS 90 func (a *AdaptFS) Utimens(string, int64, int64) experimentalsys.Errno { 91 return experimentalsys.ENOSYS 92 } 93 94 func cleanPath(name string) string { 95 if len(name) == 0 { 96 return name 97 } 98 // fs.ValidFile cannot be rooted (start with '/') 99 cleaned := name 100 if name[0] == '/' { 101 cleaned = name[1:] 102 } 103 cleaned = path.Clean(cleaned) // e.g. "sub/." -> "sub" 104 return cleaned 105 }