Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions filesystem/fat12/directoryentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,23 @@ func (de *directoryEntry) Info() (iofs.FileInfo, error) {
shortName: de.fullShortName(),
size: int64(de.fileSize),
isDir: de.isSubdirectory,
sys: de.stat(),
}, nil
}

func (de *directoryEntry) stat() *StatT {
return &StatT{
ReadOnly: de.isReadOnly,
Hidden: de.isHidden,
System: de.isSystem,
Archive: de.isArchiveDirty,
VolumeLabel: de.isVolumeLabel,
CreateTime: de.createTime,
AccessTime: de.accessTime,
Cluster: de.clusterLocation,
}
}

func (de *directoryEntry) nameMatches(name string) bool {
return strings.EqualFold(de.filenameLong, name) || strings.EqualFold(de.fullShortName(), name)
}
Expand Down
26 changes: 26 additions & 0 deletions filesystem/fat12/fat12_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,32 @@ func TestFat12Stat(t *testing.T) {
}
}

func TestFat12StatSys(t *testing.T) {
_, fs := createFAT12(t, "SYSTEST")
writeFile(t, fs, "/sys.txt", []byte("sys"))

info, err := fs.Stat("sys.txt")
if err != nil {
t.Fatalf("Stat: %v", err)
}
stat, ok := info.Sys().(*fat12.StatT)
if !ok {
t.Fatalf("Sys() did not return *fat12.StatT, got %T", info.Sys())
}
if stat == nil {
t.Fatal("StatT is nil")
}
if stat.Cluster < 2 {
t.Errorf("Cluster = %d, expected >= 2 (data clusters start at 2)", stat.Cluster)
}
if stat.VolumeLabel {
t.Error("regular file should not have VolumeLabel set")
}
if stat.Hidden || stat.System || stat.ReadOnly {
t.Errorf("unexpected attribute bits set: Hidden=%v System=%v ReadOnly=%v", stat.Hidden, stat.System, stat.ReadOnly)
}
}

// ── ReadFile (fs.ReadFileFS) ──────────────────────────────────────────────────

func TestFat12ReadFile(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions filesystem/fat12/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func (fl *File) Stat() (iofs.FileInfo, error) {
shortName: fl.fullShortName(),
size: int64(fl.fileSize),
isDir: fl.isSubdirectory,
sys: fl.stat(),
}, nil
}

Expand Down
19 changes: 17 additions & 2 deletions filesystem/fat12/fileinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ type FileInfo struct {
shortName string
size int64
isDir bool
sys *StatT
}

// StatT carries FAT-specific metadata returned by FileInfo.Sys(). FAT12/16/32
// have no inodes, uid/gid, or POSIX permissions, but they do carry attribute
// flags and additional timestamps that os.FileMode doesn't represent.
type StatT struct {
ReadOnly bool
Hidden bool
System bool
Archive bool
VolumeLabel bool
CreateTime time.Time
AccessTime time.Time
Cluster uint32
}

// IsDir abbreviation for Mode().IsDir()
Expand Down Expand Up @@ -63,9 +78,9 @@ func (fi FileInfo) Size() int64 {
return fi.size
}

// Sys underlying data source - not supported yet and so will return nil
// Sys returns *StatT with FAT-specific metadata.
//
//nolint:gocritic // we need this to comply with fs.FileInfo
func (fi FileInfo) Sys() interface{} {
return nil
return fi.sys
}
3 changes: 3 additions & 0 deletions filesystem/fat16/fat16.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type FileSystem struct {
// interface guard
var _ filesystem.FileSystem = (*FileSystem)(nil)

// StatT is an alias for fat12.StatT, the metadata returned by FileInfo.Sys().
type StatT = fat12.StatT

// Type returns filesystem.TypeFat16, overriding fat12.FileSystem.Type().
func (fs *FileSystem) Type() filesystem.Type { return filesystem.TypeFat16 }

Expand Down
3 changes: 3 additions & 0 deletions filesystem/fat32/fat32.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const (
// is directly usable in fat12.Dos20BPB struct literals.
type SectorSize = fat12.SectorSize

// StatT is an alias for fat12.StatT, the metadata returned by FileInfo.Sys().
type StatT = fat12.StatT

const (
SectorSize512 SectorSize = 512
SectorSize4096 SectorSize = 4096
Expand Down
Loading