feat: Add portable Timespec implementation for FileInfo
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pojntfx/stfs/internal/ioext"
|
"github.com/pojntfx/stfs/internal/ioext"
|
||||||
"github.com/pojntfx/stfs/pkg/cache"
|
"github.com/pojntfx/stfs/pkg/cache"
|
||||||
@@ -124,17 +125,24 @@ func (f *File) syncWithoutLocking() error {
|
|||||||
// Some OSes like i.e. Windows don't support numeric GIDs and UIDs, so use 0 instead
|
// Some OSes like i.e. Windows don't support numeric GIDs and UIDs, so use 0 instead
|
||||||
gid := 0
|
gid := 0
|
||||||
uid := 0
|
uid := 0
|
||||||
|
modTime := f.info.ModTime()
|
||||||
|
accessTime := f.info.ModTime()
|
||||||
|
changeTime := f.info.ModTime()
|
||||||
sys, ok := f.info.Sys().(*Stat)
|
sys, ok := f.info.Sys().(*Stat)
|
||||||
if ok {
|
if ok {
|
||||||
gid = int(sys.Gid)
|
gid = int(sys.Gid)
|
||||||
uid = int(sys.Uid)
|
uid = int(sys.Uid)
|
||||||
|
accessTime = time.Unix(0, sys.Atim.Nano())
|
||||||
|
changeTime = time.Unix(0, sys.Ctim.Nano())
|
||||||
}
|
}
|
||||||
|
|
||||||
f.info = NewFileInfo(
|
f.info = NewFileInfo(
|
||||||
f.info.Name(),
|
f.info.Name(),
|
||||||
size,
|
size,
|
||||||
f.info.Mode(),
|
f.info.Mode(),
|
||||||
f.info.ModTime(),
|
modTime,
|
||||||
|
accessTime,
|
||||||
|
changeTime,
|
||||||
gid,
|
gid,
|
||||||
uid,
|
uid,
|
||||||
f.info.IsDir(),
|
f.info.IsDir(),
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
//go:build windows
|
|
||||||
|
|
||||||
package fs
|
|
||||||
|
|
||||||
type Stat struct {
|
|
||||||
Uid uint32
|
|
||||||
Gid uint32
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
|
|
||||||
package fs
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
type Stat syscall.Stat_t
|
|
||||||
@@ -12,13 +12,15 @@ import (
|
|||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
os.FileInfo
|
os.FileInfo
|
||||||
|
|
||||||
name string
|
name string
|
||||||
size int64
|
size int64
|
||||||
mode fs.FileMode
|
mode fs.FileMode
|
||||||
modTime time.Time
|
modTime time.Time
|
||||||
gid int
|
accessTime time.Time
|
||||||
uid int
|
changeTime time.Time
|
||||||
isDir bool
|
gid int
|
||||||
|
uid int
|
||||||
|
isDir bool
|
||||||
|
|
||||||
log logging.StructuredLogger
|
log logging.StructuredLogger
|
||||||
}
|
}
|
||||||
@@ -28,6 +30,8 @@ func NewFileInfo(
|
|||||||
size int64,
|
size int64,
|
||||||
mode fs.FileMode,
|
mode fs.FileMode,
|
||||||
modTime time.Time,
|
modTime time.Time,
|
||||||
|
accessTime time.Time,
|
||||||
|
changeTime time.Time,
|
||||||
gid int,
|
gid int,
|
||||||
uid int,
|
uid int,
|
||||||
isDir bool,
|
isDir bool,
|
||||||
@@ -35,13 +39,15 @@ func NewFileInfo(
|
|||||||
log logging.StructuredLogger,
|
log logging.StructuredLogger,
|
||||||
) *FileInfo {
|
) *FileInfo {
|
||||||
return &FileInfo{
|
return &FileInfo{
|
||||||
name: name,
|
name: name,
|
||||||
size: size,
|
size: size,
|
||||||
mode: mode,
|
mode: mode,
|
||||||
modTime: modTime,
|
modTime: modTime,
|
||||||
gid: gid,
|
accessTime: accessTime,
|
||||||
uid: uid,
|
changeTime: changeTime,
|
||||||
isDir: isDir,
|
gid: gid,
|
||||||
|
uid: uid,
|
||||||
|
isDir: isDir,
|
||||||
|
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
@@ -53,13 +59,15 @@ func NewFileInfoFromTarHeader(
|
|||||||
log logging.StructuredLogger,
|
log logging.StructuredLogger,
|
||||||
) *FileInfo {
|
) *FileInfo {
|
||||||
return &FileInfo{
|
return &FileInfo{
|
||||||
name: hdr.FileInfo().Name(),
|
name: hdr.FileInfo().Name(),
|
||||||
size: hdr.FileInfo().Size(),
|
size: hdr.FileInfo().Size(),
|
||||||
mode: hdr.FileInfo().Mode(),
|
mode: hdr.FileInfo().Mode(),
|
||||||
modTime: hdr.FileInfo().ModTime(),
|
modTime: hdr.FileInfo().ModTime(),
|
||||||
gid: hdr.Gid,
|
accessTime: hdr.AccessTime,
|
||||||
uid: hdr.Uid,
|
changeTime: hdr.ChangeTime,
|
||||||
isDir: hdr.FileInfo().IsDir(),
|
gid: hdr.Gid,
|
||||||
|
uid: hdr.Uid,
|
||||||
|
isDir: hdr.FileInfo().IsDir(),
|
||||||
|
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
@@ -110,8 +118,11 @@ func (f *FileInfo) Sys() interface{} {
|
|||||||
"name": f.name,
|
"name": f.name,
|
||||||
})
|
})
|
||||||
|
|
||||||
return &Stat{
|
return NewStat(
|
||||||
Uid: uint32(f.uid),
|
uint32(f.uid),
|
||||||
Gid: uint32(f.gid),
|
uint32(f.gid),
|
||||||
}
|
f.modTime.UnixNano(),
|
||||||
|
f.accessTime.UnixNano(),
|
||||||
|
f.changeTime.UnixNano(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
52
internal/fs/fileinfo_non_unix.go
Normal file
52
internal/fs/fileinfo_non_unix.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
//go:build !linux
|
||||||
|
|
||||||
|
package fs
|
||||||
|
|
||||||
|
// From the Go stdlib for linux/amd64
|
||||||
|
type Timespec struct {
|
||||||
|
Sec int64
|
||||||
|
Nsec int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *Timespec) Unix() (sec int64, nsec int64) {
|
||||||
|
return int64(ts.Sec), int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *Timespec) Nano() int64 {
|
||||||
|
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) Timespec {
|
||||||
|
sec := nsec / 1e9
|
||||||
|
nsec = nsec % 1e9
|
||||||
|
if nsec < 0 {
|
||||||
|
nsec += 1e9
|
||||||
|
sec--
|
||||||
|
}
|
||||||
|
|
||||||
|
return Timespec{Sec: sec, Nsec: nsec}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Stat struct {
|
||||||
|
Uid uint32
|
||||||
|
Gid uint32
|
||||||
|
Mtim Timespec
|
||||||
|
Atim Timespec
|
||||||
|
Ctim Timespec
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStat(
|
||||||
|
uid uint32,
|
||||||
|
gid uint32,
|
||||||
|
mtim int64,
|
||||||
|
atim int64,
|
||||||
|
ctim int64,
|
||||||
|
) *Stat {
|
||||||
|
return &Stat{
|
||||||
|
Uid: uid,
|
||||||
|
Gid: gid,
|
||||||
|
Mtim: NsecToTimespec(mtim),
|
||||||
|
Atim: NsecToTimespec(atim),
|
||||||
|
Ctim: NsecToTimespec(ctim),
|
||||||
|
}
|
||||||
|
}
|
||||||
23
internal/fs/fileinfo_unix.go
Normal file
23
internal/fs/fileinfo_unix.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package fs
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
type Stat syscall.Stat_t
|
||||||
|
|
||||||
|
func NewStat(
|
||||||
|
uid uint32,
|
||||||
|
gid uint32,
|
||||||
|
mtim int64,
|
||||||
|
atim int64,
|
||||||
|
ctim int64,
|
||||||
|
) *Stat {
|
||||||
|
return &Stat{
|
||||||
|
Uid: uid,
|
||||||
|
Gid: gid,
|
||||||
|
Mtim: syscall.NsecToTimespec(mtim),
|
||||||
|
Atim: syscall.NsecToTimespec(atim),
|
||||||
|
Ctim: syscall.NsecToTimespec(ctim),
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user