github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/gojs/custom/fs.go (about)

     1  package custom
     2  
     3  import "io/fs"
     4  
     5  const (
     6  	NameFs          = "fs"
     7  	NameFsOpen      = "open"
     8  	NameFsStat      = "stat"
     9  	NameFsFstat     = "fstat"
    10  	NameFsLstat     = "lstat"
    11  	NameFsClose     = "close"
    12  	NameFsWrite     = "write"
    13  	NameFsRead      = "read"
    14  	NameFsReaddir   = "readdir"
    15  	NameFsMkdir     = "mkdir"
    16  	NameFsRmdir     = "rmdir"
    17  	NameFsRename    = "rename"
    18  	NameFsUnlink    = "unlink"
    19  	NameFsUtimes    = "utimes"
    20  	NameFsChmod     = "chmod"
    21  	NameFsFchmod    = "fchmod"
    22  	NameFsChown     = "chown"
    23  	NameFsFchown    = "fchown"
    24  	NameFsLchown    = "lchown"
    25  	NameFsTruncate  = "truncate"
    26  	NameFsFtruncate = "ftruncate"
    27  	NameFsReadlink  = "readlink"
    28  	NameFsLink      = "link"
    29  	NameFsSymlink   = "symlink"
    30  	NameFsFsync     = "fsync"
    31  )
    32  
    33  // FsNameSection are the functions defined in the object named NameFs. Results
    34  // here are those set to the current event object, but effectively are results
    35  // of the host function.
    36  var FsNameSection = map[string]*Names{
    37  	NameFsOpen: {
    38  		Name:        NameFsOpen,
    39  		ParamNames:  []string{"path", "flags", "perm", NameCallback},
    40  		ResultNames: []string{"err", "fd"},
    41  	},
    42  	NameFsStat: {
    43  		Name:        NameFsStat,
    44  		ParamNames:  []string{"path", NameCallback},
    45  		ResultNames: []string{"err", "stat"},
    46  	},
    47  	NameFsFstat: {
    48  		Name:        NameFsFstat,
    49  		ParamNames:  []string{"fd", NameCallback},
    50  		ResultNames: []string{"err", "stat"},
    51  	},
    52  	NameFsLstat: {
    53  		Name:        NameFsLstat,
    54  		ParamNames:  []string{"path", NameCallback},
    55  		ResultNames: []string{"err", "stat"},
    56  	},
    57  	NameFsClose: {
    58  		Name:        NameFsClose,
    59  		ParamNames:  []string{"fd", NameCallback},
    60  		ResultNames: []string{"err", "ok"},
    61  	},
    62  	NameFsRead: {
    63  		Name:        NameFsRead,
    64  		ParamNames:  []string{"fd", "buf", "offset", "byteCount", "fOffset", NameCallback},
    65  		ResultNames: []string{"err", "n"},
    66  	},
    67  	NameFsWrite: {
    68  		Name:        NameFsWrite,
    69  		ParamNames:  []string{"fd", "buf", "offset", "byteCount", "fOffset", NameCallback},
    70  		ResultNames: []string{"err", "n"},
    71  	},
    72  	NameFsReaddir: {
    73  		Name:        NameFsReaddir,
    74  		ParamNames:  []string{"path", NameCallback},
    75  		ResultNames: []string{"err", "dirents"},
    76  	},
    77  	NameFsMkdir: {
    78  		Name:        NameFsMkdir,
    79  		ParamNames:  []string{"path", "perm", NameCallback},
    80  		ResultNames: []string{"err", "fd"},
    81  	},
    82  	NameFsRmdir: {
    83  		Name:        NameFsRmdir,
    84  		ParamNames:  []string{"path", NameCallback},
    85  		ResultNames: []string{"err", "ok"},
    86  	},
    87  	NameFsRename: {
    88  		Name:        NameFsRename,
    89  		ParamNames:  []string{"from", "to", NameCallback},
    90  		ResultNames: []string{"err", "ok"},
    91  	},
    92  	NameFsUnlink: {
    93  		Name:        NameFsUnlink,
    94  		ParamNames:  []string{"path", NameCallback},
    95  		ResultNames: []string{"err", "ok"},
    96  	},
    97  	NameFsUtimes: {
    98  		Name:        NameFsUtimes,
    99  		ParamNames:  []string{"path", "atime", "mtime", NameCallback},
   100  		ResultNames: []string{"err", "ok"},
   101  	},
   102  	NameFsChmod: {
   103  		Name:        NameFsChmod,
   104  		ParamNames:  []string{"path", "mode", NameCallback},
   105  		ResultNames: []string{"err", "ok"},
   106  	},
   107  	NameFsFchmod: {
   108  		Name:        NameFsFchmod,
   109  		ParamNames:  []string{"fd", "mode", NameCallback},
   110  		ResultNames: []string{"err", "ok"},
   111  	},
   112  	NameFsChown: {
   113  		Name:        NameFsChown,
   114  		ParamNames:  []string{"path", "uid", "gid", NameCallback},
   115  		ResultNames: []string{"err", "ok"},
   116  	},
   117  	NameFsFchown: {
   118  		Name:        NameFsFchown,
   119  		ParamNames:  []string{"fd", "uid", "gid", NameCallback},
   120  		ResultNames: []string{"err", "ok"},
   121  	},
   122  	NameFsLchown: {
   123  		Name:        NameFsLchown,
   124  		ParamNames:  []string{"path", "uid", "gid", NameCallback},
   125  		ResultNames: []string{"err", "ok"},
   126  	},
   127  	NameFsTruncate: {
   128  		Name:        NameFsTruncate,
   129  		ParamNames:  []string{"path", "length", NameCallback},
   130  		ResultNames: []string{"err", "ok"},
   131  	},
   132  	NameFsFtruncate: {
   133  		Name:        NameFsFtruncate,
   134  		ParamNames:  []string{"fd", "length", NameCallback},
   135  		ResultNames: []string{"err", "ok"},
   136  	},
   137  	NameFsReadlink: {
   138  		Name:        NameFsReadlink,
   139  		ParamNames:  []string{"path", NameCallback},
   140  		ResultNames: []string{"err", "dst"},
   141  	},
   142  	NameFsLink: {
   143  		Name:        NameFsLink,
   144  		ParamNames:  []string{"path", "link", NameCallback},
   145  		ResultNames: []string{"err", "ok"},
   146  	},
   147  	NameFsSymlink: {
   148  		Name:        NameFsSymlink,
   149  		ParamNames:  []string{"path", "link", NameCallback},
   150  		ResultNames: []string{"err", "ok"},
   151  	},
   152  	NameFsFsync: {
   153  		Name:        NameFsFsync,
   154  		ParamNames:  []string{"fd", NameCallback},
   155  		ResultNames: []string{"err", "ok"},
   156  	},
   157  }
   158  
   159  // mode constants from syscall_js.go
   160  const (
   161  	S_IFSOCK = uint32(0o000140000)
   162  	S_IFLNK  = uint32(0o000120000)
   163  	S_IFREG  = uint32(0o000100000)
   164  	S_IFBLK  = uint32(0o000060000)
   165  	S_IFDIR  = uint32(0o000040000)
   166  	S_IFCHR  = uint32(0o000020000)
   167  	S_IFIFO  = uint32(0o000010000)
   168  
   169  	S_ISUID = uint32(0o004000)
   170  	S_ISGID = uint32(0o002000)
   171  	S_ISVTX = uint32(0o001000)
   172  )
   173  
   174  // ToJsMode is required because the mode property read in `GOOS=js` is
   175  // incompatible with normal go. Particularly the directory flag isn't the same.
   176  func ToJsMode(fm fs.FileMode) (jsMode uint32) {
   177  	switch {
   178  	case fm.IsRegular():
   179  		jsMode = S_IFREG
   180  	case fm.IsDir():
   181  		jsMode = S_IFDIR
   182  	case fm&fs.ModeSymlink != 0:
   183  		jsMode = S_IFLNK
   184  	case fm&fs.ModeDevice != 0:
   185  		// Unlike ModeDevice and ModeCharDevice, S_IFCHR and S_IFBLK are set
   186  		// mutually exclusively.
   187  		if fm&fs.ModeCharDevice != 0 {
   188  			jsMode = S_IFCHR
   189  		} else {
   190  			jsMode = S_IFBLK
   191  		}
   192  	case fm&fs.ModeNamedPipe != 0:
   193  		jsMode = S_IFIFO
   194  	case fm&fs.ModeSocket != 0:
   195  		jsMode = S_IFSOCK
   196  	default: // unknown
   197  		jsMode = 0
   198  	}
   199  
   200  	jsMode |= uint32(fm & fs.ModePerm)
   201  
   202  	if fm&fs.ModeSetgid != 0 {
   203  		jsMode |= S_ISGID
   204  	}
   205  	if fm&fs.ModeSetuid != 0 {
   206  		jsMode |= S_ISUID
   207  	}
   208  	if fm&fs.ModeSticky != 0 {
   209  		jsMode |= S_ISVTX
   210  	}
   211  	return
   212  }
   213  
   214  // FromJsMode is required because the mode property read in `GOOS=js` is
   215  // incompatible with normal go. Particularly the directory flag isn't the same.
   216  func FromJsMode(jsMode, umask uint32) (fm fs.FileMode) {
   217  	switch {
   218  	case jsMode&S_IFREG != 0: // zero
   219  	case jsMode&S_IFDIR != 0:
   220  		fm = fs.ModeDir
   221  	case jsMode&S_IFLNK != 0:
   222  		fm = fs.ModeSymlink
   223  	case jsMode&S_IFCHR != 0:
   224  		fm = fs.ModeDevice | fs.ModeCharDevice
   225  	case jsMode&S_IFBLK != 0:
   226  		fm = fs.ModeDevice
   227  	case jsMode&S_IFIFO != 0:
   228  		fm = fs.ModeNamedPipe
   229  	case jsMode&S_IFSOCK != 0:
   230  		fm = fs.ModeSocket
   231  	default: // unknown
   232  		fm = 0
   233  	}
   234  
   235  	fm |= fs.FileMode(jsMode) & fs.ModePerm
   236  
   237  	if jsMode&S_ISGID != 0 {
   238  		fm |= fs.ModeSetgid
   239  	}
   240  	if jsMode&S_ISUID != 0 {
   241  		fm |= fs.ModeSetuid
   242  	}
   243  	if jsMode&S_ISVTX != 0 {
   244  		fm |= fs.ModeSticky
   245  	}
   246  	fm &= ^(fs.FileMode(umask))
   247  	return
   248  }