diff options
| author | Paul Eggert | 2017-08-02 01:53:46 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-08-02 01:59:32 -0700 |
| commit | 1f9f514e7c2ba41b0954d0141f99652f6a53a107 (patch) | |
| tree | 37d6a253a4db4b6ff2a46e9a7ac512cbe1938c71 /src/sysdep.c | |
| parent | 5656492d04aa1a82747ff167d8063bbd7950597e (diff) | |
| download | emacs-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.c | 20 |
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. */ | ||
| 2691 | int | ||
| 2692 | renameat_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. */ |