aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeebs <seebs@seebs.net>2016-09-30 10:56:35 -0500
committerSeebs <seebs@seebs.net>2016-09-30 10:56:35 -0500
commitd9ab3a0acc94151048498b1ea4d69e7707df1526 (patch)
tree241cfd00cd1aacc6ec281fabc4e9b4cce9610867
parent7a0632cad851826d804db0540d9a59773e6bf29c (diff)
downloadpseudo-d9ab3a0acc94151048498b1ea4d69e7707df1526.tar.gz
pseudo-d9ab3a0acc94151048498b1ea4d69e7707df1526.tar.bz2
pseudo-d9ab3a0acc94151048498b1ea4d69e7707df1526.zip
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>
-rw-r--r--ChangeLog.txt4
-rw-r--r--ports/unix/guts/renameat.c7
2 files changed, 10 insertions, 1 deletions
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.