From d9ab3a0acc94151048498b1ea4d69e7707df1526 Mon Sep 17 00:00:00 2001 From: Seebs 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 for the bug report and patch. Signed-off-by: Seebs Upstream-Status: Backport Signed-off-by: Joshua Lock --- 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 . + 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 : "", @@ -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