[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master ddc1ff5: Port recent rename changes to RHEL 7 + NFS
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master ddc1ff5: Port recent rename changes to RHEL 7 + NFS |
Date: |
Thu, 3 Aug 2017 19:19:27 -0400 (EDT) |
branch: master
commit ddc1ff58dec92a782b233d97a254fc41c1c887eb
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Port recent rename changes to RHEL 7 + NFS
Problem reported by Ted Zlatanov in:
http://lists.gnu.org/archive/html/emacs-devel/2017-08/msg00082.html
* src/fileio.c (Frename_file): On RHEL 7 + NFS, renameat2 can fail
with errno == EINVAL when it is not supported. So treat that case
like errno == ENOSYS. Also, when ok_if_already_exists is neither
nil nor an integer, just call plain rename; this avoids an extra
syscall to renameat2 when the latter fails with errno == EINVAL or
ENOSYS or ENOENT.
---
src/fileio.c | 45 ++++++++++++++++++++++++++++++---------------
1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/src/fileio.c b/src/fileio.c
index 0264c9f..db760d9 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2344,23 +2344,38 @@ This is what happens in interactive use with M-x. */)
encoded_file = ENCODE_FILE (file);
encoded_newname = ENCODE_FILE (newname);
- if (renameat_noreplace (AT_FDCWD, SSDATA (encoded_file),
- AT_FDCWD, SSDATA (encoded_newname))
- == 0)
- return Qnil;
- int rename_errno = errno;
+ /* If the filesystem is case-insensitive and the file names are
+ identical but for the case, don't worry whether the destination
+ already exists: the caller simply wants to change the letter-case
+ of the file name. */
+ bool plain_rename
+ = ((!NILP (ok_if_already_exists) && !INTEGERP (ok_if_already_exists))
+ || (file_name_case_insensitive_p (SSDATA (encoded_file))
+ && ! NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))));
+
+ int rename_errno;
+ if (!plain_rename)
+ {
+ if (renameat_noreplace (AT_FDCWD, SSDATA (encoded_file),
+ AT_FDCWD, SSDATA (encoded_newname))
+ == 0)
+ return Qnil;
+
+ rename_errno = errno;
+ switch (rename_errno)
+ {
+ case EEXIST: case EINVAL: case ENOSYS:
+ barf_or_query_if_file_exists (newname, rename_errno == EEXIST,
+ "rename to it",
+ INTEGERP (ok_if_already_exists),
+ false);
+ plain_rename = true;
+ break;
+ }
+ }
- if (rename_errno == EEXIST || rename_errno == ENOSYS)
+ if (plain_rename)
{
- /* If the filesystem is case-insensitive and the file names are
- identical but for the case, don't ask for confirmation: they
- simply want to change the letter-case of the file name. */
- if ((NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists))
- && (! file_name_case_insensitive_p (SSDATA (encoded_file))
- || NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname)))))
- barf_or_query_if_file_exists (newname, rename_errno == EEXIST,
- "rename to it",
- INTEGERP (ok_if_already_exists), false);
if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) == 0)
return Qnil;
rename_errno = errno;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master ddc1ff5: Port recent rename changes to RHEL 7 + NFS,
Paul Eggert <=