aboutsummaryrefslogtreecommitdiffstats
path: root/src/sysdep.c
diff options
context:
space:
mode:
authorPaul Eggert2017-08-02 01:53:46 -0700
committerPaul Eggert2017-08-02 01:59:32 -0700
commit1f9f514e7c2ba41b0954d0141f99652f6a53a107 (patch)
tree37d6a253a4db4b6ff2a46e9a7ac512cbe1938c71 /src/sysdep.c
parent5656492d04aa1a82747ff167d8063bbd7950597e (diff)
downloademacs-1f9f514e7c2ba41b0954d0141f99652f6a53a107.tar.gz
emacs-1f9f514e7c2ba41b0954d0141f99652f6a53a107.zip
When renaming a file, ask only if EEXIST or ENOSYS
* src/fileio.c (Frename_file): Avoid calling Ffile_directory_p more than once on FILE. Use renameat_noreplace, so that we can ask the user (and unlink and retry) only if this fails with errno == EEXIST or ENOSYS. This avoids the need to ask the user for permission to do an operation that will fail anyway. Simplify computation of ok_if_already_exists for subsidiary functions. * src/filelock.c (rename_lock_file): Prefer renameat_noreplace if it works, as this avoids the need to link and unlink. * src/lisp.h (renameat_noreplace): New decl. * src/sysdep.c [HAVE_LINUX_FS_H]: Include linux/fs.h and sys/syscall.h. (renameat_noreplace): New function.
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index db99f53299c..22446b25d16 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -37,6 +37,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
37#include "sysselect.h" 37#include "sysselect.h"
38#include "blockinput.h" 38#include "blockinput.h"
39 39
40#ifdef HAVE_LINUX_FS_H
41# include <linux/fs.h>
42# include <sys/syscall.h>
43#endif
44
40#if defined DARWIN_OS || defined __FreeBSD__ 45#if defined DARWIN_OS || defined __FreeBSD__
41# include <sys/sysctl.h> 46# include <sys/sysctl.h>
42#endif 47#endif
@@ -2678,6 +2683,21 @@ set_file_times (int fd, const char *filename,
2678 timespec[1] = mtime; 2683 timespec[1] = mtime;
2679 return fdutimens (fd, filename, timespec); 2684 return fdutimens (fd, filename, timespec);
2680} 2685}
2686
2687/* Rename directory SRCFD's entry SRC to directory DSTFD's entry DST.
2688 This is like renameat except that it fails if DST already exists,
2689 or if this operation is not supported atomically. Return 0 if
2690 successful, -1 (setting errno) otherwise. */
2691int
2692renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst)
2693{
2694#ifdef SYS_renameat2
2695 return syscall (SYS_renameat2, srcfd, src, dstfd, dst, RENAME_NOREPLACE);
2696#else
2697 errno = ENOSYS;
2698 return -1;
2699#endif
2700}
2681 2701
2682/* Like strsignal, except async-signal-safe, and this function typically 2702/* Like strsignal, except async-signal-safe, and this function typically
2683 returns a string in the C locale rather than the current locale. */ 2703 returns a string in the C locale rather than the current locale. */