[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00330] Re: copying from/to a linked file



 しらいです。

In Message-Id <86r7q3eoiw.knu@iDaemons.org>
        "Akinori MUSHA" <knu@iDaemons.org>さんwrites:
>  ファイルのコピーにおいてコピー元とコピー先がリンク(ハード or
> シンボリック)によって実体を同じくする場合、 FDclone でコピーを
> 強行(上書き)するとファイルが破壊されてしまいます。

 実体が同じなので自分自身に上書きしようとして中身を消してし
まう訳ですか。確かにまずいですね。rename(2) だと統合して一つ
の実態になるのでファイル移動だと問題なさそうですけど。


>  *BSD や GNU の cp(1) では stat して st_dev と st_ino が一致
> していたらその旨を表示してコピーを避けるようになっていますが、
> FDclone でも同様の処理にできないでしょうか。

 でも、これって同名ファイルが存在して敢えて「上書き」を選ん
だ場合の処理ですよね?その場合のユーザの意図を重視するなら、
求められる動作は「削除して上書き」ではないでしょうか?
 とは言え、この二つの操作を atomic に行なう system call は
存在しないので、unlink() & creat() だと critical section が
現れてしまいますね。
 となると、実体が一致したら unlink() -> open(E_EXCL) という
処理が妥当なところではないでしょうか。

 という訳でこんな感じではどうでしょう?

---- Cut Here ----
diff -u ../old/FD-2.06/file.c ./file.c
--- ../old/FD-2.06/file.c	Tue Aug 10 00:00:00 2004
+++ ./file.c	Thu Aug 19 23:05:51 2004
@@ -612,11 +612,9 @@
 char *src, *dest;
 struct stat *stp1, *stp2;
 {
-#if	MSDOS
 	struct stat st;
-#endif
 	char buf[BUFSIZ];
-	int i, fd1, fd2, duperrno;
+	int i, fd1, fd2, flags, mode, duperrno;
 
 #if	MSDOS
 	if (!stp2 && Xlstat(dest, &st) >= 0) stp2 = &st;
@@ -628,17 +626,25 @@
 		buf[i] = '\0';
 		return(Xsymlink(buf, dest));
 	}
-	if ((fd1 = Xopen(src, O_BINARY | O_RDONLY, stp1 -> st_mode)) < 0)
-		return(-1);
+
+	flags = (O_BINARY | O_RDONLY);
+	mode = stp1 -> st_mode;
+	if ((fd1 = Xopen(src, flags, mode)) < 0) return(-1);
+
+	flags = (O_BINARY | O_WRONLY | O_CREAT | O_TRUNC);
 #if	MSDOS
-	fd2 = Xopen(dest,
-		O_BINARY | O_WRONLY | O_CREAT | O_TRUNC,
-		stp1 -> st_mode | S_IWRITE);
+	mode |= S_IWRITE;
 #else
-	fd2 = Xopen(dest,
-		O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, stp1 -> st_mode);
+	if (Xstat(dest, &st) >= 0
+	&& st.st_dev == stp1 -> st_dev && st.st_ino == stp1 -> st_ino) {
+		if (Xunlink(dest) < 0) {
+			Xclose(fd1);
+			return(-1);
+		}
+		flags |= O_EXCL;
+	}
 #endif
-	if (fd2 < 0) {
+	if ((fd2 = Xopen(dest, flags, mode)) < 0) {
 		Xclose(fd1);
 		return(-1);
 	}
---- Cut Here ----

                                               しらい たかし