github.com/gotranspile/cxgo@v0.3.7/runtime/stdio/fs.go (about) 1 package stdio 2 3 import ( 4 "errors" 5 "io" 6 "os" 7 "sync" 8 9 "github.com/gotranspile/cxgo/runtime/libc" 10 ) 11 12 type FileI interface { 13 Fd() uintptr 14 Name() string 15 Sync() error 16 io.Reader 17 io.Writer 18 io.Seeker 19 io.Closer 20 } 21 22 type Filesystem interface { 23 Stdout() FileI 24 Stderr() FileI 25 Stdin() FileI 26 Getwd() (string, error) 27 Chdir(path string) error 28 Rmdir(path string) error 29 Unlink(path string) error 30 Open(path string, flag int, mode os.FileMode) (FileI, error) 31 Stat(path string) (os.FileInfo, error) 32 } 33 34 var defaultFS *filesystem 35 36 func init() { 37 SetFS(nil) 38 } 39 40 func SetFS(fs Filesystem) { 41 if fs == nil { 42 fs = localFS{} 43 } 44 // TODO: mount stdout, stderr, stdin 45 defaultFS = &filesystem{ 46 fs: fs, 47 byFD: make(map[uintptr]*File), 48 } 49 } 50 51 func FS() Filesystem { 52 if defaultFS == nil { 53 SetFS(nil) 54 } 55 return defaultFS.fs 56 } 57 58 func ByFD(fd uintptr) *File { 59 f, err := defaultFS.fileByFD(fd) 60 if err != nil { 61 libc.SetErr(err) 62 return nil 63 } 64 return f 65 } 66 67 type filesystem struct { 68 fs Filesystem 69 sync.RWMutex 70 byFD map[uintptr]*File 71 } 72 73 func (fs *filesystem) fileByFD(fd uintptr) (*File, error) { 74 fs.RLock() 75 f := fs.byFD[fd] 76 fs.RUnlock() 77 if f == nil { 78 return nil, errors.New("invalid fd") 79 } 80 return f, nil 81 }