All checks were successful
Fuse test / go-test (push) Successful in 32s
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
101 lines
2.3 KiB
Go
101 lines
2.3 KiB
Go
//go:build unix
|
|
|
|
package utils
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"io/fs"
|
|
"os"
|
|
"syscall"
|
|
|
|
"sirherobrine23.com.br/Sirherobrine23/cgofuse/fuse"
|
|
)
|
|
|
|
// Add to fuse file information from [io/fs.File] interface
|
|
func BasicStat(stat fs.FileInfo, fuseStat *fuse.Stat_t) {
|
|
fuseStat.Mtim = fuse.NewTimespec(stat.ModTime())
|
|
fuseStat.Ctim = fuse.NewTimespec(stat.ModTime())
|
|
fuseStat.Atim = fuse.NewTimespec(stat.ModTime())
|
|
fuseStat.Birthtim = fuse.NewTimespec(stat.ModTime())
|
|
|
|
fuseStat.Size = stat.Size()
|
|
fuseStat.Blksize = 512
|
|
fuseStat.Blocks = fuseStat.Size / fuseStat.Blksize
|
|
|
|
fuseStat.Nlink = 1
|
|
fuseStat.Uid = uint32(os.Getuid())
|
|
fuseStat.Gid = uint32(os.Getgid())
|
|
fuseStat.Rdev = 0
|
|
fuseStat.Dev = 0
|
|
fuseStat.Ino = 0
|
|
|
|
fuseStat.Mode = GetMode(stat.Mode())
|
|
}
|
|
|
|
// Add to fuse dir entry informatio, if [io/fs.DirEntry.Info]
|
|
// return [io/fs.FileInfo] append with [AppendStat]
|
|
func AppendDirEntry(stat fs.DirEntry, fuseStat *fuse.Stat_t) {
|
|
fuseStat.Mode = GetMode(stat.Type()) | 0755
|
|
|
|
if extraInfo, err := stat.Info(); err == nil {
|
|
AppendStat(extraInfo, fuseStat)
|
|
}
|
|
}
|
|
|
|
func FromEntry(stat fs.DirEntry) *fuse.Stat_t {
|
|
fuseStat := new(fuse.Stat_t)
|
|
AppendDirEntry(stat, fuseStat)
|
|
return fuseStat
|
|
}
|
|
|
|
func FromFileInfo(stat fs.FileInfo) *fuse.Stat_t {
|
|
fuseStat := new(fuse.Stat_t)
|
|
AppendStat(stat, fuseStat)
|
|
return fuseStat
|
|
}
|
|
|
|
// Convert [syscall.Errno], [calls.Error], [fs.ErrInvalid], [fs.ErrNotExist],
|
|
// [fs.ErrExist], [fs.ErrPermission], [fs.ErrClosed], [io.EOF]
|
|
// to valid negative error to system respective
|
|
func ErrorToStatus(err error) int {
|
|
if err == nil { // return OK
|
|
return 0
|
|
}
|
|
|
|
// Chec type
|
|
switch v := err.(type) {
|
|
case syscall.Errno:
|
|
return -int(v)
|
|
case fuse.Error:
|
|
return -int(v)
|
|
case *fs.PathError:
|
|
return ErrorToStatus(v.Err)
|
|
case *os.LinkError:
|
|
return ErrorToStatus(v.Err)
|
|
case *os.SyscallError:
|
|
return ErrorToStatus(v.Err)
|
|
}
|
|
|
|
// Check types of error
|
|
switch {
|
|
case errors.Is(err, fs.ErrInvalid):
|
|
return -int(syscall.EINVAL)
|
|
case errors.Is(err, fs.ErrNotExist):
|
|
return -int(syscall.ENOENT)
|
|
case errors.Is(err, fs.ErrExist):
|
|
return -int(syscall.EEXIST)
|
|
case errors.Is(err, fs.ErrPermission):
|
|
return -int(syscall.EPERM)
|
|
case errors.Is(err, fs.ErrClosed):
|
|
return -int(syscall.EBADF)
|
|
case errors.Is(err, io.ErrUnexpectedEOF):
|
|
return -1
|
|
case errors.Is(err, io.EOF):
|
|
return 0
|
|
}
|
|
|
|
// return default error
|
|
return -int(syscall.EIO)
|
|
}
|