diff options
| author | Michael Albinus | 2017-08-12 12:30:39 +0200 |
|---|---|---|
| committer | Michael Albinus | 2017-08-12 12:30:39 +0200 |
| commit | ec5cfaa4568327b5b0b299be2664f7fdae123292 (patch) | |
| tree | 7d79d2a4fd23960763365e192b5934e872f0534c /lisp | |
| parent | e94b0d4d54e39b2601b7f3f724d6c6d8a556e89f (diff) | |
| download | emacs-ec5cfaa4568327b5b0b299be2664f7fdae123292.tar.gz emacs-ec5cfaa4568327b5b0b299be2664f7fdae123292.zip | |
Implement EXCL of write-region for Tramp
* lisp/net/ange-ftp.el (ange-ftp-write-region):
* lisp/net/tramp-adb.el (tramp-adb-handle-write-region)
* lisp/net/tramp-gvfs.el (tramp-gvfs-handle-write-region):
* lisp/net/tramp-sh.el (tramp-sh-handle-write-region)
* lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
Implement MUSTBENEW.
* lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file)
* lisp/net/tramp-sh.el (tramp-sh-handle-make-symbolic-link)
(tramp-sh-handle-add-name-to-file)
(tramp-do-copy-or-rename-file)
* lisp/net/tramp-smb.el (tramp-smb-handle-make-symbolic-link):
Adapt error message for `file-already-exists'.
* src/lisp.h:
* src/eval.c (call8): New function.
* src/fileio.c (write_region): Pass also lockname and
mustbenew to the file name handler.
* test/lisp/net/tramp-tests.el (tramp-test10-write-region):
Add tests for MUSTBENEW.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/net/ange-ftp.el | 6 | ||||
| -rw-r--r-- | lisp/net/tramp-adb.el | 16 | ||||
| -rw-r--r-- | lisp/net/tramp-gvfs.el | 20 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 36 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 23 |
5 files changed, 47 insertions, 54 deletions
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index ecb60e5a4f4..ebc14693f65 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el | |||
| @@ -3223,8 +3223,12 @@ system TYPE.") | |||
| 3223 | (defun ange-ftp-binary-file (file) | 3223 | (defun ange-ftp-binary-file (file) |
| 3224 | (string-match-p ange-ftp-binary-file-name-regexp file)) | 3224 | (string-match-p ange-ftp-binary-file-name-regexp file)) |
| 3225 | 3225 | ||
| 3226 | (defun ange-ftp-write-region (start end filename &optional append visit) | 3226 | (defun ange-ftp-write-region |
| 3227 | (start end filename &optional append visit _lockname mustbenew) | ||
| 3227 | (setq filename (expand-file-name filename)) | 3228 | (setq filename (expand-file-name filename)) |
| 3229 | (when mustbenew | ||
| 3230 | (ange-ftp-barf-or-query-if-file-exists | ||
| 3231 | filename "overwrite" (not (eq mustbenew 'excl)))) | ||
| 3228 | (let ((parsed (ange-ftp-ftp-name filename))) | 3232 | (let ((parsed (ange-ftp-ftp-name filename))) |
| 3229 | (if parsed | 3233 | (if parsed |
| 3230 | (let* ((host (nth 0 parsed)) | 3234 | (let* ((host (nth 0 parsed)) |
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 346979000f5..6e662df6e29 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el | |||
| @@ -630,14 +630,17 @@ But handle the case, if the \"test\" command is not available." | |||
| 630 | rw-path))))))) | 630 | rw-path))))))) |
| 631 | 631 | ||
| 632 | (defun tramp-adb-handle-write-region | 632 | (defun tramp-adb-handle-write-region |
| 633 | (start end filename &optional append visit lockname confirm) | 633 | (start end filename &optional append visit lockname mustbenew) |
| 634 | "Like `write-region' for Tramp files." | 634 | "Like `write-region' for Tramp files." |
| 635 | (setq filename (expand-file-name filename)) | 635 | (setq filename (expand-file-name filename)) |
| 636 | (with-parsed-tramp-file-name filename nil | 636 | (with-parsed-tramp-file-name filename nil |
| 637 | (when (and confirm (file-exists-p filename)) | 637 | (when (and mustbenew (file-exists-p filename) |
| 638 | (unless (y-or-n-p (format "File %s exists; overwrite anyway? " | 638 | (or (eq mustbenew 'excl) |
| 639 | filename)) | 639 | (not |
| 640 | (tramp-error v 'file-error "File not overwritten"))) | 640 | (y-or-n-p |
| 641 | (format "File %s exists; overwrite anyway? " filename))))) | ||
| 642 | (tramp-error v 'file-already-exists filename)) | ||
| 643 | |||
| 641 | ;; We must also flush the cache of the directory, because | 644 | ;; We must also flush the cache of the directory, because |
| 642 | ;; `file-attributes' reads the values from there. | 645 | ;; `file-attributes' reads the values from there. |
| 643 | (tramp-flush-file-property v (file-name-directory localname)) | 646 | (tramp-flush-file-property v (file-name-directory localname)) |
| @@ -650,8 +653,7 @@ But handle the case, if the \"test\" command is not available." | |||
| 650 | tmpfile | 653 | tmpfile |
| 651 | (logior (or (file-modes tmpfile) 0) (string-to-number "0600" 8)))) | 654 | (logior (or (file-modes tmpfile) 0) (string-to-number "0600" 8)))) |
| 652 | (tramp-run-real-handler | 655 | (tramp-run-real-handler |
| 653 | 'write-region | 656 | 'write-region (list start end tmpfile append 'no-message lockname)) |
| 654 | (list start end tmpfile append 'no-message lockname confirm)) | ||
| 655 | (with-tramp-progress-reporter | 657 | (with-tramp-progress-reporter |
| 656 | v 3 (format-message | 658 | v 3 (format-message |
| 657 | "Moving tmp file `%s' to `%s'" tmpfile filename) | 659 | "Moving tmp file `%s' to `%s'" tmpfile filename) |
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 4c750df3c40..48f50a3d05a 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el | |||
| @@ -658,8 +658,7 @@ file names." | |||
| 658 | 658 | ||
| 659 | (with-parsed-tramp-file-name (if t1 filename newname) nil | 659 | (with-parsed-tramp-file-name (if t1 filename newname) nil |
| 660 | (when (and (not ok-if-already-exists) (file-exists-p newname)) | 660 | (when (and (not ok-if-already-exists) (file-exists-p newname)) |
| 661 | (tramp-error | 661 | (tramp-error v 'file-already-exists newname)) |
| 662 | v 'file-already-exists "File %s already exists" newname)) | ||
| 663 | 662 | ||
| 664 | (if (or (and equal-remote | 663 | (if (or (and equal-remote |
| 665 | (tramp-get-connection-property v "direct-copy-failed" nil)) | 664 | (tramp-get-connection-property v "direct-copy-failed" nil)) |
| @@ -1172,12 +1171,16 @@ file-notify events." | |||
| 1172 | 'rename-file (list filename newname ok-if-already-exists)))) | 1171 | 'rename-file (list filename newname ok-if-already-exists)))) |
| 1173 | 1172 | ||
| 1174 | (defun tramp-gvfs-handle-write-region | 1173 | (defun tramp-gvfs-handle-write-region |
| 1175 | (start end filename &optional append visit lockname confirm) | 1174 | (start end filename &optional append visit lockname mustbenew) |
| 1176 | "Like `write-region' for Tramp files." | 1175 | "Like `write-region' for Tramp files." |
| 1176 | (setq filename (expand-file-name filename)) | ||
| 1177 | (with-parsed-tramp-file-name filename nil | 1177 | (with-parsed-tramp-file-name filename nil |
| 1178 | (when (and confirm (file-exists-p filename)) | 1178 | (when (and mustbenew (file-exists-p filename) |
| 1179 | (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) | 1179 | (or (eq mustbenew 'excl) |
| 1180 | (tramp-error v 'file-error "File not overwritten"))) | 1180 | (not |
| 1181 | (y-or-n-p | ||
| 1182 | (format "File %s exists; overwrite anyway? " filename))))) | ||
| 1183 | (tramp-error v 'file-already-exists filename)) | ||
| 1181 | 1184 | ||
| 1182 | (let ((tmpfile (tramp-compat-make-temp-file filename))) | 1185 | (let ((tmpfile (tramp-compat-make-temp-file filename))) |
| 1183 | (when (and append (file-exists-p filename)) | 1186 | (when (and append (file-exists-p filename)) |
| @@ -1186,10 +1189,7 @@ file-notify events." | |||
| 1186 | ;; modtime data to be clobbered from the temp file. We call | 1189 | ;; modtime data to be clobbered from the temp file. We call |
| 1187 | ;; `set-visited-file-modtime' ourselves later on. | 1190 | ;; `set-visited-file-modtime' ourselves later on. |
| 1188 | (tramp-run-real-handler | 1191 | (tramp-run-real-handler |
| 1189 | 'write-region | 1192 | 'write-region (list start end tmpfile append 'no-message lockname)) |
| 1190 | (if confirm ; don't pass this arg unless defined for backward compat. | ||
| 1191 | (list start end tmpfile append 'no-message lockname confirm) | ||
| 1192 | (list start end tmpfile append 'no-message lockname))) | ||
| 1193 | (condition-case nil | 1193 | (condition-case nil |
| 1194 | (rename-file tmpfile filename 'ok-if-already-exists) | 1194 | (rename-file tmpfile filename 'ok-if-already-exists) |
| 1195 | (error | 1195 | (error |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 4beb6fe5216..6b365c10e25 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1085,8 +1085,7 @@ target of the symlink differ." | |||
| 1085 | (format | 1085 | (format |
| 1086 | "File %s already exists; make it a link anyway? " | 1086 | "File %s already exists; make it a link anyway? " |
| 1087 | l-localname))))) | 1087 | l-localname))))) |
| 1088 | (tramp-error | 1088 | (tramp-error l 'file-already-exists l-localname) |
| 1089 | l 'file-already-exists "File %s already exists" l-localname) | ||
| 1090 | (delete-file linkname))) | 1089 | (delete-file linkname))) |
| 1091 | 1090 | ||
| 1092 | ;; If FILENAME is a Tramp name, use just the localname component. | 1091 | ;; If FILENAME is a Tramp name, use just the localname component. |
| @@ -1925,9 +1924,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" | |||
| 1925 | (format | 1924 | (format |
| 1926 | "File %s already exists; make it a new name anyway? " | 1925 | "File %s already exists; make it a new name anyway? " |
| 1927 | newname))) | 1926 | newname))) |
| 1928 | (tramp-error | 1927 | (tramp-error v2 'file-already-exists newname)) |
| 1929 | v2 'file-already-exists | ||
| 1930 | "add-name-to-file: file %s already exists" newname)) | ||
| 1931 | (when ok-if-already-exists (setq ln (concat ln " -f"))) | 1928 | (when ok-if-already-exists (setq ln (concat ln " -f"))) |
| 1932 | (tramp-flush-file-property v2 (file-name-directory v2-localname)) | 1929 | (tramp-flush-file-property v2 (file-name-directory v2-localname)) |
| 1933 | (tramp-flush-file-property v2 v2-localname) | 1930 | (tramp-flush-file-property v2 v2-localname) |
| @@ -2041,8 +2038,7 @@ file names." | |||
| 2041 | 2038 | ||
| 2042 | (with-parsed-tramp-file-name (if t1 filename newname) nil | 2039 | (with-parsed-tramp-file-name (if t1 filename newname) nil |
| 2043 | (when (and (not ok-if-already-exists) (file-exists-p newname)) | 2040 | (when (and (not ok-if-already-exists) (file-exists-p newname)) |
| 2044 | (tramp-error | 2041 | (tramp-error v 'file-already-exists newname)) |
| 2045 | v 'file-already-exists "File %s already exists" newname)) | ||
| 2046 | 2042 | ||
| 2047 | (with-tramp-progress-reporter | 2043 | (with-tramp-progress-reporter |
| 2048 | v 0 (format "%s %s to %s" | 2044 | v 0 (format "%s %s to %s" |
| @@ -3150,23 +3146,16 @@ the result will be a local, non-Tramp, file name." | |||
| 3150 | 3146 | ||
| 3151 | ;; CCC grok LOCKNAME | 3147 | ;; CCC grok LOCKNAME |
| 3152 | (defun tramp-sh-handle-write-region | 3148 | (defun tramp-sh-handle-write-region |
| 3153 | (start end filename &optional append visit lockname confirm) | 3149 | (start end filename &optional append visit lockname mustbenew) |
| 3154 | "Like `write-region' for Tramp files." | 3150 | "Like `write-region' for Tramp files." |
| 3155 | (setq filename (expand-file-name filename)) | 3151 | (setq filename (expand-file-name filename)) |
| 3156 | (with-parsed-tramp-file-name filename nil | 3152 | (with-parsed-tramp-file-name filename nil |
| 3157 | ;; Following part commented out because we don't know what to do about | 3153 | (when (and mustbenew (file-exists-p filename) |
| 3158 | ;; file locking, and it does not appear to be a problem to ignore it. | 3154 | (or (eq mustbenew 'excl) |
| 3159 | ;; Ange-ftp ignores it, too. | 3155 | (not |
| 3160 | ;; (when (and lockname (stringp lockname)) | 3156 | (y-or-n-p |
| 3161 | ;; (setq lockname (expand-file-name lockname))) | 3157 | (format "File %s exists; overwrite anyway? " filename))))) |
| 3162 | ;; (unless (or (eq lockname nil) | 3158 | (tramp-error v 'file-already-exists filename)) |
| 3163 | ;; (string= lockname filename)) | ||
| 3164 | ;; (error | ||
| 3165 | ;; "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME")) | ||
| 3166 | |||
| 3167 | (when (and confirm (file-exists-p filename)) | ||
| 3168 | (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) | ||
| 3169 | (tramp-error v 'file-error "File not overwritten"))) | ||
| 3170 | 3159 | ||
| 3171 | (let ((uid (or (tramp-compat-file-attribute-user-id | 3160 | (let ((uid (or (tramp-compat-file-attribute-user-id |
| 3172 | (file-attributes filename 'integer)) | 3161 | (file-attributes filename 'integer)) |
| @@ -3185,8 +3174,7 @@ the result will be a local, non-Tramp, file name." | |||
| 3185 | (file-writable-p localname))))) | 3174 | (file-writable-p localname))))) |
| 3186 | ;; Short track: if we are on the local host, we can run directly. | 3175 | ;; Short track: if we are on the local host, we can run directly. |
| 3187 | (tramp-run-real-handler | 3176 | (tramp-run-real-handler |
| 3188 | 'write-region | 3177 | 'write-region (list start end localname append 'no-message lockname)) |
| 3189 | (list start end localname append 'no-message lockname confirm)) | ||
| 3190 | 3178 | ||
| 3191 | (let* ((modes (save-excursion (tramp-default-file-modes filename))) | 3179 | (let* ((modes (save-excursion (tramp-default-file-modes filename))) |
| 3192 | ;; We use this to save the value of | 3180 | ;; We use this to save the value of |
| @@ -3223,7 +3211,7 @@ the result will be a local, non-Tramp, file name." | |||
| 3223 | (condition-case err | 3211 | (condition-case err |
| 3224 | (tramp-run-real-handler | 3212 | (tramp-run-real-handler |
| 3225 | 'write-region | 3213 | 'write-region |
| 3226 | (list start end tmpfile append 'no-message lockname confirm)) | 3214 | (list start end tmpfile append 'no-message lockname)) |
| 3227 | ((error quit) | 3215 | ((error quit) |
| 3228 | (setq tramp-temp-buffer-file-name nil) | 3216 | (setq tramp-temp-buffer-file-name nil) |
| 3229 | (delete-file tmpfile) | 3217 | (delete-file tmpfile) |
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 1aadd14fb41..367beb823aa 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el | |||
| @@ -137,6 +137,7 @@ call, letting the SMB client use the default one." | |||
| 137 | "NT_STATUS_HOST_UNREACHABLE" | 137 | "NT_STATUS_HOST_UNREACHABLE" |
| 138 | "NT_STATUS_IMAGE_ALREADY_LOADED" | 138 | "NT_STATUS_IMAGE_ALREADY_LOADED" |
| 139 | "NT_STATUS_INVALID_LEVEL" | 139 | "NT_STATUS_INVALID_LEVEL" |
| 140 | "NT_STATUS_INVALID_PARAMETER_MIX" | ||
| 140 | "NT_STATUS_IO_TIMEOUT" | 141 | "NT_STATUS_IO_TIMEOUT" |
| 141 | "NT_STATUS_LOGON_FAILURE" | 142 | "NT_STATUS_LOGON_FAILURE" |
| 142 | "NT_STATUS_NETWORK_ACCESS_DENIED" | 143 | "NT_STATUS_NETWORK_ACCESS_DENIED" |
| @@ -1124,9 +1125,7 @@ target of the symlink differ." | |||
| 1124 | (format | 1125 | (format |
| 1125 | "File %s already exists; make it a new name anyway? " | 1126 | "File %s already exists; make it a new name anyway? " |
| 1126 | linkname))) | 1127 | linkname))) |
| 1127 | (tramp-error | 1128 | (tramp-error v2 'file-already-exists linkname)) |
| 1128 | v2 'file-already-exists | ||
| 1129 | "make-symbolic-link: file %s already exists" linkname)) | ||
| 1130 | (unless (tramp-smb-get-cifs-capabilities v1) | 1129 | (unless (tramp-smb-get-cifs-capabilities v1) |
| 1131 | (tramp-error v2 'file-error "make-symbolic-link not supported")) | 1130 | (tramp-error v2 'file-error "make-symbolic-link not supported")) |
| 1132 | ;; We must also flush the cache of the directory, because | 1131 | ;; We must also flush the cache of the directory, because |
| @@ -1469,14 +1468,17 @@ errors for shares like \"C$/\", which are common in Microsoft Windows." | |||
| 1469 | (error filename)))) | 1468 | (error filename)))) |
| 1470 | 1469 | ||
| 1471 | (defun tramp-smb-handle-write-region | 1470 | (defun tramp-smb-handle-write-region |
| 1472 | (start end filename &optional append visit lockname confirm) | 1471 | (start end filename &optional append visit lockname mustbenew) |
| 1473 | "Like `write-region' for Tramp files." | 1472 | "Like `write-region' for Tramp files." |
| 1474 | (setq filename (expand-file-name filename)) | 1473 | (setq filename (expand-file-name filename)) |
| 1475 | (with-parsed-tramp-file-name filename nil | 1474 | (with-parsed-tramp-file-name filename nil |
| 1476 | (when (and confirm (file-exists-p filename)) | 1475 | (when (and mustbenew (file-exists-p filename) |
| 1477 | (unless (y-or-n-p (format "File %s exists; overwrite anyway? " | 1476 | (or (eq mustbenew 'excl) |
| 1478 | filename)) | 1477 | (not |
| 1479 | (tramp-error v 'file-error "File not overwritten"))) | 1478 | (y-or-n-p |
| 1479 | (format "File %s exists; overwrite anyway? " filename))))) | ||
| 1480 | (tramp-error v 'file-already-exists filename)) | ||
| 1481 | |||
| 1480 | ;; We must also flush the cache of the directory, because | 1482 | ;; We must also flush the cache of the directory, because |
| 1481 | ;; `file-attributes' reads the values from there. | 1483 | ;; `file-attributes' reads the values from there. |
| 1482 | (tramp-flush-file-property v (file-name-directory localname)) | 1484 | (tramp-flush-file-property v (file-name-directory localname)) |
| @@ -1489,10 +1491,7 @@ errors for shares like \"C$/\", which are common in Microsoft Windows." | |||
| 1489 | ;; modtime data to be clobbered from the temp file. We call | 1491 | ;; modtime data to be clobbered from the temp file. We call |
| 1490 | ;; `set-visited-file-modtime' ourselves later on. | 1492 | ;; `set-visited-file-modtime' ourselves later on. |
| 1491 | (tramp-run-real-handler | 1493 | (tramp-run-real-handler |
| 1492 | 'write-region | 1494 | 'write-region (list start end tmpfile append 'no-message lockname)) |
| 1493 | (if confirm ; don't pass this arg unless defined for backward compat. | ||
| 1494 | (list start end tmpfile append 'no-message lockname confirm) | ||
| 1495 | (list start end tmpfile append 'no-message lockname))) | ||
| 1496 | 1495 | ||
| 1497 | (with-tramp-progress-reporter | 1496 | (with-tramp-progress-reporter |
| 1498 | v 3 (format "Moving tmp file %s to %s" tmpfile filename) | 1497 | v 3 (format "Moving tmp file %s to %s" tmpfile filename) |