diff --git a/src/restic/fs/file.go b/src/restic/fs/file.go index be72d925e..f6836eb8b 100644 --- a/src/restic/fs/file.go +++ b/src/restic/fs/file.go @@ -3,6 +3,8 @@ package fs import ( "io" "os" + "path/filepath" + "runtime" ) // File is an open file on a file system. @@ -17,3 +19,113 @@ type File interface { Seek(int64, int) (int64, error) Stat() (os.FileInfo, error) } + +// fixpath returns an absolute path on windows, so restic can open long file +// names. +func fixpath(name string) string { + if runtime.GOOS == "windows" { + abspath, err := filepath.Abs(name) + if err == nil { + return "\\\\?\\" + abspath + } + } + return name +} + +// Chmod changes the mode of the named file to mode. +func Chmod(name string, mode os.FileMode) error { + return os.Chmod(fixpath(name), mode) +} + +// Mkdir creates a new directory with the specified name and permission bits. +// If there is an error, it will be of type *PathError. +func Mkdir(name string, perm os.FileMode) error { + return os.Mkdir(fixpath(name), perm) +} + +// MkdirAll creates a directory named path, +// along with any necessary parents, and returns nil, +// or else returns an error. +// The permission bits perm are used for all +// directories that MkdirAll creates. +// If path is already a directory, MkdirAll does nothing +// and returns nil. +func MkdirAll(path string, perm os.FileMode) error { + return os.MkdirAll(fixpath(path), perm) +} + +// Readlink returns the destination of the named symbolic link. +// If there is an error, it will be of type *PathError. +func Readlink(name string) (string, error) { + return os.Readlink(fixpath(name)) +} + +// Remove removes the named file or directory. +// If there is an error, it will be of type *PathError. +func Remove(name string) error { + return os.Remove(fixpath(name)) +} + +// RemoveAll removes path and any children it contains. +// It removes everything it can but returns the first error +// it encounters. If the path does not exist, RemoveAll +// returns nil (no error). +func RemoveAll(path string) error { + return os.RemoveAll(fixpath(path)) +} + +// Rename renames (moves) oldpath to newpath. +// If newpath already exists, Rename replaces it. +// OS-specific restrictions may apply when oldpath and newpath are in different directories. +// If there is an error, it will be of type *LinkError. +func Rename(oldpath, newpath string) error { + return os.Rename(fixpath(oldpath), fixpath(newpath)) +} + +// Symlink creates newname as a symbolic link to oldname. +// If there is an error, it will be of type *LinkError. +func Symlink(oldname, newname string) error { + return os.Symlink(fixpath(oldname), fixpath(newname)) +} + +// Stat returns a FileInfo structure describing the named file. +// If there is an error, it will be of type *PathError. +func Stat(name string) (os.FileInfo, error) { + return os.Stat(fixpath(name)) +} + +// Lstat returns the FileInfo structure describing the named file. +// If the file is a symbolic link, the returned FileInfo +// describes the symbolic link. Lstat makes no attempt to follow the link. +// If there is an error, it will be of type *PathError. +func Lstat(name string) (os.FileInfo, error) { + return os.Lstat(fixpath(name)) +} + +// Create creates the named file with mode 0666 (before umask), truncating +// it if it already exists. If successful, methods on the returned +// File can be used for I/O; the associated file descriptor has mode +// O_RDWR. +// If there is an error, it will be of type *PathError. +func Create(name string) (*os.File, error) { + return os.Create(fixpath(name)) +} + +// OpenFile is the generalized open call; most users will use Open +// or Create instead. It opens the named file with specified flag +// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, +// methods on the returned File can be used for I/O. +// If there is an error, it will be of type *PathError. +func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) { + return os.OpenFile(fixpath(name), flag, perm) +} + +// Walk walks the file tree rooted at root, calling walkFn for each file or +// directory in the tree, including root. All errors that arise visiting files +// and directories are filtered by walkFn. The files are walked in lexical +// order, which makes the output deterministic but means that for very +// large directories Walk can be inefficient. +// Walk does not follow symbolic links. +func Walk(root string, walkFn filepath.WalkFunc) error { + return filepath.Walk(fixpath(root), walkFn) +} diff --git a/src/restic/fs/file_all.go b/src/restic/fs/file_all.go deleted file mode 100644 index 93ce1ba20..000000000 --- a/src/restic/fs/file_all.go +++ /dev/null @@ -1,127 +0,0 @@ -// +build !linux !go1.4 - -package fs - -import ( - "os" - "path/filepath" - "runtime" -) - -func fixpath(name string) string { - if runtime.GOOS == "windows" { - abspath, err := filepath.Abs(name) - if err == nil { - return "\\\\?\\" + abspath - } - } - return name -} - -// Open opens a file for reading. -func Open(name string) (File, error) { - return os.OpenFile(fixpath(name), os.O_RDONLY, 0) -} - -// ClearCache syncs and then removes the file's content from the OS cache. -func ClearCache(f File) error { - return nil -} - -// Chmod changes the mode of the named file to mode. -func Chmod(name string, mode os.FileMode) error { - return os.Chmod(fixpath(name), mode) -} - -// Mkdir creates a new directory with the specified name and permission bits. -// If there is an error, it will be of type *PathError. -func Mkdir(name string, perm os.FileMode) error { - return os.Mkdir(fixpath(name), perm) -} - -// MkdirAll creates a directory named path, -// along with any necessary parents, and returns nil, -// or else returns an error. -// The permission bits perm are used for all -// directories that MkdirAll creates. -// If path is already a directory, MkdirAll does nothing -// and returns nil. -func MkdirAll(path string, perm os.FileMode) error { - return os.MkdirAll(fixpath(path), perm) -} - -// Readlink returns the destination of the named symbolic link. -// If there is an error, it will be of type *PathError. -func Readlink(name string) (string, error) { - return os.Readlink(fixpath(name)) -} - -// Remove removes the named file or directory. -// If there is an error, it will be of type *PathError. -func Remove(name string) error { - return os.Remove(fixpath(name)) -} - -// RemoveAll removes path and any children it contains. -// It removes everything it can but returns the first error -// it encounters. If the path does not exist, RemoveAll -// returns nil (no error). -func RemoveAll(path string) error { - return os.RemoveAll(fixpath(path)) -} - -// Rename renames (moves) oldpath to newpath. -// If newpath already exists, Rename replaces it. -// OS-specific restrictions may apply when oldpath and newpath are in different directories. -// If there is an error, it will be of type *LinkError. -func Rename(oldpath, newpath string) error { - return os.Rename(fixpath(oldpath), fixpath(newpath)) -} - -// Symlink creates newname as a symbolic link to oldname. -// If there is an error, it will be of type *LinkError. -func Symlink(oldname, newname string) error { - return os.Symlink(fixpath(oldname), fixpath(newname)) -} - -// Stat returns a FileInfo structure describing the named file. -// If there is an error, it will be of type *PathError. -func Stat(name string) (os.FileInfo, error) { - return os.Stat(fixpath(name)) -} - -// Lstat returns the FileInfo structure describing the named file. -// If the file is a symbolic link, the returned FileInfo -// describes the symbolic link. Lstat makes no attempt to follow the link. -// If there is an error, it will be of type *PathError. -func Lstat(name string) (os.FileInfo, error) { - return os.Lstat(fixpath(name)) -} - -// Create creates the named file with mode 0666 (before umask), truncating -// it if it already exists. If successful, methods on the returned -// File can be used for I/O; the associated file descriptor has mode -// O_RDWR. -// If there is an error, it will be of type *PathError. -func Create(name string) (*os.File, error) { - return os.Create(fixpath(name)) -} - -// OpenFile is the generalized open call; most users will use Open -// or Create instead. It opens the named file with specified flag -// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, -// methods on the returned File can be used for I/O. -// If there is an error, it will be of type *PathError. -func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) { - return os.OpenFile(fixpath(name), flag, perm) -} - -// Walk walks the file tree rooted at root, calling walkFn for each file or -// directory in the tree, including root. All errors that arise visiting files -// and directories are filtered by walkFn. The files are walked in lexical -// order, which makes the output deterministic but means that for very -// large directories Walk can be inefficient. -// Walk does not follow symbolic links. -func Walk(root string, walkFn filepath.WalkFunc) error { - return filepath.Walk(fixpath(root), walkFn) -} diff --git a/src/restic/fs/file_linux.go b/src/restic/fs/file_linux.go index ef6eff6a6..4e0831b76 100644 --- a/src/restic/fs/file_linux.go +++ b/src/restic/fs/file_linux.go @@ -4,7 +4,6 @@ package fs import ( "os" - "path/filepath" "syscall" "golang.org/x/sys/unix" @@ -56,101 +55,3 @@ func ClearCache(file File) error { return unix.Fadvise(int(f.Fd()), 0, 0, unix.FADV_DONTNEED) } - -// Chmod changes the mode of the named file to mode. -func Chmod(name string, mode os.FileMode) error { - return os.Chmod(name, mode) -} - -// Mkdir creates a new directory with the specified name and permission bits. -// If there is an error, it will be of type *PathError. -func Mkdir(name string, perm os.FileMode) error { - return os.Mkdir(name, perm) -} - -// MkdirAll creates a directory named path, -// along with any necessary parents, and returns nil, -// or else returns an error. -// The permission bits perm are used for all -// directories that MkdirAll creates. -// If path is already a directory, MkdirAll does nothing -// and returns nil. -func MkdirAll(path string, perm os.FileMode) error { - return os.MkdirAll(path, perm) -} - -// Readlink returns the destination of the named symbolic link. -// If there is an error, it will be of type *PathError. -func Readlink(name string) (string, error) { - return os.Readlink(name) -} - -// Remove removes the named file or directory. -// If there is an error, it will be of type *PathError. -func Remove(name string) error { - return os.Remove(name) -} - -// RemoveAll removes path and any children it contains. -// It removes everything it can but returns the first error -// it encounters. If the path does not exist, RemoveAll -// returns nil (no error). -func RemoveAll(path string) error { - return os.RemoveAll(path) -} - -// Rename renames (moves) oldpath to newpath. -// If newpath already exists, Rename replaces it. -// OS-specific restrictions may apply when oldpath and newpath are in different directories. -// If there is an error, it will be of type *LinkError. -func Rename(oldpath, newpath string) error { - return os.Rename(oldpath, newpath) -} - -// Symlink creates newname as a symbolic link to oldname. -// If there is an error, it will be of type *LinkError. -func Symlink(oldname, newname string) error { - return os.Symlink(oldname, newname) -} - -// Stat returns a FileInfo structure describing the named file. -// If there is an error, it will be of type *PathError. -func Stat(name string) (os.FileInfo, error) { - return os.Stat(name) -} - -// Lstat returns the FileInfo structure describing the named file. -// If the file is a symbolic link, the returned FileInfo -// describes the symbolic link. Lstat makes no attempt to follow the link. -// If there is an error, it will be of type *PathError. -func Lstat(name string) (os.FileInfo, error) { - return os.Lstat(name) -} - -// Create creates the named file with mode 0666 (before umask), truncating -// it if it already exists. If successful, methods on the returned -// File can be used for I/O; the associated file descriptor has mode -// O_RDWR. -// If there is an error, it will be of type *PathError. -func Create(name string) (*os.File, error) { - return os.Create(name) -} - -// OpenFile is the generalized open call; most users will use Open -// or Create instead. It opens the named file with specified flag -// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, -// methods on the returned File can be used for I/O. -// If there is an error, it will be of type *PathError. -func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) { - return os.OpenFile(name, flag, perm) -} - -// Walk walks the file tree rooted at root, calling walkFn for each file or -// directory in the tree, including root. All errors that arise visiting files -// and directories are filtered by walkFn. The files are walked in lexical -// order, which makes the output deterministic but means that for very -// large directories Walk can be inefficient. -// Walk does not follow symbolic links. -func Walk(root string, walkFn filepath.WalkFunc) error { - return filepath.Walk(root, walkFn) -} diff --git a/src/restic/fs/file_nonlinux.go b/src/restic/fs/file_nonlinux.go new file mode 100644 index 000000000..672348074 --- /dev/null +++ b/src/restic/fs/file_nonlinux.go @@ -0,0 +1,15 @@ +// +build !linux !go1.4 + +package fs + +import "os" + +// Open opens a file for reading. +func Open(name string) (File, error) { + return os.OpenFile(fixpath(name), os.O_RDONLY, 0) +} + +// ClearCache syncs and then removes the file's content from the OS cache. +func ClearCache(f File) error { + return nil +}