diff src/lib/nfs-workarounds.c @ 6811:9bc620b934f4 HEAD

Added nfs_safe_link().
author Timo Sirainen <tss@iki.fi>
date Thu, 15 Nov 2007 16:27:41 +0200
parents a59deefc552f
children 575235932194
line wrap: on
line diff
--- a/src/lib/nfs-workarounds.c	Thu Nov 15 15:01:27 2007 +0200
+++ b/src/lib/nfs-workarounds.c	Thu Nov 15 16:27:41 2007 +0200
@@ -129,6 +129,35 @@
 	return nfs_safe_do(path, nfs_safe_lstat_callback, buf);
 }
 
+int nfs_safe_link(const char *oldpath, const char *newpath)
+{
+	struct stat st;
+
+#ifdef DEBUG
+	if (stat(oldpath, &st) == 0 && st.st_nlink != 1) {
+		i_panic("nfs_safe_link(): %s link count = %d",
+			oldpath, (int)st.st_nlink);
+	}
+#endif
+	if (link(oldpath, newpath) == 0) {
+#ifndef __FreeBSD__
+		return 0;
+#endif
+		/* FreeBSD at least up to v6.2 converts EEXIST errors to
+		   success. */
+	} else if (errno != EEXIST)
+		return -1;
+
+	/* We don't know if it succeeded or failed. stat() to make sure. */
+	if (stat(oldpath, &st) < 0)
+		return -1;
+	if (st.st_nlink < 2) {
+		errno = EEXIST;
+		return -1;
+	}
+	return 0;
+}
+
 static bool nfs_flush_fchown_uid(const char *path, int fd)
 {
 	struct stat st;