summaryrefslogtreecommitdiff
path: root/src/fileio.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-08-26 18:36:38 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-08-26 18:36:38 -0700
commite8001d4c27e1e33c83b9994aac4d5fc3feada2da (patch)
tree6910256d7cf7723aa1b3f7ab7779b91627ba52f6 /src/fileio.c
parent937d9d7f60460edb1d3f978151599fddcbba2214 (diff)
downloademacs-e8001d4c27e1e33c83b9994aac4d5fc3feada2da.tar.gz
emacs-e8001d4c27e1e33c83b9994aac4d5fc3feada2da.tar.bz2
emacs-e8001d4c27e1e33c83b9994aac4d5fc3feada2da.zip
Do not munge contents of local symbolic links
This lets Emacs deal with arbitrary local symlinks without mishandling their contents (Bug#28156). For example, (progn (shell-command "ln -fs '~' 'x'") (rename-file "x" "/tmp/x")) now consistently creates a symbolic link from '/tmp/x' to '~'. Formerly, it did that only if the working directory was on the same filesystem as /tmp; otherwise, it expanded the '~' to the user's home directory. * lisp/dired.el (dired-get-filename): Use files--name-absolute-system-p instead of rolling our own code. * lisp/files.el (files--name-absolute-system-p): New function. (file-truename, file-chase-links): Use it to avoid mishandling symlink contents that begin with ~. (copy-directory, move-file-to-trash): Use concat rather than expand-file-name, to avoid mishandling symlink contents that begin with ~. * src/fileio.c (Fmake_symbolic_link): Do not expand leading "~" in the target unless interactive. Strip leading "/:" if interactive. (emacs_readlinkat): Do not prepend "/:" to the link target if it starts with "/" and contains ":" before NUL. * test/src/fileio-tests.el (try-link): Rename from try-char, and accept a string instead of a char. All uses changed. (fileio-tests--symlink-failure): Also test leading ~, and "/:", to test the new behavior.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c28
1 files changed, 9 insertions, 19 deletions
diff --git a/src/fileio.c b/src/fileio.c
index fa694249cb7..bbd1a4ef69c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2413,7 +2413,8 @@ DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
Both args must be strings.
Signal a `file-already-exists' error if a file LINKNAME already exists
unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
-An integer third arg means request confirmation if LINKNAME already exists.
+An integer third arg means request confirmation if LINKNAME already
+exists, and expand leading "~" or strip leading "/:" in TARGET.
This happens for interactive use with M-x. */)
(Lisp_Object target, Lisp_Object linkname, Lisp_Object ok_if_already_exists)
{
@@ -2421,21 +2422,15 @@ This happens for interactive use with M-x. */)
Lisp_Object encoded_target, encoded_linkname;
CHECK_STRING (target);
- /* If the link target has a ~, we must expand it to get
- a truly valid file name. Otherwise, do not expand;
- we want to permit links to relative file names. */
- if (SREF (target, 0) == '~')
- target = Fexpand_file_name (target, Qnil);
-
+ if (INTEGERP (ok_if_already_exists))
+ {
+ if (SREF (target, 0) == '~')
+ target = Fexpand_file_name (target, Qnil);
+ else if (SREF (target, 0) == '/' && SREF (target, 1) == ':')
+ target = Fsubstring_no_properties (target, make_number (2), Qnil);
+ }
linkname = expand_cp_target (target, linkname);
- /* If the file name has special constructs in it,
- call the corresponding file handler. */
- handler = Ffind_file_name_handler (target, Qmake_symbolic_link);
- if (!NILP (handler))
- return call4 (handler, Qmake_symbolic_link, target,
- linkname, ok_if_already_exists);
-
/* If the new link name has special constructs in it,
call the corresponding file handler. */
handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
@@ -2633,11 +2628,6 @@ emacs_readlinkat (int fd, char const *filename)
return Qnil;
val = build_unibyte_string (buf);
- if (buf[0] == '/' && strchr (buf, ':'))
- {
- AUTO_STRING (slash_colon, "/:");
- val = concat2 (slash_colon, val);
- }
if (buf != readlink_buf)
xfree (buf);
val = DECODE_FILE (val);