From: Paul Eggert Date: Thu, 12 Oct 2017 20:08:53 +0000 (-0700) Subject: Let rename-file rename dirs across filesystems X-Git-Tag: emacs-26.0.91~568 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2f4bd2fbda;p=emacs.git 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. --- 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. */) (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists) { Lisp_Object handler; - Lisp_Object encoded_file, encoded_newname, symlink_target; + Lisp_Object encoded_file, encoded_newname; file = Fexpand_file_name (file, Qnil); @@ -2334,12 +2334,22 @@ This is what happens in interactive use with M-x. */) if (rename_errno != EXDEV) report_file_errno ("Renaming", list2 (file, newname), rename_errno); + struct stat file_st; bool dirp = !NILP (Fdirectory_name_p (file)); + if (!dirp) + { + if (lstat (SSDATA (encoded_file), &file_st) != 0) + report_file_error ("Renaming", list2 (file, newname)); + dirp = S_ISDIR (file_st.st_mode) != 0; + } if (dirp) call4 (Qcopy_directory, file, newname, Qt, Qnil); else { - symlink_target = Ffile_symlink_p (file); + Lisp_Object symlink_target + = (S_ISLNK (file_st.st_mode) + ? emacs_readlinkat (AT_FDCWD, SSDATA (encoded_file)) + : Qnil); if (!NILP (symlink_target)) Fmake_symbolic_link (symlink_target, newname, ok_if_already_exists); else