]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp-sh.el
Update copyright year to 2016
[gnu-emacs] / lisp / net / tramp-sh.el
index 9bd22d27d5d87eaa3fbc29ae68aafbc304b6833c..2e6233ade3bbb0cdfedaf7e4920600c3dd97ef7a 100644 (file)
@@ -1,6 +1,6 @@
 ;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
 
-;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2016 Free Software Foundation, Inc.
 
 ;; (copyright statements below in code to be updated with the above notice)
 
@@ -97,7 +97,7 @@ e.g. \"$HOME/.sh_history\"."
    "///%s#$"
    (md5 (concat (prin1-to-string process-environment) (current-time-string))))
   "String used to recognize end of output.
-The ‘$’ character at the end is quoted; the string cannot be
+The `$' character at the end is quoted; the string cannot be
 detected as prompt when being sent on echoing hosts, therefore.")
 
 ;;;###tramp-autoload
@@ -288,7 +288,10 @@ The string is used in `tramp-methods'.")
 (add-to-list 'tramp-methods
   '("sudo"
     (tramp-login-program        "sudo")
-    (tramp-login-args           (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
+    ;; The password template must be masked.  Otherwise, it could be
+    ;; interpreted as password prompt if the remote host echoes the command.
+    (tramp-login-args           (("-u" "%u") ("-s") ("-H")
+                                ("-p" "P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":")))
     ;; Local $SHELL could be a nasty one, like zsh or fish.  Let's override it.
     (tramp-login-env            (("SHELL") ("/bin/sh")))
     (tramp-remote-shell         "/bin/sh")
@@ -483,6 +486,7 @@ The string is used in `tramp-methods'.")
 ;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
 ;; GNU/Linux (Debian, Suse): /bin:/usr/bin
 ;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
+;; Darwin: /usr/bin:/bin:/usr/sbin:/sbin
 ;; IRIX64: /usr/bin
 ;;;###tramp-autoload
 (defcustom tramp-remote-path
@@ -594,9 +598,14 @@ we have this shell function.")
 use File::Spec;
 use Cwd \"realpath\";
 
+sub myrealpath {
+    my ($file) = @_;
+    return realpath($file) if -e $file;
+}
+
 sub recursive {
     my ($volume, @dirs) = @_;
-    my $real = realpath(File::Spec->catpath(
+    my $real = myrealpath(File::Spec->catpath(
                    $volume, File::Spec->catdir(@dirs), \"\"));
     if ($real) {
         my ($vol, $dir) = File::Spec->splitpath($real, 1);
@@ -610,7 +619,7 @@ sub recursive {
     }
 }
 
-$result = realpath($ARGV[0]);
+$result = myrealpath($ARGV[0]);
 if (!$result) {
     my ($vol, $dir) = File::Spec->splitpath($ARGV[0], 1);
     ($vol, @dirs) = recursive($vol, File::Spec->splitdir($dir));
@@ -618,10 +627,7 @@ if (!$result) {
     $result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\");
 }
 
-if ($ARGV[0] =~ /\\/$/) {
-    $result = $result . \"/\";
-}
-
+$result =~ s/\"/\\\\\"/g;
 print \"\\\"$result\\\"\\n\";
 ' \"$1\" 2>/dev/null"
   "Perl script to produce output suitable for use with `file-truename'
@@ -990,10 +996,10 @@ of command line.")
     (file-acl . tramp-sh-handle-file-acl)
     (file-attributes . tramp-sh-handle-file-attributes)
     (file-directory-p . tramp-sh-handle-file-directory-p)
-    ;; `file-equal-p' performed by default handler.
+    (file-equal-p . tramp-handle-file-equal-p)
     (file-executable-p . tramp-sh-handle-file-executable-p)
     (file-exists-p . tramp-sh-handle-file-exists-p)
-    ;; `file-in-directory-p' performed by default handler.
+    (file-in-directory-p . tramp-handle-file-in-directory-p)
     (file-local-copy . tramp-sh-handle-file-local-copy)
     (file-modes . tramp-handle-file-modes)
     (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
@@ -1005,6 +1011,7 @@ of command line.")
     (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
     (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
     (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+    (file-notify-valid-p . tramp-handle-file-notify-valid-p)
     (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
     (file-readable-p . tramp-sh-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
@@ -1112,7 +1119,7 @@ target of the symlink differ."
       method user host
       (with-tramp-file-property v localname "file-truename"
        (let ((result nil))                     ; result steps in reverse order
-         (tramp-message v 4 "Finding true name for ‘%s’" filename)
+         (tramp-message v 4 "Finding true name for `%s'" filename)
          (cond
           ;; Use GNU readlink --canonicalize-missing where available.
           ((tramp-get-remote-readlink v)
@@ -1139,20 +1146,17 @@ target of the symlink differ."
 
           ;; Do it yourself.  We bind `directory-sep-char' here for
           ;; XEmacs on Windows, which would otherwise use backslash.
-          (t (let* ((directory-sep-char ?/)
-                    (steps (tramp-compat-split-string localname "/"))
-                    (localnamedir (tramp-run-real-handler
-                                   'file-name-as-directory (list localname)))
-                    (is-dir (string= localname localnamedir))
-                    (thisstep nil)
-                    (numchase 0)
-                    ;; Don't make the following value larger than
-                    ;; necessary.  People expect an error message in
-                    ;; a timely fashion when something is wrong;
-                    ;; otherwise they might think that Emacs is hung.
-                    ;; Of course, correctness has to come first.
-                    (numchase-limit 20)
-                    symlink-target)
+          (t (let ((directory-sep-char ?/)
+                   (steps (tramp-compat-split-string localname "/"))
+                   (thisstep nil)
+                   (numchase 0)
+                   ;; Don't make the following value larger than
+                   ;; necessary.  People expect an error message in a
+                   ;; timely fashion when something is wrong;
+                   ;; otherwise they might think that Emacs is hung.
+                   ;; Of course, correctness has to come first.
+                   (numchase-limit 20)
+                   symlink-target)
                (while (and steps (< numchase numchase-limit))
                  (setq thisstep (pop steps))
                  (tramp-message
@@ -1170,9 +1174,9 @@ target of the symlink differ."
                                                    (list thisstep))
                                            "/")))))
                  (cond ((string= "." thisstep)
-                        (tramp-message v 5 "Ignoring step ‘.’"))
+                        (tramp-message v 5 "Ignoring step `.'"))
                        ((string= ".." thisstep)
-                        (tramp-message v 5 "Processing step ‘..’")
+                        (tramp-message v 5 "Processing step `..'")
                         (pop result))
                        ((stringp symlink-target)
                         ;; It's a symlink, follow it.
@@ -1188,7 +1192,7 @@ target of the symlink differ."
                           (unless (tramp-equal-remote filename symlink-target)
                             (tramp-error
                              v 'file-error
-                             "Symlink target ‘%s’ on wrong host"
+                             "Symlink target `%s' on wrong host"
                              symlink-target))
                           (setq symlink-target localname))
                         (setq steps
@@ -1208,12 +1212,10 @@ target of the symlink differ."
                      (if result
                          (mapconcat 'identity (cons "" result) "/")
                        "/"))
-               (when (and is-dir
-                          (or (string= "" result)
-                              (not (string= (substring result -1) "/"))))
-                 (setq result (concat result "/"))))))
+               (when (string= "" result)
+                 (setq result "/")))))
 
-         (tramp-message v 4 "True name of ‘%s’ is ‘%s’" localname result)
+         (tramp-message v 4 "True name of `%s' is `%s'" localname result)
          result))))
 
    ;; Preserve trailing "/".
@@ -1272,11 +1274,15 @@ target of the symlink differ."
             (tramp-get-test-command vec)
             (tramp-shell-quote-argument localname)
             (tramp-get-ls-command vec)
+            (if (eq id-format 'integer) "-ildn" "-ild")
             ;; On systems which have no quoting style, file names
             ;; with special characters could fail.
-            (if (tramp-get-ls-command-with-quoting-style vec)
-                "--quoting-style=c" "")
-            (if (eq id-format 'integer) "-ildn" "-ild")
+            (cond
+             ((tramp-get-ls-command-with-quoting-style vec)
+              "--quoting-style=c")
+             ((tramp-get-ls-command-with-w-option vec)
+              "-w")
+             (t ""))
             (tramp-shell-quote-argument localname)))
     ;; Parse `ls -l' output ...
     (with-current-buffer (tramp-get-buffer vec)
@@ -1399,7 +1405,7 @@ target of the symlink differ."
 (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
   "Like `set-visited-file-modtime' for Tramp files."
   (unless (buffer-file-name)
-    (error "Can’t set-visited-file-modtime: buffer ‘%s’ not visiting a file"
+    (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
           (buffer-name)))
   (if time-list
       (tramp-run-real-handler 'set-visited-file-modtime (list time-list))
@@ -1493,7 +1499,7 @@ of."
      (format "chmod %s %s"
             (tramp-compat-decimal-to-octal mode)
             (tramp-shell-quote-argument localname))
-     "Error while changing files mode %s" filename)))
+     "Error while changing file's mode %s" filename)))
 
 (defun tramp-sh-handle-set-file-times (filename &optional time)
   "Like `set-file-times' for Tramp files."
@@ -1833,10 +1839,14 @@ be non-negative integers."
      "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
-    ;; On systems which have no quoting style, file names with
-    ;; special characters could fail.
-    (if (tramp-get-ls-command-with-quoting-style vec)
-       "--quoting-style=shell" "")
+    ;; On systems which have no quoting style, file names with special
+    ;; characters could fail.
+    (cond
+     ((tramp-get-ls-command-with-quoting-style vec)
+      "--quoting-style=shell")
+     ((tramp-get-ls-command-with-w-option vec)
+      "-w")
+     (t ""))
     (tramp-get-remote-stat vec)
     tramp-stat-marker tramp-stat-marker
     tramp-stat-marker tramp-stat-marker
@@ -1967,7 +1977,7 @@ be non-negative integers."
                  (tramp-error
                   v 'file-error
                   "\
-tramp-sh-handle-file-name-all-completions: internal error accessing ‘%s’: ‘%s’"
+tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
                   (tramp-shell-quote-argument localname) (buffer-string))))
 
              (while (zerop (forward-line -1))
@@ -2020,7 +2030,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing ‘%s’: 
         (format "%s %s %s" ln
                 (tramp-shell-quote-argument v1-localname)
                 (tramp-shell-quote-argument v2-localname))
-        "error with add-name-to-file, see buffer ‘%s’ for details"
+        "error with add-name-to-file, see buffer `%s' for details"
         (buffer-name))))))
 
 (defun tramp-sh-handle-copy-file
@@ -2125,7 +2135,7 @@ This function is invoked by `tramp-sh-handle-copy-file' and
 of `copy' and `rename'.  FILENAME and NEWNAME must be absolute
 file names."
   (unless (memq op '(copy rename))
-    (error "Unknown operation ‘%s’, must be ‘copy’ or ‘rename’" op))
+    (error "Unknown operation `%s', must be `copy' or `rename'" op))
   (let ((t1 (tramp-tramp-file-p filename))
        (t2 (tramp-tramp-file-p newname))
        (length (nth 7 (file-attributes (file-truename filename))))
@@ -2265,7 +2275,7 @@ the uid and gid from FILENAME."
                        ((eq op 'rename) "mv -f")
                        (t (tramp-error
                            v 'file-error
-                           "Unknown operation ‘%s’, must be ‘copy’ or ‘rename’"
+                           "Unknown operation `%s', must be `copy' or `rename'"
                            op))))
             (localname1
              (if t1
@@ -2297,7 +2307,7 @@ the uid and gid from FILENAME."
                 cmd-result)
              (tramp-error-with-buffer
               nil v 'file-error
-              "Copying directly failed, see buffer ‘%s’ for details."
+              "Copying directly failed, see buffer `%s' for details."
               (buffer-name)))))
 
         ;; We are on the local host.
@@ -2350,7 +2360,7 @@ the uid and gid from FILENAME."
                          "%s %s %s" cmd
                          (tramp-shell-quote-argument localname1)
                          (tramp-shell-quote-argument tmpfile))
-                      "Copying directly failed, see buffer ‘%s’ for details."
+                      "Copying directly failed, see buffer `%s' for details."
                       (tramp-get-buffer v))
                      ;; We must change the ownership as remote user.
                      ;; Since this does not work reliable, we also
