diff options
| author | Paul Eggert | 2022-12-18 12:57:57 -0800 |
|---|---|---|
| committer | Paul Eggert | 2022-12-18 13:04:54 -0800 |
| commit | 79e1bff2694444a27036b08e8fa2a6619b40dc2a (patch) | |
| tree | a633756420ab05ec067902dddf09ee745c4a97eb /src | |
| parent | ab3cfa4a17663cf479f286149a2289974dd67240 (diff) | |
| download | emacs-79e1bff2694444a27036b08e8fa2a6619b40dc2a.tar.gz emacs-79e1bff2694444a27036b08e8fa2a6619b40dc2a.zip | |
Improve rename-file fix (bug#34069)
* src/fileio.c (Frename_file): No need for a special case to
rename a fifo, since we already tried and failed to rename it.
Also improve symlink handling, in that if readlink fails report an
error rather than trying to treat the link as a regular file.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 35 |
1 files changed, 12 insertions, 23 deletions
diff --git a/src/fileio.c b/src/fileio.c index a50f8d67c11..789f3d509e7 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -134,6 +134,7 @@ static dev_t timestamp_file_system; | |||
| 134 | is added here. */ | 134 | is added here. */ |
| 135 | static Lisp_Object Vwrite_region_annotation_buffers; | 135 | static Lisp_Object Vwrite_region_annotation_buffers; |
| 136 | 136 | ||
| 137 | static Lisp_Object emacs_readlinkat (int, char const *); | ||
| 137 | static Lisp_Object file_name_directory (Lisp_Object); | 138 | static Lisp_Object file_name_directory (Lisp_Object); |
| 138 | static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, | 139 | static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 139 | Lisp_Object *, struct coding_system *); | 140 | Lisp_Object *, struct coding_system *); |
| @@ -2710,31 +2711,19 @@ This is what happens in interactive use with M-x. */) | |||
| 2710 | } | 2711 | } |
| 2711 | if (dirp) | 2712 | if (dirp) |
| 2712 | call4 (Qcopy_directory, file, newname, Qt, Qnil); | 2713 | call4 (Qcopy_directory, file, newname, Qt, Qnil); |
| 2713 | else | 2714 | else if (S_ISREG (file_st.st_mode)) |
| 2714 | { | 2715 | Fcopy_file (file, newname, ok_if_already_exists, Qt, Qt, Qt); |
| 2715 | Lisp_Object symlink_target | 2716 | else if (S_ISLNK (file_st.st_mode)) |
| 2716 | = (S_ISLNK (file_st.st_mode) | 2717 | { |
| 2717 | ? check_emacs_readlinkat (AT_FDCWD, file, SSDATA (encoded_file)) | 2718 | Lisp_Object target = emacs_readlinkat (AT_FDCWD, |
| 2718 | : Qnil); | 2719 | SSDATA (encoded_file)); |
| 2719 | if (!NILP (symlink_target)) | 2720 | if (!NILP (target)) |
| 2720 | Fmake_symbolic_link (symlink_target, newname, ok_if_already_exists); | 2721 | Fmake_symbolic_link (target, newname, ok_if_already_exists); |
| 2721 | else if (S_ISFIFO (file_st.st_mode)) | ||
| 2722 | { | ||
| 2723 | /* If it's a FIFO, calling `copy-file' will hang if it's a | ||
| 2724 | inter-file system move, so do it here. (It will signal | ||
| 2725 | an error in that case, but it won't hang in any case.) */ | ||
| 2726 | if (!NILP (ok_if_already_exists)) | ||
| 2727 | barf_or_query_if_file_exists (newname, false, | ||
| 2728 | "rename to it", | ||
| 2729 | FIXNUMP (ok_if_already_exists), | ||
| 2730 | false); | ||
| 2731 | if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) != 0) | ||
| 2732 | report_file_errno ("Renaming", list2 (file, newname), errno); | ||
| 2733 | return Qnil; | ||
| 2734 | } | ||
| 2735 | else | 2722 | else |
| 2736 | Fcopy_file (file, newname, ok_if_already_exists, Qt, Qt, Qt); | 2723 | report_file_error ("Renaming", list2 (file, newname)); |
| 2737 | } | 2724 | } |
| 2725 | else | ||
| 2726 | report_file_errno ("Renaming", list2 (file, newname), rename_errno); | ||
| 2738 | 2727 | ||
| 2739 | specpdl_ref count = SPECPDL_INDEX (); | 2728 | specpdl_ref count = SPECPDL_INDEX (); |
| 2740 | specbind (Qdelete_by_moving_to_trash, Qnil); | 2729 | specbind (Qdelete_by_moving_to_trash, Qnil); |