diff options
author | 2016-09-30 10:56:35 -0500 | |
---|---|---|
committer | 2016-09-30 10:56:35 -0500 | |
commit | d9ab3a0acc94151048498b1ea4d69e7707df1526 (patch) | |
tree | 241cfd00cd1aacc6ec281fabc4e9b4cce9610867 | |
parent | 7a0632cad851826d804db0540d9a59773e6bf29c (diff) | |
download | pseudo-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.txt | 4 | ||||
-rw-r--r-- | ports/unix/guts/renameat.c | 7 |
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. |