@@ -2388,7 +2398,7 @@ the uid and gid from FILENAME."
                          "cp -f -p %s %s"
                          (tramp-shell-quote-argument tmpfile)
                          (tramp-shell-quote-argument localname2))
-                      "Copying directly failed, see buffer ‘%s’ for details."
+                      "Copying directly failed, see buffer `%s' for details."
                       (tramp-get-buffer v)))
                     (t1
                      (tramp-run-real-handler
@@ -2453,16 +2463,17 @@ The method used must be an out-of-band method."
        (setq source (if t1
                         (tramp-make-copy-program-file-name v)
                       (shell-quote-argument filename))
-             target (funcall
+          target (if t2
+                     (tramp-make-copy-program-file-name v)
+                   (shell-quote-argument
+                    (funcall
                      (if (and (file-directory-p filename)
                               (string-equal
                                (file-name-nondirectory filename)
                                (file-name-nondirectory newname)))
                          'file-name-directory
                        'identity)
-                     (if t2
-                         (tramp-make-copy-program-file-name v)
-                       (shell-quote-argument newname))))
+                     newname))))
 
        ;; Check for host and port number.  We cannot use
        ;; `tramp-file-name-port', because this returns also
@@ -2559,7 +2570,7 @@ The method used must be an out-of-band method."
          (with-timeout
              (60 (tramp-error
                   v 'file-error
-                  "Listener process not running on remote host: ‘%s’"
+                  "Listener process not running on remote host: `%s'"
                   remote-copy-program))
            (tramp-send-command v (format "netstat -l | grep -q :%s" listener))
            (while (not (tramp-send-command-and-check v nil))
@@ -2619,14 +2630,14 @@ The method used must be an out-of-band method."
                      (re-search-backward "tramp_exit_status [0-9]+" nil t)
                    (tramp-error
                     orig-vec 'file-error
-                    "Couldn’t find exit status of ‘%s’"
+                    "Couldn't find exit status of `%s'"
                     (mapconcat 'identity (process-command p) " ")))
                  (skip-chars-forward "^ ")
                  (unless (zerop (read (current-buffer)))
                    (forward-line -1)
                    (tramp-error
                     orig-vec 'file-error
-                    "Error copying: ‘%s’"
+                    "Error copying: `%s'"
                     (buffer-substring (point-min) (point-at-eol))))))
 
            ;; Reset the transfer process properties.
@@ -2665,7 +2676,7 @@ The method used must be an out-of-band method."
        v (format "%s %s"
                 (if parents "mkdir -p" "mkdir")
                 (tramp-shell-quote-argument localname))
-       "Couldnt make directory %s" dir))))
+       "Couldn't make directory %s" dir))))
 
 (defun tramp-sh-handle-delete-directory (directory &optional recursive)
   "Like `delete-directory' for Tramp files."
@@ -2677,7 +2688,7 @@ The method used must be an out-of-band method."
      v (format "cd / && %s %s"
               (if recursive "rm -rf" "rmdir")
               (tramp-shell-quote-argument localname))
-     "Couldnt delete %s" directory)))
+     "Couldn't delete %s" directory)))
 
 (defun tramp-sh-handle-delete-file (filename &optional trash)
   "Like `delete-file' for Tramp files."
@@ -2689,7 +2700,7 @@ The method used must be an out-of-band method."
      v (format "%s %s"
               (or (and trash (tramp-get-remote-trash v)) "rm -f")
               (tramp-shell-quote-argument localname))
-     "Couldnt delete %s" filename)))
+     "Couldn't delete %s" filename)))
 
 ;; Dired.
 
