github.com/gaukas/wazerofs@v0.1.0/wraplogfs/fs.go (about)

     1  // wraplogfs is a wazero filesystem that wraps another, existing filesystem, and logs
     2  // all inputs/outputs to writer.
     3  //
     4  // Was first generated by hexdigest/gowrap, but then edited for better outputs in some cases
     5  package wraplogfs
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"io/fs"
    11  	"log"
    12  	"strings"
    13  
    14  	expsys "github.com/tetratelabs/wazero/experimental/sys"
    15  	wasys "github.com/tetratelabs/wazero/sys"
    16  )
    17  
    18  type fsWithLog struct {
    19  	// intentionally does NOT embed unimplemented; I do NOT want to be forward-compatible;
    20  	// I want to break on missing funcs
    21  
    22  	stdlog     *log.Logger
    23  	base       expsys.FS
    24  	writeBytes bool
    25  	fsName     string
    26  }
    27  
    28  // New returns a new filesystem on top of another filesystem.
    29  // writeBytes controls if all bytes are written on stdout on reads/writes, or just "(data)".
    30  func New(base expsys.FS, stdout io.Writer, writeBytes bool, name string) expsys.FS {
    31  	return fsWithLog{
    32  		base:       base,
    33  		stdlog:     log.New(stdout, "", log.LstdFlags),
    34  		writeBytes: writeBytes,
    35  		fsName:     name,
    36  	}
    37  }
    38  
    39  func (d fsWithLog) log(nm string) func(format string, params ...any) {
    40  	return func(format string, params ...any) {
    41  		txt := fmt.Sprintf(format, params...)
    42  		txt = fmt.Sprintf("WrapLogFS %s %s: %s", d.fsName, nm, txt)
    43  		d.stdlog.Println(txt)
    44  	}
    45  }
    46  
    47  // Chmod implements sys.FS
    48  func (d fsWithLog) Chmod(path string, perm fs.FileMode) (e1 expsys.Errno) {
    49  	l := d.log("Chmod")
    50  	l("calling with params: %q %s", path, perm)
    51  	defer func() {
    52  		l("returned results: %s", e1)
    53  	}()
    54  	return d.base.Chmod(path, perm)
    55  }
    56  
    57  // Link implements sys.FS
    58  func (d fsWithLog) Link(oldPath string, newPath string) (e1 expsys.Errno) {
    59  	l := d.log("Link")
    60  	l("calling with params: %q %q", oldPath, newPath)
    61  	defer func() {
    62  		l("returned results: %s", e1)
    63  	}()
    64  	return d.base.Link(oldPath, newPath)
    65  }
    66  
    67  // Lstat implements sys.FS
    68  func (d fsWithLog) Lstat(path string) (s1 wasys.Stat_t, e1 expsys.Errno) {
    69  	l := d.log("Lstat")
    70  	l("calling with params: %q", path)
    71  
    72  	defer func() {
    73  		l("returned results: %+v %s", s1, e1)
    74  	}()
    75  	return d.base.Lstat(path)
    76  }
    77  
    78  // Mkdir implements sys.FS
    79  func (d fsWithLog) Mkdir(path string, perm fs.FileMode) (e1 expsys.Errno) {
    80  	l := d.log("Mkdir")
    81  	l("calling with params: %q %s", path, perm)
    82  
    83  	defer func() {
    84  		l("returned results: %+v %s", e1)
    85  	}()
    86  	return d.base.Mkdir(path, perm)
    87  }
    88  
    89  func printOflags(flag expsys.Oflag) string {
    90  	st := []string{}
    91  	flags := map[expsys.Oflag]string{
    92  
    93  		expsys.O_RDONLY:    "O_RDONLY",
    94  		expsys.O_RDWR:      "O_RDWR",
    95  		expsys.O_WRONLY:    "O_WRONLY",
    96  		expsys.O_APPEND:    "O_APPEND",
    97  		expsys.O_CREAT:     "O_CREAT",
    98  		expsys.O_DIRECTORY: "O_DIRECTORY",
    99  		expsys.O_DSYNC:     "O_DSYNC",
   100  		expsys.O_EXCL:      "O_EXCL",
   101  		expsys.O_NOFOLLOW:  "O_NOFOLLOW",
   102  		expsys.O_NONBLOCK:  "O_NONBLOCK",
   103  		expsys.O_RSYNC:     "O_RSYNC",
   104  		expsys.O_SYNC:      "O_SYNC",
   105  		expsys.O_TRUNC:     "O_TRUNC",
   106  	}
   107  	for f, d := range flags {
   108  		if flag&f != 0 {
   109  			st = append(st, d)
   110  		}
   111  	}
   112  	if len(st) == 0 {
   113  		return "(none)"
   114  	} else {
   115  		return strings.Join(st, "|")
   116  	}
   117  }
   118  
   119  // OpenFile implements sys.FS
   120  func (d fsWithLog) OpenFile(path string, flag expsys.Oflag, perm fs.FileMode) (f1 expsys.File, e1 expsys.Errno) {
   121  	l := d.log("OpenFile")
   122  	l("calling with params: %q %s; %s", path, printOflags(flag), perm)
   123  
   124  	defer func() {
   125  		l("returned results: %T %+v %s", f1, f1, e1)
   126  	}()
   127  	fl, errno := d.base.OpenFile(path, flag, perm)
   128  	return fileWithLog{
   129  		base:       fl,
   130  		stdlog:     d.stdlog,
   131  		writeBytes: d.writeBytes,
   132  		name:       path,
   133  		fsName:     d.fsName,
   134  	}, errno
   135  }
   136  
   137  // Readlink implements sys.FS
   138  func (d fsWithLog) Readlink(path string) (s1 string, e1 expsys.Errno) {
   139  	l := d.log("Readlink")
   140  	l("calling with params: %q", path)
   141  
   142  	defer func() {
   143  		l("returned results: %q %s", s1, e1)
   144  	}()
   145  	return d.base.Readlink(path)
   146  }
   147  
   148  // Rename implements sys.FS
   149  func (d fsWithLog) Rename(from string, to string) (e1 expsys.Errno) {
   150  	l := d.log("Rename")
   151  	l("calling with params: %q %q", from, to)
   152  
   153  	defer func() {
   154  		l("returned results: %s", e1)
   155  	}()
   156  	return d.base.Rename(from, to)
   157  }
   158  
   159  // Rmdir implements sys.FS
   160  func (d fsWithLog) Rmdir(path string) (e1 expsys.Errno) {
   161  	l := d.log("Rmdir")
   162  	l("calling with params: %q", path)
   163  
   164  	defer func() {
   165  		l("returned results: %s", e1)
   166  	}()
   167  	return d.base.Rmdir(path)
   168  }
   169  
   170  // Stat implements sys.FS
   171  func (d fsWithLog) Stat(path string) (s1 wasys.Stat_t, e1 expsys.Errno) {
   172  	l := d.log("Stat")
   173  	l("calling with params: %q", path)
   174  
   175  	defer func() {
   176  		l("returned results: %s", e1)
   177  	}()
   178  
   179  	return d.base.Stat(path)
   180  }
   181  
   182  // Symlink implements sys.FS
   183  func (d fsWithLog) Symlink(oldPath string, linkName string) (e1 expsys.Errno) {
   184  	l := d.log("Symlink")
   185  	l("calling with params: %q %q", oldPath, linkName)
   186  
   187  	defer func() {
   188  		l("returned results: %s", e1)
   189  	}()
   190  	return d.base.Symlink(oldPath, linkName)
   191  }
   192  
   193  // Unlink implements sys.FS
   194  func (d fsWithLog) Unlink(path string) (e1 expsys.Errno) {
   195  	l := d.log("Unlink")
   196  	l("calling with params: %q", path)
   197  
   198  	defer func() {
   199  		l("returned results: %s", e1)
   200  	}()
   201  	return d.base.Unlink(path)
   202  }
   203  
   204  // Utimens implements sys.FS
   205  func (d fsWithLog) Utimens(path string, atim int64, mtim int64) (e1 expsys.Errno) {
   206  	l := d.log("Symlink")
   207  	l("calling with params: %q %d %d", path, atim, mtim)
   208  
   209  	defer func() {
   210  		l("returned results: %s", e1)
   211  	}()
   212  	return d.base.Utimens(path, atim, mtim)
   213  }