aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2017-10-12 13:08:53 -0700
committerPaul Eggert2017-10-12 13:11:33 -0700
commit2f4bd2fbdaccbaa61fe9b5adb56ba9e8f3d49505 (patch)
tree71e75b38c66ba1554423ac7eccd911bc0b5adaef
parent413978727c9fb1d26b64e81412434064d99ec568 (diff)
downloademacs-2f4bd2fbdaccbaa61fe9b5adb56ba9e8f3d49505.tar.gz
emacs-2f4bd2fbdaccbaa61fe9b5adb56ba9e8f3d49505.zip
Let rename-file rename dirs across filesystems
Problem diagnosed by Andreas Schwab (Bug#28792#65). This fixes a bug that I introduced in 2017-09-10T22:39:24@eggert@cs.ucla.edu "Fix race with rename-file etc. with dir NEWNAME". * src/fileio.c (Frename_file): Copy a source directory across file system boundaries even if its name does not end in slash.
-rw-r--r--src/fileio.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 4bbcec6f178..e57bf46015c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2260,7 +2260,7 @@ This is what happens in interactive use with M-x. */)
2260 (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists) 2260 (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists)
2261{ 2261{
2262 Lisp_Object handler; 2262 Lisp_Object handler;
2263 Lisp_Object encoded_file, encoded_newname, symlink_target; 2263 Lisp_Object encoded_file, encoded_newname;
2264 2264
2265 file = Fexpand_file_name (file, Qnil); 2265 file = Fexpand_file_name (file, Qnil);
2266 2266
@@ -2334,12 +2334,22 @@ This is what happens in interactive use with M-x. */)
2334 if (rename_errno != EXDEV) 2334 if (rename_errno != EXDEV)
2335 report_file_errno ("Renaming", list2 (file, newname), rename_errno); 2335 report_file_errno ("Renaming", list2 (file, newname), rename_errno);
2336 2336
2337 struct stat file_st;
2337 bool dirp = !NILP (Fdirectory_name_p (file)); 2338 bool dirp = !NILP (Fdirectory_name_p (file));
2339 if (!dirp)
2340 {
2341 if (lstat (SSDATA (encoded_file), &file_st) != 0)
2342 report_file_error ("Renaming", list2 (file, newname));
2343 dirp = S_ISDIR (file_st.st_mode) != 0;
2344 }
2338 if (dirp) 2345 if (dirp)
2339 call4 (Qcopy_directory, file, newname, Qt, Qnil); 2346 call4 (Qcopy_directory, file, newname, Qt, Qnil);
2340 else 2347 else
2341 { 2348 {
2342 symlink_target = Ffile_symlink_p (file); 2349 Lisp_Object symlink_target
2350 = (S_ISLNK (file_st.st_mode)
2351 ? emacs_readlinkat (AT_FDCWD, SSDATA (encoded_file))
2352 : Qnil);
2343 if (!NILP (symlink_target)) 2353 if (!NILP (symlink_target))
2344 Fmake_symbolic_link (symlink_target, newname, ok_if_already_exists); 2354 Fmake_symbolic_link (symlink_target, newname, ok_if_already_exists);
2345 else 2355 else