@@ -2800,7 +2811,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
       (when wildcard
        (setq switches (concat switches " " wildcard)))
       (tramp-message
-       v 4 "Inserting directory ‘ls %s %s’, wildcard %s, fulldir %s"
+       v 4 "Inserting directory `ls %s %s', wildcard %s, fulldir %s"
        switches filename (if wildcard "yes" "no")
        (if full-directory-p "yes" "no"))
       ;; If `full-directory-p', we just say `ls -l FILENAME'.
@@ -2819,7 +2830,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
         (format "cd %s" (tramp-shell-quote-argument
                          (tramp-run-real-handler
                           'file-name-directory (list localname))))
-        "Couldn’t ‘cd %s’"
+        "Couldn't `cd %s'"
         (tramp-shell-quote-argument
          (tramp-run-real-handler 'file-name-directory (list localname))))
        (tramp-send-command
@@ -2963,7 +2974,7 @@ the result will be a local, non-Tramp, file name."
   (unless (memq (process-status proc) '(run open))
     (let ((vec (tramp-get-connection-property proc "vector" nil)))
       (when vec
-       (tramp-message vec 5 "Sentinel called: ‘%S’ ‘%s’" proc event)
+       (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event)
         (tramp-flush-connection-property proc)
         (tramp-flush-directory-property vec "")))))
 
@@ -3074,7 +3085,7 @@ the result will be a local, non-Tramp, file name."
                               (tramp-get-connection-process v) 'remote-tty)
                        (tramp-error
                         v 'file-error
-                        "pty association is not supported for ‘%s’" name))))
+                        "pty association is not supported for `%s'" name))))
                  (let ((p (tramp-get-connection-process v)))
                    ;; Set query flag and process marker for this
                    ;; process.  We ignore errors, because the process
@@ -3223,7 +3234,7 @@ the result will be a local, non-Tramp, file name."
     (unless (file-exists-p filename)
       (tramp-error
        v 'file-error
-       "Cannot make local copy of non-existing file ‘%s’" filename))
+       "Cannot make local copy of non-existing file `%s'" filename))
 
     (let* ((size (nth 7 (file-attributes (file-truename filename))))
           (rem-enc (tramp-get-inline-coding v "remote-encoding" size))
@@ -3242,14 +3253,14 @@ the result will be a local, non-Tramp, file name."
            (save-excursion
              (with-tramp-progress-reporter
               v 3
-              (format-message "Encoding remote file ‘%s’ with ‘%s’"
+              (format-message "Encoding remote file `%s' with `%s'"
                                filename rem-enc)
               (tramp-barf-unless-okay
                v (format rem-enc (tramp-shell-quote-argument localname))
                "Encoding remote file failed"))
 
              (with-tramp-progress-reporter
-                 v 3 (format-message "Decoding local file ‘%s’ with ‘%s’"
+                 v 3 (format-message "Decoding local file `%s' with `%s'"
                                      tmpfile loc-dec)
                (if (functionp loc-dec)
                    ;; If local decoding is a function, we call it.
@@ -3286,7 +3297,7 @@ the result will be a local, non-Tramp, file name."
 
           ;; Oops, I don't know what to do.
           (t (tramp-error
-              v 'file-error "Wrong method specification for ‘%s’" method)))
+              v 'file-error "Wrong method specification for `%s'" method)))
 
        ;; Error handling.
        ((error quit)
@@ -3458,7 +3469,7 @@ the result will be a local, non-Tramp, file name."
                    ;; Use encoding function or command.
                    (with-tramp-progress-reporter
                        v 3 (format-message
-                            "Encoding local file ‘%s’ using ‘%s’"
+                            "Encoding local file `%s' using `%s'"
                             tmpfile loc-enc)
                      (if (functionp loc-enc)
                          ;; The following `let' is a workaround for
@@ -3480,8 +3491,8 @@ the result will be a local, non-Tramp, file name."
                                        loc-enc tmpfile t))
                          (tramp-error
                           v 'file-error
-                          (concat "Cannot write to ‘%s’, "
-                                  "local encoding command ‘%s’ failed")
+                          (concat "Cannot write to `%s', "
+                                  "local encoding command `%s' failed")
                           filename loc-enc))))
 
                    ;; Send buffer into remote decoding command which
@@ -3489,7 +3500,7 @@ the result will be a local, non-Tramp, file name."
                    ;; the remote host, we cannot use the function.
                    (with-tramp-progress-reporter
                        v 3 (format-message
-                            "Decoding remote file ‘%s’ using ‘%s’"
+                            "Decoding remote file `%s' using `%s'"
                             filename rem-dec)
                      (goto-char (point-max))
                      (unless (bolp) (newline))
@@ -3503,7 +3514,7 @@ the result will be a local, non-Tramp, file name."
                        tramp-end-of-heredoc))
                      (tramp-barf-unless-okay
                       v nil
-                      "Couldn’t write region to ‘%s’, decode using ‘%s’ failed"
+                      "Couldn't write region to `%s', decode using `%s' failed"
                       filename rem-dec)
                      ;; When `file-precious-flag' is set, the region is
                      ;; written to a temporary file.  Check that the
@@ -3526,8 +3537,8 @@ the result will be a local, non-Tramp, file name."
                             (buffer-string))))
                         (tramp-error
                          v 'file-error
-                         (concat "Couldn’t write region to ‘%s’,"
-                                 " decode using ‘%s’ failed")
+                         (concat "Couldn't write region to `%s',"
+                                 " decode using `%s' failed")
                          filename rem-dec)))))
 
                ;; Save exit.
@@ -3537,7 +3548,7 @@ the result will be a local, non-Tramp, file name."
             (t
              (tramp-error
               v 'file-error
-              (concat "Method ‘%s’ should specify both encoding and "
+              (concat "Method `%s' should specify both encoding and "
                       "decoding command or an scp program")
               method))))
 
