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  }