From d9ab3a0acc94151048498b1ea4d69e7707df1526 Mon Sep 17 00:00:00 2001
From: Seebs <seebs@seebs.net>
Date: Fri, 30 Sep 2016 10:56:35 -0500
Subject: [PATCH 3/3] Fix renameat (parallel to previous fix to rename)

There was a bug in rename(), which was duplicated when renameat() was
implemented, and which got fixed two years ago for rename(), but no
one ever uses renameat() so it didn't get fixed there. Thanks
to Anton Gerasimov <anton@advancedtelematic.com> for the bug report
and patch.

Signed-off-by: Seebs <seebs@seebs.net>

Upstream-Status: Backport
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>

---
 ChangeLog.txt              | 4 ++++
 ports/unix/guts/renameat.c | 7 ++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/ChangeLog.txt b/ChangeLog.txt
index 65b9759..ca04cc0 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,7 @@
+2016-09-30:
+	* (seebs) Fix rename at, matching fix from ee00f63d for rename. Bug
+	  and fix provided by Anton Gerasimov <anton@advancedtelematic.com>.
+
 2016-09-28:
 	* (seebs) Send errors to log when daemonizing, but do that a lot
 	  sooner to prevent startup messages which can show up spuriously
diff --git a/ports/unix/guts/renameat.c b/ports/unix/guts/renameat.c
index ade0509..d5e36fa 100644
--- a/ports/unix/guts/renameat.c
+++ b/ports/unix/guts/renameat.c
@@ -11,6 +11,7 @@
 	int oldrc, newrc;
 	int save_errno;
 	int old_db_entry = 0;
+	int may_unlinked = 0;
 
 	pseudo_debug(PDBGF_FILE, "renameat: %d,%s->%d,%s\n",
 		olddirfd, oldpath ? oldpath : "<nil>",
@@ -44,10 +45,14 @@
 	/* as with unlink, we have to mark that the file may get deleted */
 	msg = pseudo_client_op(OP_MAY_UNLINK, 0, -1, newdirfd, newpath, newrc ? NULL : &newbuf);
 	if (msg && msg->result == RESULT_SUCCEED)
+		may_unlinked = 1;
+	msg = pseudo_client_op(OP_STAT, 0, -1, olddirfd, oldpath, oldrc ? NULL : &oldbuf);
+	if (msg && msg->result == RESULT_SUCCEED)
 		old_db_entry = 1;
+
 	rc = real_renameat(olddirfd, oldpath, newdirfd, newpath);
 	save_errno = errno;
-	if (old_db_entry) {
+	if (may_unlinked) {
 		if (rc == -1) {
 			/* since we failed, that wasn't really unlinked -- put
 			 * it back.
-- 
2.7.4