@@ -3591,7 +3602,7 @@ the result will be a local, non-Tramp, file name."
   (tramp-compat-with-temp-message ""
     (with-parsed-tramp-file-name file nil
       (with-tramp-progress-reporter
-         v 3 (format-message "Checking ‘vc-registered’ for %s" file)
+         v 3 (format-message "Checking `vc-registered' for %s" file)
 
        ;; There could be new files, created by the vc backend.  We
        ;; cannot reuse the old cache entries, therefore.  In
@@ -3718,22 +3729,33 @@ Fall back to normal file name handler if no Tramp handler exists."
   "Like `file-notify-add-watch' for Tramp files."
   (setq file-name (expand-file-name file-name))
   (with-parsed-tramp-file-name file-name nil
-    (let* ((default-directory (file-name-directory file-name))
-          command events filter p sequence)
+    (let ((default-directory (file-name-directory file-name))
+         command events filter p sequence)
       (cond
        ;; gvfs-monitor-dir.
        ((setq command (tramp-get-remote-gvfs-monitor-dir v))
-       (setq filter 'tramp-sh-file-gvfs-monitor-dir-process-filter
+       (setq filter 'tramp-sh-gvfs-monitor-dir-process-filter
+             events
+             (cond
+              ((and (memq 'change flags) (memq 'attribute-change flags))
+               '(created changed changes-done-hint moved deleted
+                         attribute-changed))
+              ((memq 'change flags)
+               '(created changed changes-done-hint moved deleted))
+              ((memq 'attribute-change flags) '(attribute-changed)))
              sequence `(,command ,localname)))
        ;; inotifywait.
        ((setq command (tramp-get-remote-inotifywait v))
-       (setq filter 'tramp-sh-file-inotifywait-process-filter
+       (setq filter 'tramp-sh-inotifywait-process-filter
              events
              (cond
               ((and (memq 'change flags) (memq 'attribute-change flags))
-               "create,modify,move,delete,attrib")
-              ((memq 'change flags) "create,modify,move,delete")
-              ((memq 'attribute-change flags) "attrib"))
+               (concat "create,modify,move,moved_from,moved_to,move_self,"
+                       "delete,delete_self,attrib,ignored"))
+              ((memq 'change flags)
+               (concat "create,modify,move,moved_from,moved_to,move_self,"
+                       "delete,delete_self,ignored"))
+              ((memq 'attribute-change flags) "attrib,ignored"))
              sequence `(,command "-mq" "-e" ,events ,localname)))
        ;; None.
        (t (tramp-error
@@ -3751,16 +3773,26 @@ Fall back to normal file name handler if no Tramp handler exists."
       (if (not (processp p))
          (tramp-error
           v 'file-notify-error
-          "‘%s’ failed to start on remote host"
+          "`%s' failed to start on remote host"
           (mapconcat 'identity sequence " "))
-       (tramp-message v 6 "Run ‘%s’, %S" (mapconcat 'identity sequence " ") p)
+       (tramp-message v 6 "Run `%s', %S" (mapconcat 'identity sequence " ") p)
        (tramp-set-connection-property p "vector" v)
+       ;; Needed for `tramp-sh-gvfs-monitor-dir-process-filter'.
+       (tramp-compat-process-put p 'events events)
+       (tramp-compat-process-put p 'watch-name localname)
        (tramp-compat-set-process-query-on-exit-flag p nil)
        (set-process-filter p filter)
+       ;; There might be an error if the monitor is not supported.
+       ;; Give the filter a chance to read the output.
+       (tramp-accept-process-output p 1)
+       (unless (memq (process-status p) '(run open))
+         (tramp-error
+          v 'file-notify-error "Monitoring not supported for `%s'" file-name))
        p))))
 
-(defun tramp-sh-file-gvfs-monitor-dir-process-filter (proc string)
-  "Read output from \"gvfs-monitor-dir\" and add corresponding file-notify events."
+(defun tramp-sh-gvfs-monitor-dir-process-filter (proc string)
+  "Read output from \"gvfs-monitor-dir\" and add corresponding \
+file-notify events."
   (let ((remote-prefix
         (with-current-buffer (process-buffer proc)
           (file-remote-p default-directory)))
@@ -3772,6 +3804,8 @@ Fall back to normal file name handler if no Tramp handler exists."
          ;; Attribute change is returned in unused wording.
          string (tramp-compat-replace-regexp-in-string
                  "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
+    (when (string-match "Monitoring not supported" string)
+      (delete-process proc))
 
     (while (string-match
            (concat "^[\n\r]*"
@@ -3780,29 +3814,36 @@ Fall back to normal file name handler if no Tramp handler exists."
                    "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?"
                    "Event = \\([^[:blank:]]+\\)[\n\r]+")
            string)
-      (let ((object
-            (list
-             proc
-             (intern-soft
-              (tramp-compat-replace-regexp-in-string
-               "_" "-" (downcase (match-string 4 string))))
-             ;; File names are returned as absolute paths.  We must
-             ;; add the remote prefix.
-             (concat remote-prefix (match-string 1 string))
-             (when (match-string 3 string)
-               (concat remote-prefix (match-string 3 string))))))
+      (let* ((file (match-string 1 string))
+            (file1 (match-string 3 string))
+            (object
+             (list
+              proc
+              (intern-soft
+               (tramp-compat-replace-regexp-in-string
+                "_" "-" (downcase (match-string 4 string))))
+              ;; File names are returned as absolute paths.  We must
+              ;; add the remote prefix.
+              (concat remote-prefix file)
+              (when file1 (concat remote-prefix file1)))))
        (setq string (replace-match "" nil nil string))
+       ;; Remove watch when file or directory to be watched is deleted.
+       (when (and (member (cadr object) '(moved deleted))
+                  (string-equal
+                   file (tramp-compat-process-get proc 'watch-name)))
+         (delete-process proc))
        ;; Usually, we would add an Emacs event now.  Unfortunately,
        ;; `unread-command-events' does not accept several events at
        ;; once.  Therefore, we apply the callback directly.
-       (tramp-compat-funcall 'file-notify-callback object)))
+       (when (member (cadr object) (tramp-compat-process-get proc 'events))
+         (tramp-compat-funcall 'file-notify-callback object))))
 
     ;; Save rest of the string.
     (when (zerop (length string)) (setq string nil))
     (when string (tramp-message proc 10 "Rest string:\n%s" string))
     (tramp-compat-process-put proc 'rest-string string)))
 
-(defun tramp-sh-file-inotifywait-process-filter (proc string)
+(defun tramp-sh-inotifywait-process-filter (proc string)
   "Read output from \"inotifywait\" and add corresponding file-notify events."
   (tramp-message proc 6 "%S\n%s" proc string)
   (dolist (line (split-string string "[\n\r]+" 'omit-nulls))
@@ -3824,6 +3865,9 @@ Fall back to normal file name handler if no Tramp handler exists."
                (tramp-compat-replace-regexp-in-string "_" "-" (downcase x))))
             (split-string (match-string 1 line) "," 'omit-nulls))
            (match-string 3 line))))
+      ;; Remove watch when file or directory to be watched is deleted.
+      (when (equal (cadr object) 'ignored)
+       (delete-process proc))
       ;; Usually, we would add an Emacs event now.  Unfortunately,
       ;; `unread-command-events' does not accept several events at
       ;; once.  Therefore, we apply the callback directly.
@@ -3840,7 +3884,7 @@ Only send the definition if it has not already been done."
                  (tramp-get-connection-process vec) "scripts" nil)))
     (unless (member name scripts)
       (with-tramp-progress-reporter
-         vec 5 (format-message "Sending script ‘%s’" name)
+         vec 5 (format-message "Sending script `%s'" name)
        ;; In bash, leading TABs like in `tramp-vc-registered-read-file-names'
        ;; could result in unwanted command expansion.  Avoid this.
        (setq script (tramp-compat-replace-regexp-in-string
@@ -4008,13 +4052,13 @@ file exists and nonzero exit status otherwise."
                    (not (tramp-send-command-and-check
                          vec (format "%s %s" result nonexistent))))))
       (tramp-error
-       vec 'file-error "Couldnt find command to check if file exists"))
+       vec 'file-error "Couldn't find command to check if file exists"))
     result))
 
 (defun tramp-open-shell (vec shell)
   "Opens shell SHELL."
   (with-tramp-progress-reporter
-      vec 5 (format-message "Opening remote shell ‘%s’" shell)
+      vec 5 (format-message "Opening remote shell `%s'" shell)
     ;; Find arguments for this shell.
     (let ((alist tramp-sh-extra-args)
          item extra-args)
@@ -4078,8 +4122,8 @@ file exists and nonzero exit status otherwise."
                        (tramp-message
                         vec 2
                         (concat
-                         "Couldnt find a remote shell which groks tilde "
-                         "expansion, using ‘%s’")
+                         "Couldn't find a remote shell which groks tilde "
+                         "expansion, using `%s'")
                         default-shell)))
 
                default-shell)))
@@ -4087,7 +4131,7 @@ file exists and nonzero exit status otherwise."
       ;; Open a new shell if needed.
       (unless (string-equal shell default-shell)
        (tramp-message
-        vec 5 "Starting remote shell ‘%s’ for tilde expansion" shell)
+        vec 5 "Starting remote shell `%s' for tilde expansion" shell)
        (tramp-open-shell vec shell)))))
 
 ;; Utility functions.
@@ -4111,12 +4155,14 @@ seconds.  If not, it produces an error message with the given ERROR-ARGS."
   "Set up an interactive shell.
 Mainly sets the prompt and the echo correctly.  PROC is the shell
 process to set up.  VEC specifies the connection."
-  (let ((tramp-end-of-output tramp-initial-end-of-output))
+  (let ((tramp-end-of-output tramp-initial-end-of-output)
+       (case-fold-search t))
     (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
 
     ;; Disable tab and echo expansion.
     (tramp-message vec 5 "Setting up remote shell environment")
-    (tramp-send-command vec "stty tab0 -inlcr -echo kill '^U' erase '^H'" t)
+    (tramp-send-command
+     vec "stty tab0 -inlcr -onlcr -echo kill '^U' erase '^H'" t)
     ;; Check whether the echo has really been disabled.  Some
     ;; implementations, like busybox of embedded GNU/Linux, don't
     ;; support disabling.
@@ -4135,6 +4181,25 @@ process to set up.  VEC specifies the connection."
    vec (format "PS1=%s PS2='' PS3='' PROMPT_COMMAND=''"
               (tramp-shell-quote-argument tramp-end-of-output)) t)
 
+  ;; Check whether the output of "uname -sr" has been changed.  If
+  ;; yes, this is a strong indication that we must expire all
+  ;; connection properties.  We start again with
+  ;; `tramp-maybe-open-connection', it will be caught there.
+  (tramp-message vec 5 "Checking system information")
+  (let ((old-uname (tramp-get-connection-property vec "uname" nil))
+       (new-uname
+        (tramp-set-connection-property
+         vec "uname"
+         (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
+    (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
+      (tramp-message
+       vec 3
+       "Connection reset, because remote host changed from `%s' to `%s'"
+       old-uname new-uname)
+      ;; We want to keep the password.
+      (tramp-cleanup-connection vec t t)
+      (throw 'uname-changed (tramp-maybe-open-connection vec))))
+
   ;; Try to set up the coding system correctly.
   ;; CCC this can't be the right way to do it.  Hm.
   (tramp-message vec 5 "Determining coding system")
@@ -4143,7 +4208,7 @@ process to set up.  VEC specifies the connection."
        ;; Use MULE to select the right EOL convention for communicating
        ;; with the process.
        (let ((cs (or (and (memq 'utf-8 (coding-system-list))
-                          (string-match "utf8" (tramp-get-remote-locale vec))
+                          (string-match "utf-?8" (tramp-get-remote-locale vec))
                           (cons 'utf-8 'utf-8))
                      (tramp-compat-funcall 'process-coding-system proc)
                      (cons 'undecided 'undecided)))
@@ -4153,8 +4218,12 @@ process to set up.  VEC specifies the connection."
          (setq cs-encode (cdr cs))
          (unless cs-decode (setq cs-decode 'undecided))
          (unless cs-encode (setq cs-encode 'undecided))
-         (setq cs-encode (tramp-compat-coding-system-change-eol-conversion
-                          cs-encode 'unix))
+         (setq cs-encode
+               (tramp-compat-coding-system-change-eol-conversion
+                cs-encode
+                (if (string-match
+                     "^Darwin" (tramp-get-connection-property vec "uname" ""))
+                    'mac 'unix)))
          (tramp-send-command vec "echo foo ; echo bar" t)
          (goto-char (point-min))
          (when (search-forward "\r" nil t)
@@ -4163,7 +4232,7 @@ process to set up.  VEC specifies the connection."
          (tramp-compat-funcall
           'set-buffer-process-coding-system cs-decode cs-encode)
          (tramp-message
-          vec 5 "Setting coding system to ‘%s’ and ‘%s’" cs-decode cs-encode))
+          vec 5 "Setting coding system to `%s' and `%s'" cs-decode cs-encode))
       ;; Look for ^M and do something useful if found.
       (when (search-forward "\r" nil t)
        ;; We have found a ^M but cannot frob the process coding system
@@ -4173,25 +4242,6 @@ process to set up.  VEC specifies the connection."
 
   (tramp-send-command vec "set +o vi +o emacs" t)
 
-  ;; Check whether the output of "uname -sr" has been changed.  If
-  ;; yes, this is a strong indication that we must expire all
-  ;; connection properties.  We start again with
-  ;; `tramp-maybe-open-connection', it will be caught there.
-  (tramp-message vec 5 "Checking system information")
-  (let ((old-uname (tramp-get-connection-property vec "uname" nil))
-       (new-uname
-        (tramp-set-connection-property
-         vec "uname"
-         (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
-    (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
-      (tramp-message
-       vec 3
-       "Connection reset, because remote host changed from ‘%s’ to ‘%s’"
-       old-uname new-uname)
-      ;; We want to keep the password.
-      (tramp-cleanup-connection vec t t)
-      (throw 'uname-changed (tramp-maybe-open-connection vec))))
-
   ;; Check whether the remote host suffers from buggy
   ;; `send-process-string'.  This is known for FreeBSD (see comment in
   ;; `send_process', file process.c).  I've tested sending 624 bytes
@@ -4204,7 +4254,7 @@ process to set up.  VEC specifies the connection."
       tramp-chunksize)
      (t
       (tramp-message
-       vec 5 "Checking remote host type for ‘send-process-string’ bug")
+       vec 5 "Checking remote host type for `send-process-string' bug")
       (if (string-match
           "^FreeBSD" (tramp-get-connection-property vec "uname" ""))
          500 0))))
@@ -4225,7 +4275,7 @@ process to set up.  VEC specifies the connection."
   (tramp-find-shell vec)
 
   ;; Disable unexpected output.
-  (tramp-send-command vec "mesg n; biff n" t)
+  (tramp-send-command vec "mesg n 2>/dev/null; biff n 2>/dev/null" t)
 
   ;; IRIX64 bash expands "!" even when in single quotes.  This
   ;; destroys our shell functions, we must disable it.  See
@@ -4238,6 +4288,10 @@ process to set up.  VEC specifies the connection."
                      (tramp-get-connection-property vec "uname" ""))
     (tramp-send-command vec "stty -oxtabs" t))
 
+  ;; Set utf8 encoding.  Needed for Mac OS X, for example.  This is
+  ;; non-POSIX, so we must expect errors on some systems.
+  (tramp-send-command vec "stty iutf8 2>/dev/null" t)
+
   ;; Set `remote-tty' process property.
   (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
     (unless (zerop (length tty))
@@ -4294,7 +4348,7 @@ process to set up.  VEC specifies the connection."
   "List of local coding commands for inline transfer.
 Each item is a list that looks like this:
 
-\(FORMAT ENCODING DECODING\)
+\(FORMAT ENCODING DECODING)
 
 FORMAT is  symbol describing the encoding/decoding format.  It can be
 `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
@@ -4316,6 +4370,7 @@ with the encoded or decoded results, respectively.")
     ;; However, I don't know whether all base64 versions do supports
     ;; this option.
     (b64 "base64" "base64 -d")
+    (b64 "openssl enc -base64" "openssl enc -d -base64")
     (b64 "mimencode -b" "mimencode -u -b")
     (b64 "mmencode -b" "mmencode -u -b")
     (b64 "recode data..base64" "recode base64..data")
@@ -4331,7 +4386,7 @@ with the encoded or decoded results, respectively.")
   "List of remote coding commands for inline transfer.
 Each item is a list that looks like this:
 
-\(FORMAT ENCODING DECODING [TEST]\)
+\(FORMAT ENCODING DECODING [TEST])
 
 FORMAT is a symbol describing the encoding/decoding format.  It can be
 `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
@@ -4372,17 +4427,17 @@ Goes through the list `tramp-local-coding-commands' and
            ;; corresponding command has to work locally.
            (if (not (stringp loc-enc))
                (tramp-message
-                vec 5 "Checking local encoding function ‘%s’" loc-enc)
+                vec 5 "Checking local encoding function `%s'" loc-enc)
              (tramp-message
-              vec 5 "Checking local encoding command ‘%s’ for sanity" loc-enc)
+              vec 5 "Checking local encoding command `%s' for sanity" loc-enc)
              (unless (zerop (tramp-call-local-coding-command
                              loc-enc nil nil))
                (throw 'wont-work-local nil)))
            (if (not (stringp loc-dec))
                (tramp-message
-                vec 5 "Checking local decoding function ‘%s’" loc-dec)
+                vec 5 "Checking local decoding function `%s'" loc-dec)
              (tramp-message
-              vec 5 "Checking local decoding command ‘%s’ for sanity" loc-dec)
+              vec 5 "Checking local decoding command `%s' for sanity" loc-dec)
              (unless (zerop (tramp-call-local-coding-command
                              loc-dec nil nil))
                (throw 'wont-work-local nil)))
@@ -4397,7 +4452,7 @@ Goes through the list `tramp-local-coding-commands' and
                  ;; Check the remote test command if exists.
                  (when (stringp rem-test)
                    (tramp-message
-                    vec 5 "Checking remote test command ‘%s’" rem-test)
+                    vec 5 "Checking remote test command `%s'" rem-test)
                    (unless (tramp-send-command-and-check vec rem-test t)
                      (throw 'wont-work-remote nil)))
                  ;; Check if remote perl exists when necessary.
@@ -4421,7 +4476,7 @@ Goes through the list `tramp-local-coding-commands' and
                      (setq rem-enc name)))
                  (tramp-message
                   vec 5
-                  "Checking remote encoding command ‘%s’ for sanity" rem-enc)
+                  "Checking remote encoding command `%s' for sanity" rem-enc)
                  (unless (tramp-send-command-and-check
                           vec (format "%s </dev/null" rem-enc) t)
                    (throw 'wont-work-remote nil))
@@ -4449,7 +4504,7 @@ Goes through the list `tramp-local-coding-commands' and
                      (setq rem-dec name)))
                  (tramp-message
                   vec 5
-                  "Checking remote decoding command ‘%s’ for sanity" rem-dec)
+                  "Checking remote decoding command `%s' for sanity" rem-dec)
                  (unless (tramp-send-command-and-check
                           vec
                           (format "echo %s | %s | %s" magic rem-enc rem-dec)
@@ -4469,13 +4524,13 @@ Goes through the list `tramp-local-coding-commands' and
       (when found
        ;; Set connection properties.  Since the commands are risky
        ;; (due to output direction), we cache them in the process cache.
-       (tramp-message vec 5 "Using local encoding ‘%s’" loc-enc)
+       (tramp-message vec 5 "Using local encoding `%s'" loc-enc)
        (tramp-set-connection-property p "local-encoding" loc-enc)
-       (tramp-message vec 5 "Using local decoding ‘%s’" loc-dec)
+       (tramp-message vec 5 "Using local decoding `%s'" loc-dec)
        (tramp-set-connection-property p "local-decoding" loc-dec)
-       (tramp-message vec 5 "Using remote encoding ‘%s’" rem-enc)
+       (tramp-message vec 5 "Using remote encoding `%s'" rem-enc)
        (tramp-set-connection-property p "remote-encoding" rem-enc)
-       (tramp-message vec 5 "Using remote decoding ‘%s’" rem-dec)
+       (tramp-message vec 5 "Using remote decoding `%s'" rem-dec)
        (tramp-set-connection-property p "remote-decoding" rem-dec)))))
 
 (defun tramp-call-local-coding-command (cmd input output)
@@ -4504,7 +4559,7 @@ means discard it)."
   "List of compress and decompress commands for inline transfer.
 Each item is a list that looks like this:
 
-\(COMPRESS DECOMPRESS\)
+\(COMPRESS DECOMPRESS)
 
 COMPRESS or DECOMPRESS are strings with the respective commands.")
 
@@ -4523,7 +4578,7 @@ Goes through the list `tramp-inline-compress-commands'."
                decompress (nth 1 item))
          (tramp-message
           vec 5
-          "Checking local compress commands ‘%s’, ‘%s’ for sanity"
+          "Checking local compress commands `%s', `%s' for sanity"
           compress decompress)
          (unless
              (zerop
@@ -4539,7 +4594,7 @@ Goes through the list `tramp-inline-compress-commands'."
            (throw 'next nil))
          (tramp-message
           vec 5
-          "Checking remote compress commands ‘%s’, ‘%s’ for sanity"
+          "Checking remote compress commands `%s', `%s' for sanity"
           compress decompress)
          (unless (tramp-send-command-and-check
                   vec (format "echo %s | %s | %s" magic compress decompress) t)
@@ -4553,16 +4608,16 @@ Goes through the list `tramp-inline-compress-commands'."
            ;; risky (due to output direction), we cache them in the
            ;; process cache.
            (tramp-message
-            vec 5 "Using inline transfer compress command ‘%s’" compress)
+            vec 5 "Using inline transfer compress command `%s'" compress)
            (tramp-set-connection-property p "inline-compress" compress)
            (tramp-message
-            vec 5 "Using inline transfer decompress command ‘%s’" decompress)
+            vec 5 "Using inline transfer decompress command `%s'" decompress)
            (tramp-set-connection-property p "inline-decompress" decompress))
 
        (tramp-set-connection-property p "inline-compress" nil)
        (tramp-set-connection-property p "inline-decompress" nil)
        (tramp-message
-        vec 2 "Couldnt find an inline transfer compress command")))))
+        vec 2 "Couldn't find an inline transfer compress command")))))
 
 (defun tramp-compute-multi-hops (vec)
   "Expands VEC according to `tramp-default-proxies-alist'.
@@ -4635,7 +4690,7 @@ Gateway hops are already opened."
        (unless (tramp-file-name-port hop)
          (tramp-error
           vec 'file-error
-          "Connection ‘%s’ is not supported for gateway access." hop))
+          "Connection `%s' is not supported for gateway access." hop))
        ;; Open the gateway connection.
        (push
         (vector
@@ -4657,7 +4712,7 @@ Gateway hops are already opened."
                  (tramp-get-method-parameter item 'tramp-copy-program))
          (tramp-error
           vec 'file-error
-          "Method ‘%s’ is not supported for multi-hops."
+          "Method `%s' is not supported for multi-hops."
           (tramp-file-name-method item)))))
 
     ;; In case the host name is not used for the remote shell
@@ -4677,7 +4732,7 @@ Gateway hops are already opened."
           (string-match tramp-local-host-regexp host))
        (tramp-error
         v 'file-error
-        "Host ‘%s’ looks like a remote host, ‘%s’ can only use the local host"
+        "Host `%s' looks like a remote host, `%s' can only use the local host"
         host method)))
 
     ;; Result.
@@ -4837,7 +4892,7 @@ connection if a previous connection has died for some reason."
                ;; Check whether process is alive.
                (tramp-barf-if-no-shell-prompt
                 p 10
-                "Couldnt find local shell prompt for %s" tramp-encoding-shell)
+                "Couldn't find local shell prompt for %s" tramp-encoding-shell)
 
                ;; Now do all the connections as specified.
                (while target-alist
@@ -4957,13 +5012,13 @@ connection if a previous connection has died for some reason."
                      (when r-shell " && exit || exit")))
 
                    ;; Send the command.
-                   (tramp-message vec 3 "Sending command ‘%s’" command)
+                   (tramp-message vec 3 "Sending command `%s'" command)
                    (tramp-send-command vec command t t)
                    (tramp-process-actions
                     p vec pos tramp-actions-before-shell
                     (or connection-timeout tramp-connection-timeout))
                    (tramp-message
-                    vec 3 "Found remote shell prompt on ‘%s’" l-host))
+                    vec 3 "Found remote shell prompt on `%s'" l-host))
                  ;; Next hop.
                  (setq options ""
                        target-alist (cdr target-alist)))
@@ -5009,7 +5064,7 @@ function waits for output unless NOOUTPUT is set."
   "Wait for output from remote command."
   (unless (buffer-live-p (process-buffer proc))
     (delete-process proc)
-    (tramp-error proc 'file-error "Process ‘%s’ not available, try again" proc))
+    (tramp-error proc 'file-error "Process `%s' not available, try again" proc))
   (with-current-buffer (process-buffer proc)
     (let* (;; Initially, `tramp-end-of-output' is "#$ ".  There might
           ;; be leading escape sequences, which must be ignored.
@@ -5034,11 +5089,11 @@ function waits for output unless NOOUTPUT is set."
        (if timeout
            (tramp-error
             proc 'file-error
-            "[[Remote prompt ‘%s’ not found in %d secs]]"
+            "[[Remote prompt `%s' not found in %d secs]]"
             tramp-end-of-output timeout)
          (tramp-error
           proc 'file-error
-          "[[Remote prompt ‘%s’ not found]]" tramp-end-of-output)))
+          "[[Remote prompt `%s' not found]]" tramp-end-of-output)))
       ;; Return value is whether end-of-output sentinel was found.
       found)))
 
@@ -5063,7 +5118,7 @@ DONT-SUPPRESS-ERR is non-nil, stderr won't be sent to /dev/null."
     (goto-char (point-max))
     (unless (re-search-backward "tramp_exit_status [0-9]+" nil t)
       (tramp-error
-       vec 'file-error "Couldn’t find exit status of ‘%s’" command))
+       vec 'file-error "Couldn't find exit status of `%s'" command))
     (skip-chars-forward "^ ")
     (prog1
        (zerop (read (current-buffer)))
@@ -5085,7 +5140,7 @@ raises an error."
   (when (if noerror
            (tramp-send-command-and-check vec command)
          (tramp-barf-unless-okay
-          vec command "‘%s’ returns with error" command))
+          vec command "`%s' returns with error" command))
     (with-current-buffer (tramp-get-connection-buffer vec)
       (goto-char (point-min))
       ;; Read the marker.
@@ -5095,7 +5150,7 @@ raises an error."
          (error (unless noerror
                   (tramp-error
                    vec 'file-error
-                   "‘%s’ does not return the marker ‘%s’: ‘%s’"
+                   "`%s' does not return the marker `%s': `%s'"
                    command marker (buffer-string))))))
       ;; Read the expression.
       (condition-case nil
@@ -5106,7 +5161,7 @@ raises an error."
        (error (unless noerror
                 (tramp-error
                  vec 'file-error
-                 "‘%s’ does not return a valid Lisp expression: ‘%s’"
+                 "`%s' does not return a valid Lisp expression: `%s'"
                  command (buffer-string))))))))
 
 (defun tramp-convert-file-attributes (vec attr)
@@ -5114,18 +5169,10 @@ raises an error."
 Convert file mode bits to string and set virtual device number.
 Return ATTR."
   (when attr
-    ;; Convert symlink from `tramp-do-file-attributes-with-stat'.
-    (when (consp (car attr))
-      (if (and (stringp (caar attr))
-               (string-match ".+ -> .\\(.+\\)." (caar attr)))
-          (setcar attr (match-string 1 (caar attr)))
-        (setcar attr nil)))
-    ;; Remove color escape sequences and double slashes from symlink.
+    ;; Remove color escape sequences from symlink.
     (when (stringp (car attr))
       (while (string-match tramp-color-escape-sequence-regexp (car attr))
-       (setcar attr (replace-match "" nil nil (car attr))))
-      (while (string-match "//" (car attr))
-       (setcar attr (replace-match "/" nil nil (car attr)))))
+       (setcar attr (replace-match "" nil nil (car attr)))))
     ;; Convert uid and gid.  Use -1 as indication of unusable value.
     (when (and (numberp (nth 2 attr)) (< (nth 2 attr) 0))
       (setcar (nthcdr 2 attr) -1))
@@ -5166,6 +5213,12 @@ Return ATTR."
     ;; Convert directory indication bit.
     (when (string-match "^d" (nth 8 attr))
       (setcar attr t))
+    ;; Convert symlink from `tramp-do-file-attributes-with-stat'.
+    (when (consp (car attr))
+      (if (and (stringp (caar attr))
+               (string-match ".+ -> .\\(.+\\)." (caar attr)))
+          (setcar attr (match-string 1 (caar attr)))
+        (setcar attr nil)))
     ;; Set file's gid change bit.
     (setcar (nthcdr 9 attr)
             (if (numberp (nth 3 attr))
@@ -5250,28 +5303,33 @@ Return ATTR."
                (progn
                  (tramp-message
                   vec 3
-                  "‘getconf PATH’ not successful, using default value \"%s\"."
+                  "`getconf PATH' not successful, using default value \"%s\"."
                   "/bin:/usr/bin")
                  "/bin:/usr/bin"))))
           (own-remote-path
            ;; The login shell could return more than just the $PATH
            ;; string.  So we use `tramp-end-of-heredoc' as marker.
            (when elt2
-             (tramp-send-command-and-read
-              vec
-              (format
-               "%s %s %s 'echo %s \\\"$PATH\\\"'"
-               (tramp-get-method-parameter vec 'tramp-remote-shell)
-               (mapconcat
-                'identity
-                (tramp-get-method-parameter vec 'tramp-remote-shell-login)
-                " ")
-               (mapconcat
-                'identity
-                (tramp-get-method-parameter vec 'tramp-remote-shell-args)
-                " ")
-               (tramp-shell-quote-argument tramp-end-of-heredoc))
-              nil (regexp-quote tramp-end-of-heredoc)))))
+             (or
+              (tramp-send-command-and-read
+               vec
+               (format
+                "%s %s %s 'echo %s \\\"$PATH\\\"'"
+                (tramp-get-method-parameter vec 'tramp-remote-shell)
+                (mapconcat
+                 'identity
+                 (tramp-get-method-parameter vec 'tramp-remote-shell-login)
+                 " ")
+                (mapconcat
+                 'identity
+                 (tramp-get-method-parameter vec 'tramp-remote-shell-args)
+                 " ")
+                (tramp-shell-quote-argument tramp-end-of-heredoc))
+               'noerror (regexp-quote tramp-end-of-heredoc))
+              (progn
+                (tramp-message
+                 vec 2 "Could not retrieve `tramp-own-remote-path'")
+                nil)))))
 
       ;; Replace place holder `tramp-default-remote-path'.
       (when elt1
@@ -5315,7 +5373,7 @@ Return ATTR."
 (defun tramp-get-remote-locale (vec)
   (with-tramp-connection-property vec "locale"
     (tramp-send-command vec "locale -a")
-    (let ((candidates '("en_US.utf8" "C.utf8"))
+    (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8"))
          locale)
       (with-current-buffer (tramp-get-connection-buffer vec)
        (while candidates
@@ -5330,7 +5388,7 @@ Return ATTR."
 
 (defun tramp-get-ls-command (vec)
   (with-tramp-connection-property vec "ls"
-    (tramp-message vec 5 "Finding a suitable ‘ls’ command")
+    (tramp-message vec 5 "Finding a suitable `ls' command")
     (or
      (catch 'ls-found
        (dolist (cmd '("ls" "gnuls" "gls"))
@@ -5351,12 +5409,12 @@ Return ATTR."
                 (setq result (concat result " --color=never")))
               (throw 'ls-found result))
             (setq dl (cdr dl))))))
