aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2022-12-18 12:57:57 -0800
committerPaul Eggert2022-12-18 13:04:54 -0800
commit79e1bff2694444a27036b08e8fa2a6619b40dc2a (patch)
treea633756420ab05ec067902dddf09ee745c4a97eb /src
parentab3cfa4a17663cf479f286149a2289974dd67240 (diff)
downloademacs-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.c35
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. */
135static Lisp_Object Vwrite_region_annotation_buffers; 135static Lisp_Object Vwrite_region_annotation_buffers;
136 136
137static Lisp_Object emacs_readlinkat (int, char const *);
137static Lisp_Object file_name_directory (Lisp_Object); 138static Lisp_Object file_name_directory (Lisp_Object);
138static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, 139static 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);