[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Tue Sep 20 13:45:24 MDT 2011


The branch, master has been updated
       via  953feea Make do_readlink() support fake-super w/o O_NOFOLLOW.
      from  3417881 Make --delete-excluded work better with --filter=merge.

;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 953feeadd2d02e646edd2a35e3cc8465335a09dc
Author: Wayne Davison <wayned at samba.org>
Date:   Mon Sep 19 09:18:18 2011 -0700

    Make do_readlink() support fake-super w/o O_NOFOLLOW.

-----------------------------------------------------------------------

Summary of changes:
 syscall.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 48 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/syscall.c b/syscall.c
index c6c571a..6d51d3c 100644
--- a/syscall.c
+++ b/syscall.c
@@ -87,7 +87,7 @@ ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
 {
 	/* For --fake-super, we read the link from the file. */
 	if (am_root < 0) {
-		int fd = open(path, O_RDONLY|O_NOFOLLOW);
+		int fd = do_open_nofollow(path, O_RDONLY);
 		if (fd >= 0) {
 			int len = read(fd, buf, bufsiz);
 			close(fd);
@@ -443,3 +443,50 @@ int do_fallocate(int fd, OFF_T offset, OFF_T length)
 #endif
 }
 #endif
+
+int do_open_nofollow(const char *pathname, int flags)
+{
+#ifndef O_NOFOLLOW
+	struct stat f_st, l_st;
+#endif
+	int fd;
+
+	if (flags != O_RDONLY) {
+		RETURN_ERROR_IF(dry_run, 0);
+		RETURN_ERROR_IF_RO_OR_LO;
+#ifndef O_NOFOLLOW
+		/* This function doesn't support write attempts w/o O_NOFOLLOW. */
+		errno = EINVAL;
+		return -1;
+#endif
+	}
+
+#ifdef O_NOFOLLOW
+	fd = open(pathname, flags|O_NOFOLLOW);
+#else
+	if ((fd = open(pathname, flags)) < 0)
+		return fd;
+
+	if (do_fstat(fd, &f_st) < 0) {
+	  close_and_return_error:
+		{
+			int save_errno = errno;
+			close(fd);
+			errno = save_errno;
+		}
+		return -1;
+	}
+	if (do_lstat(pathname, &l_st) < 0)
+		goto close_and_return_error;
+	if (S_ISLNK(l_st.st_mode)) {
+		errno = ELOOP;
+		goto close_and_return_error;
+	}
+	if (l_st.st_dev != f_st.st_dev || l_st.st_ino != f_st.st_ino) {
+		errno = EINVAL;
+		goto close_and_return_error;
+	}
+#endif
+
+	return fd;
+}


-- 
The rsync repository.


More information about the rsync-cvs mailing list