mirror of
https://github.com/restic/restic.git
synced 2025-08-22 01:51:47 +00:00
fs: Add interface and FS implementations
This adds two implementations of the new `FS` interface: One for the local file system (`Local`) and one for a single file read from an `io.Reader` (`Reader`).
This commit is contained in:
54
internal/fs/fs_track.go
Normal file
54
internal/fs/fs_track.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
// Track is a wrapper around another file system which installs finalizers
|
||||
// for open files which call panic() when they are not closed when the garbage
|
||||
// collector releases them. This can be used to find resource leaks via open
|
||||
// files.
|
||||
type Track struct {
|
||||
FS
|
||||
}
|
||||
|
||||
// Open wraps the Open method of the underlying file system.
|
||||
func (fs Track) Open(name string) (File, error) {
|
||||
f, err := fs.FS.Open(fixpath(name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newTrackFile(debug.Stack(), name, f), nil
|
||||
}
|
||||
|
||||
// OpenFile wraps the OpenFile method of the underlying file system.
|
||||
func (fs Track) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
|
||||
f, err := fs.FS.OpenFile(fixpath(name), flag, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newTrackFile(debug.Stack(), name, f), nil
|
||||
}
|
||||
|
||||
type trackFile struct {
|
||||
File
|
||||
}
|
||||
|
||||
func newTrackFile(stack []byte, filename string, file File) *trackFile {
|
||||
f := &trackFile{file}
|
||||
runtime.SetFinalizer(f, func(f *trackFile) {
|
||||
fmt.Fprintf(os.Stderr, "file %s not closed\n\nStacktrack:\n%s\n", filename, stack)
|
||||
panic("file " + filename + " not closed")
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *trackFile) Close() error {
|
||||
runtime.SetFinalizer(f, nil)
|
||||
return f.File.Close()
|
||||
}
|
Reference in New Issue
Block a user