-     (tramp-error vec 'file-error "Couldn’t find a proper ‘ls’ command"))))
+     (tramp-error vec 'file-error "Couldn't find a proper `ls' command"))))
 
 (defun tramp-get-ls-command-with-dired (vec)
   (save-match-data
     (with-tramp-connection-property vec "ls-dired"
-      (tramp-message vec 5 "Checking, whether ‘ls --dired’ works")
+      (tramp-message vec 5 "Checking, whether `ls --dired' works")
       ;; Some "ls" versions are sensible wrt the order of arguments,
       ;; they fail when "-al" is after the "--dired" argument (for
       ;; example on FreeBSD).
@@ -5366,17 +5424,24 @@ Return ATTR."
 (defun tramp-get-ls-command-with-quoting-style (vec)
   (save-match-data
     (with-tramp-connection-property vec "ls-quoting-style"
-      (tramp-message vec 5 "Checking, whether ‘ls --quoting-style=shell’ works")
-      ;; Some "ls" versions are sensible wrt the order of arguments,
-      ;; they fail when "-al" is after the "--dired" argument (for
-      ;; example on FreeBSD).
+      (tramp-message vec 5 "Checking, whether `ls --quoting-style=shell' works")
       (tramp-send-command-and-check
        vec (format "%s --quoting-style=shell -al /dev/null"
                   (tramp-get-ls-command vec))))))
 
+(defun tramp-get-ls-command-with-w-option (vec)
+  (save-match-data
+    (with-tramp-connection-property vec "ls-w-option"
+      (tramp-message vec 5 "Checking, whether `ls -w' works")
+      ;; Option "-w" is available on BSD systems.  No argument is
+      ;; given, because this could return wrong results in case "ls"
+      ;; supports the "-w NUM" argument, as for busyboxes.
+      (tramp-send-command-and-check
+       vec (format "%s -alw" (tramp-get-ls-command vec))))))
+
 (defun tramp-get-test-command (vec)
   (with-tramp-connection-property vec "test"
-    (tramp-message vec 5 "Finding a suitable ‘test’ command")
+    (tramp-message vec 5 "Finding a suitable `test' command")
     (if (tramp-send-command-and-check vec "test 0")
        "test"
       (tramp-find-executable vec "test" (tramp-get-remote-path vec)))))
@@ -5409,12 +5474,12 @@ Return ATTR."
 
 (defun tramp-get-remote-ln (vec)
   (with-tramp-connection-property vec "ln"
-    (tramp-message vec 5 "Finding a suitable ‘ln’ command")
+    (tramp-message vec 5 "Finding a suitable `ln' command")
     (tramp-find-executable vec "ln" (tramp-get-remote-path vec))))
 
 (defun tramp-get-remote-perl (vec)
   (with-tramp-connection-property vec "perl"
-    (tramp-message vec 5 "Finding a suitable ‘perl’ command")
+    (tramp-message vec 5 "Finding a suitable `perl' command")
     (let ((result
           (or (tramp-find-executable vec "perl5" (tramp-get-remote-path vec))
               (tramp-find-executable
@@ -5431,7 +5496,7 @@ Return ATTR."
 
 (defun tramp-get-remote-stat (vec)
   (with-tramp-connection-property vec "stat"
-    (tramp-message vec 5 "Finding a suitable ‘stat’ command")
+    (tramp-message vec 5 "Finding a suitable `stat' command")
     (let ((result (tramp-find-executable
                   vec "stat" (tramp-get-remote-path vec)))
          tmp)
@@ -5449,7 +5514,7 @@ Return ATTR."
 
 (defun tramp-get-remote-readlink (vec)
   (with-tramp-connection-property vec "readlink"
-    (tramp-message vec 5 "Finding a suitable ‘readlink’ command")
+    (tramp-message vec 5 "Finding a suitable `readlink' command")
     (let ((result (tramp-find-executable
                   vec "readlink" (tramp-get-remote-path vec))))
       (when (and result
@@ -5459,12 +5524,12 @@ Return ATTR."
 
 (defun tramp-get-remote-trash (vec)
   (with-tramp-connection-property vec "trash"
-    (tramp-message vec 5 "Finding a suitable ‘trash’ command")
+    (tramp-message vec 5 "Finding a suitable `trash' command")
     (tramp-find-executable vec "trash" (tramp-get-remote-path vec))))
 
 (defun tramp-get-remote-touch (vec)
   (with-tramp-connection-property vec "touch"
-    (tramp-message vec 5 "Finding a suitable ‘touch’ command")
+    (tramp-message vec 5 "Finding a suitable `touch' command")
     (let ((result (tramp-find-executable
                   vec "touch" (tramp-get-remote-path vec)))
          (tmpfile
@@ -5488,18 +5553,18 @@ Return ATTR."
 
 (defun tramp-get-remote-gvfs-monitor-dir (vec)
   (with-tramp-connection-property vec "gvfs-monitor-dir"
-    (tramp-message vec 5 "Finding a suitable ‘gvfs-monitor-dir’ command")
+    (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command")
     (tramp-find-executable
      vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t)))
 
 (defun tramp-get-remote-inotifywait (vec)
   (with-tramp-connection-property vec "inotifywait"
-    (tramp-message vec 5 "Finding a suitable ‘inotifywait’ command")
+    (tramp-message vec 5 "Finding a suitable `inotifywait' command")
     (tramp-find-executable vec "inotifywait" (tramp-get-remote-path vec) t t)))
 
 (defun tramp-get-remote-id (vec)
   (with-tramp-connection-property vec "id"
-    (tramp-message vec 5 "Finding POSIX ‘id’ command")
+    (tramp-message vec 5 "Finding POSIX `id' command")
     (catch 'id-found
       (dolist (cmd '("id" "gid"))
        (let ((dl (tramp-get-remote-path vec))
@@ -5517,7 +5582,7 @@ Return ATTR."
           (tramp-get-remote-id vec)
           (if (equal id-format 'integer) "" "n")
           (if (equal id-format 'integer)
-              "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/"))))
+              "" "| sed -e s/^/\\\"/ -e s/\\$/\\\"/"))))
 
 (defun tramp-get-remote-uid-with-perl (vec id-format)
   (tramp-send-command-and-read
@@ -5530,7 +5595,7 @@ Return ATTR."
 
 (defun tramp-get-remote-python (vec)
   (with-tramp-connection-property vec "python"
-    (tramp-message vec 5 "Finding a suitable ‘python’ command")
+    (tramp-message vec 5 "Finding a suitable `python' command")
     (or (tramp-find-executable vec "python" (tramp-get-remote-path vec))
         (tramp-find-executable vec "python2" (tramp-get-remote-path vec))
         (tramp-find-executable vec "python3" (tramp-get-remote-path vec)))))
@@ -5568,7 +5633,7 @@ Return ATTR."
           (tramp-get-remote-id vec)
           (if (equal id-format 'integer) "" "n")
           (if (equal id-format 'integer)
-              "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/"))))
+              "" "| sed -e s/^/\\\"/ -e s/\\$/\\\"/"))))
 
 (defun tramp-get-remote-gid-with-perl (vec id-format)
   (tramp-send-command-and-read