Files
cgofuse/fuse/utils/utils_unix.go
Matheus Sampaio Queiroga 9a774478a2
All checks were successful
Fuse test / go-test (push) Successful in 32s
Merge winfsp to fuse and update fs
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2025-08-18 19:07:05 -03:00

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)
}