Function: rename-file
rename-file is an interactive function defined in fileio.c.
Signature
(rename-file FILE NEWNAME &optional OK-IF-ALREADY-EXISTS)
Documentation
Rename FILE as NEWNAME. Both args must be strings.
If file has names other than FILE, it continues to have those names. If NEWNAME is a directory name, rename FILE to a like-named file under NEWNAME. For NEWNAME to be recognized as a directory name, it should end in a slash.
Signal a file-already-exists error if a file NEWNAME already exists
unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
An integer third arg means request confirmation if NEWNAME already exists.
This is what happens in interactive use with M-x.
Other relevant functions are documented in the file group.
Probably introduced at or before Emacs version 17.
Key Bindings
Shortdoc
;; file
(rename-file "/tmp/foo" "/tmp/newname")
Source Code
// Defined in /usr/src/emacs/src/fileio.c
{
Lisp_Object handler;
Lisp_Object encoded_file, encoded_newname;
file = Fexpand_file_name (file, Qnil);
/* If the filesystem is case-insensitive and the file names are
identical but for case, treat it as a change-case request, and do
not worry whether NEWNAME exists or whether it is a directory, as
it is already another name for FILE. */
bool case_only_rename = false;
#if defined CYGWIN || defined DOS_NT
if (!NILP (Ffile_name_case_insensitive_p (file)))
{
newname = Fexpand_file_name (newname, Qnil);
case_only_rename = !NILP (Fstring_equal (Fdowncase (file),
Fdowncase (newname)));
}
#endif
if (!case_only_rename)
newname = expand_cp_target (Fdirectory_file_name (file), newname);
/* If the file name has special constructs in it,
call the corresponding file name handler. */
handler = Ffind_file_name_handler (file, Qrename_file);
if (NILP (handler))
handler = Ffind_file_name_handler (newname, Qrename_file);
if (!NILP (handler))
return calln (handler, Qrename_file,
file, newname, ok_if_already_exists);
encoded_file = ENCODE_FILE (file);
encoded_newname = ENCODE_FILE (newname);
bool plain_rename = (case_only_rename
|| (!NILP (ok_if_already_exists)
&& !FIXNUMP (ok_if_already_exists)));
int rename_errno UNINIT;
if (!plain_rename)
{
if (emacs_renameat_noreplace (AT_FDCWD,
SSDATA (encoded_file),
AT_FDCWD,
SSDATA (encoded_newname))
== 0)
return Qnil;
rename_errno = errno;
switch (rename_errno)
{
case EEXIST: case EINVAL: case ENOSYS:
#if ENOSYS != ENOTSUP
case ENOTSUP:
#endif
barf_or_query_if_file_exists (newname, rename_errno == EEXIST,
"rename to it",
FIXNUMP (ok_if_already_exists),
false);
plain_rename = true;
break;
}
}
if (plain_rename)
{
if (emacs_rename (SSDATA (encoded_file),
SSDATA (encoded_newname)) == 0)
return Qnil;
rename_errno = errno;
/* Don't prompt again. */
ok_if_already_exists = Qt;
}
else if (!NILP (ok_if_already_exists))
ok_if_already_exists = Qt;
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 (emacs_fstatat (AT_FDCWD, SSDATA (encoded_file),
&file_st, AT_SYMLINK_NOFOLLOW)
!= 0)
report_file_error ("Renaming", list2 (file, newname));
dirp = S_ISDIR (file_st.st_mode) != 0;
}
if (dirp)
calln (Qcopy_directory, file, newname, Qt, Qnil);
else if (S_ISREG (file_st.st_mode))
Fcopy_file (file, newname, ok_if_already_exists, Qt, Qt, Qt);
else if (S_ISLNK (file_st.st_mode))
{
Lisp_Object target = emacs_readlinkat (AT_FDCWD,
SSDATA (encoded_file));
if (!NILP (target))
Fmake_symbolic_link (target, newname, ok_if_already_exists);
else
report_file_error ("Renaming", list2 (file, newname));
}
else
report_file_errno ("Renaming", list2 (file, newname), rename_errno);
specpdl_ref count = SPECPDL_INDEX ();
specbind (Qdelete_by_moving_to_trash, Qnil);
if (dirp)
calln (Qdelete_directory, file, Qt);
else
calln (Qdelete_file, file, Qnil);
return unbind_to (count, Qnil);
}