local: continue listing files/folders when a circular symlink is detected
Before this change a circular symlink would cause rclone to error out from the listings. After this change rclone will skip a circular symlink and carry on the listing, producing an error at the end. Fixes #4743
This commit is contained in:
parent
2708a7569e
commit
95d0410baa
3 changed files with 41 additions and 2 deletions
|
@ -456,8 +456,8 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e
|
||||||
if f.opt.FollowSymlinks && (mode&os.ModeSymlink) != 0 {
|
if f.opt.FollowSymlinks && (mode&os.ModeSymlink) != 0 {
|
||||||
localPath := filepath.Join(fsDirPath, name)
|
localPath := filepath.Join(fsDirPath, name)
|
||||||
fi, err = os.Stat(localPath)
|
fi, err = os.Stat(localPath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) || isCircularSymlinkError(err) {
|
||||||
// Skip bad symlinks
|
// Skip bad symlinks and circular symlinks
|
||||||
err = fserrors.NoRetryError(errors.Wrap(err, "symlink"))
|
err = fserrors.NoRetryError(errors.Wrap(err, "symlink"))
|
||||||
fs.Errorf(newRemote, "Listing error: %v", err)
|
fs.Errorf(newRemote, "Listing error: %v", err)
|
||||||
err = accounting.Stats(ctx).Error(err)
|
err = accounting.Stats(ctx).Error(err)
|
||||||
|
|
22
backend/local/symlink.go
Normal file
22
backend/local/symlink.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// +build !windows,!plan9,!js
|
||||||
|
|
||||||
|
package local
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// isCircularSymlinkError checks if the current error code is because of a circular symlink
|
||||||
|
func isCircularSymlinkError(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
if newerr, ok := err.(*os.PathError); ok {
|
||||||
|
if errcode, ok := newerr.Err.(syscall.Errno); ok {
|
||||||
|
if errcode == syscall.ELOOP {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
17
backend/local/symlink_other.go
Normal file
17
backend/local/symlink_other.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// +build windows plan9 js
|
||||||
|
|
||||||
|
package local
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// isCircularSymlinkError checks if the current error code is because of a circular symlink
|
||||||
|
func isCircularSymlinkError(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "The name of the file cannot be resolved by the system") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
Loading…
Reference in a new issue