summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-01-10 10:34:09 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2022-01-10 10:38:04 -0800
commit66c5e7dd3aa58bde7a928867a763bf7e11206c93 (patch)
treef07d59cdd9ecdc80e75615006da012175eab2d5c /lib
parent8d8e9c85c1e017537b36453b4ed559fdd98483bf (diff)
downloadgnulib-66c5e7dd3aa58bde7a928867a763bf7e11206c93.tar.gz
backupfile: fix bug when renaming not from wd
* lib/backupfile.c (backupfile_internal): Fix bug when DIR_FD does not specify the working directory, and when RENAME. Without the bug fix, FILE is treated as relative to the working directory, not relative to DIR_FD, when renaming FILE. This bug was introduced when DIR_FD and RENAME were introduced, in 2018-10-24T02:10:21Z!eggert@cs.ucla.edu. While we’re at it, when SDIR is nonnegative improve performance a bit by passing an SDIR-relative old name to renameatu.
Diffstat (limited to 'lib')
-rw-r--r--lib/backupfile.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/lib/backupfile.c b/lib/backupfile.c
index ac4b0f4677..1e9290a187 100644
--- a/lib/backupfile.c
+++ b/lib/backupfile.c
@@ -332,7 +332,7 @@ backupfile_internal (int dir_fd, char const *file,
return s;
DIR *dirp = NULL;
- int sdir = -1;
+ int sdir = AT_FDCWD;
idx_t base_max = 0;
while (true)
{
@@ -371,13 +371,10 @@ backupfile_internal (int dir_fd, char const *file,
if (! rename)
break;
- if (sdir < 0)
- {
- sdir = AT_FDCWD;
- base_offset = 0;
- }
+ int olddirfd = sdir < 0 ? dir_fd : sdir;
+ idx_t offset = sdir < 0 ? 0 : base_offset;
unsigned flags = backup_type == simple_backups ? 0 : RENAME_NOREPLACE;
- if (renameatu (AT_FDCWD, file, sdir, s + base_offset, flags) == 0)
+ if (renameatu (olddirfd, file + offset, sdir, s + offset, flags) == 0)
break;
int e = errno;
if (! (e == EEXIST && extended))