瀏覽代碼

Replace directories/links with files (fixes #580)

Audrius Butkevicius 11 年之前
父節點
當前提交
37ebbb53be
共有 3 個文件被更改,包括 15 次插入13 次删除
  1. 14 6
      internal/model/puller.go
  2. 1 1
      test/filetype_test.go
  3. 0 6
      test/symlink_test.go

+ 14 - 6
internal/model/puller.go

@@ -370,12 +370,13 @@ func (p *Puller) handleDir(file protocol.FileInfo) {
 		l.Debugf("need dir\n\t%v\n\t%v", file, curFile)
 	}
 
-	info, err := os.Stat(realName)
+	info, err := os.Lstat(realName)
+	isLink, _ := symlinks.IsSymlink(realName)
 	switch {
-	// There is already something under that name, but it's a file.
-	// Most likely a file is getting replaced with a directory.
-	// Remove the file and fall through to directory creation.
-	case err == nil && !info.IsDir():
+	// There is already something under that name, but it's a file/link.
+	// Most likely a file/link is getting replaced with a directory.
+	// Remove the file/link and fall through to directory creation.
+	case isLink || (err == nil && !info.IsDir()):
 		err = osutil.InWritableDir(os.Remove, realName)
 		if err != nil {
 			l.Infof("Puller (folder %q, dir %q): %v", p.folder, file.Name, err)
@@ -795,7 +796,14 @@ func (p *Puller) finisherRoutine(in <-chan *sharedPullerState) {
 				}
 			}
 
-			// Replace the original file with the new one
+			// If the target path is a symlink or a directory, we cannot copy
+			// over it, hence remove it before proceeding.
+			stat, err := os.Lstat(state.realName)
+			isLink, _ := symlinks.IsSymlink(state.realName)
+			if isLink || (err == nil && stat.IsDir()) {
+				osutil.InWritableDir(os.Remove, state.realName)
+			}
+			// Replace the original content with the new one
 			err = osutil.Rename(state.tempName, state.realName)
 			if err != nil {
 				l.Warnln("puller: final:", err)

+ 1 - 1
test/filetype_test.go

@@ -16,7 +16,7 @@
 // +build integration
 
 // This currently fails; it should be fixed
-package integration_test_disabled
+package integration_test
 
 import (
 	"log"

+ 0 - 6
test/symlink_test.go

@@ -191,8 +191,6 @@ func TestSymlinks(t *testing.T) {
 	}
 	fd.Close()
 
-	/* Currently fails, to be fixed with #80
-
 	// Replace one with a directory
 
 	err = os.Remove("s1/repDirLink")
@@ -204,7 +202,6 @@ func TestSymlinks(t *testing.T) {
 	if err != nil {
 		log.Fatal(err)
 	}
-	*/
 
 	// Replace a file with a symlink
 
@@ -217,8 +214,6 @@ func TestSymlinks(t *testing.T) {
 		log.Fatal(err)
 	}
 
-	/* Currently fails, to be fixed with #80
-
 	// Replace a directory with a symlink
 
 	err = os.RemoveAll("s1/dirToReplace")
@@ -229,7 +224,6 @@ func TestSymlinks(t *testing.T) {
 	if err != nil {
 		log.Fatal(err)
 	}
-	*/
 
 	// Sync these changes and recheck