aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorEli Zaretskii2012-08-03 13:23:30 +0300
committerEli Zaretskii2012-08-03 13:23:30 +0300
commit6dad71783c018d3ccabcede7db6ea206de5b3255 (patch)
treea30427f359ae98e4f4f7cc1483cee77371e5ed42 /lisp
parent0948632492830f08805f2c1250a9ababb6baa95a (diff)
downloademacs-6dad71783c018d3ccabcede7db6ea206de5b3255.tar.gz
emacs-6dad71783c018d3ccabcede7db6ea206de5b3255.zip
Support symlinks on latest versions of MS-Windows.
src/w32.c: Include winioctl.h and aclapi.h. (is_symlink, chase_symlinks, enable_privilege, restore_privilege) (revert_to_self): Forward declarations of static functions. <static BOOL g_b_init_get_security_info>: <g_b_init_create_symbolic_link>: New static flags. (globals_of_w32): Initialize them to zero. (GetSecurityInfo_Proc, CreateSymbolicLink_Proc): New typedefs. (map_w32_filename): Improve commentary. Simplify switch. (SYMBOLIC_LINK_FLAG_DIRECTORY): Define if not defined in system headers (most versions of MinGW w32api don't). (get_security_info, create_symbolic_link) (get_file_security_desc_by_handle, is_symlink, chase_symlinks): New functions. (sys_access, sys_chmod): Call 'chase_symlinks' to resolve symlinks in the argument file name. (sys_access): Call unc_volume_file_attributes only if GetFileAttributes fails with network-related error codes. (sys_rename): Diagnose renaming of a symlink when the user doesn't have the required privileges. (get_file_security_desc_by_name): Renamed from get_file_security_desc. (stat_worker): New function, with most of the guts of 'stat', and with addition of handling of symlinks and support for 'lstat'. If possible, get file's attributes and security information by handle, not by name. Produce S_IFLNK bit for symlinks, when called from 'lstat'. (stat, lstat): New functions, call 'stat_worker'. (symlink, readlink, careadlinkat): Rewritten to create and resolve symlinks when the underlying filesystem supports them. lib/src/ntlib.c (lstat): New function, calls 'stat'. nt/inc/sys/stat.h (S_IFLNK): Define. (S_ISLNK): A non-trivial definition. (lstat): Prototype instead of a macro that redirects to 'stat'. lisp/files.el (file-truename): Don't skip symlink-chasing part on windows-nt. Incorporate the resolution of 8+3 short aliases on Windows into the loop that recursively chases symlinks. Compare directory and its parent case-insensitively on MS-Windows and MS-DOS. etc/NEWS: Announce the symlink support on MS-Windows.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/files.el40
2 files changed, 20 insertions, 28 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4bd509ce277..d36cc4574fa 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,11 @@
12012-08-03 Eli Zaretskii <eliz@gnu.org>
2
3 * files.el (file-truename): Don't skip symlink-chasing part on
4 windows-nt. Incorporate the resolution of 8+3 short aliases on
5 Windows into the loop that recursively chases symlinks. Compare
6 directory and its parent case-insensitively on MS-Windows and
7 MS-DOS.
8
12012-08-03 Chong Yidong <cyd@gnu.org> 92012-08-03 Chong Yidong <cyd@gnu.org>
2 10
3 * menu-bar.el (menu-bar-tools-menu): Remove PCL-CVS. 11 * menu-bar.el (menu-bar-tools-menu): Remove PCL-CVS.
diff --git a/lisp/files.el b/lisp/files.el
index 7fc7ccc8553..0c895669542 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1079,9 +1079,7 @@ containing it, until no links are left at any level.
1079 (delq (rassq 'ange-ftp-completion-hook-function tem) tem))))) 1079 (delq (rassq 'ange-ftp-completion-hook-function tem) tem)))))
1080 (or prev-dirs (setq prev-dirs (list nil))) 1080 (or prev-dirs (setq prev-dirs (list nil)))
1081 1081
1082 ;; andrewi@harlequin.co.uk - none of the following code (except for 1082 ;; andrewi@harlequin.co.uk - on Windows, there is an issue with
1083 ;; invoking the file-name handler) currently applies on Windows
1084 ;; (ie. there are no native symlinks), but there is an issue with
1085 ;; case differences being ignored by the OS, and short "8.3 DOS" 1083 ;; case differences being ignored by the OS, and short "8.3 DOS"
1086 ;; name aliases existing for all files. (The short names are not 1084 ;; name aliases existing for all files. (The short names are not
1087 ;; reported by directory-files, but can be used to refer to files.) 1085 ;; reported by directory-files, but can be used to refer to files.)
@@ -1091,31 +1089,15 @@ containing it, until no links are left at any level.
1091 ;; it is stored on disk (expanding short name aliases with the full 1089 ;; it is stored on disk (expanding short name aliases with the full
1092 ;; name in the process). 1090 ;; name in the process).
1093 (if (eq system-type 'windows-nt) 1091 (if (eq system-type 'windows-nt)
1094 (let ((handler (find-file-name-handler filename 'file-truename))) 1092 (unless (string-match "[[*?]" filename)
1095 ;; For file name that has a special handler, call handler. 1093 ;; If filename exists, use its long name. If it doesn't
1096 ;; This is so that ange-ftp can save time by doing a no-op. 1094 ;; exist, the recursion below on the directory of filename
1097 (if handler 1095 ;; will drill down until we find a directory that exists,
1098 (setq filename (funcall handler 'file-truename filename)) 1096 ;; and use the long name of that, with the extra
1099 ;; If filename contains a wildcard, newname will be the old name. 1097 ;; non-existent path components concatenated.
1100 (unless (string-match "[[*?]" filename) 1098 (let ((longname (w32-long-file-name filename)))
1101 ;; If filename exists, use the long name. If it doesn't exist, 1099 (if longname
1102 ;; drill down until we find a directory that exists, and use 1100 (setq filename longname)))))
1103 ;; the long name of that, with the extra non-existent path
1104 ;; components concatenated.
1105 (let ((longname (w32-long-file-name filename))
1106 missing rest)
1107 (if longname
1108 (setq filename longname)
1109 ;; Include the preceding directory separator in the missing
1110 ;; part so subsequent recursion on the rest works.
1111 (setq missing (concat "/" (file-name-nondirectory filename)))
1112 (let ((length (length missing)))
1113 (setq rest
1114 (if (> length (length filename))
1115 ""
1116 (substring filename 0 (- length)))))
1117 (setq filename (concat (file-truename rest) missing))))))
1118 (setq done t)))
1119 1101
1120 ;; If this file directly leads to a link, process that iteratively 1102 ;; If this file directly leads to a link, process that iteratively
1121 ;; so that we don't use lots of stack. 1103 ;; so that we don't use lots of stack.
@@ -1135,6 +1117,8 @@ containing it, until no links are left at any level.
1135 (setq dirfile (directory-file-name dir)) 1117 (setq dirfile (directory-file-name dir))
1136 ;; If these are equal, we have the (or a) root directory. 1118 ;; If these are equal, we have the (or a) root directory.
1137 (or (string= dir dirfile) 1119 (or (string= dir dirfile)
1120 (and (memq system-type '(windows-nt ms-dos cygwin))
1121 (eq (compare-strings dir 0 nil dirfile 0 nil t) t))
1138 ;; If this is the same dir we last got the truename for, 1122 ;; If this is the same dir we last got the truename for,
1139 ;; save time--don't recalculate. 1123 ;; save time--don't recalculate.
1140 (if (assoc dir (car prev-dirs)) 1124 (if (assoc dir (car prev-dirs))