[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Tramp mosh method

From: Ted Zlatanov
Subject: Re: Tramp mosh method
Date: Fri, 21 Dec 2012 05:30:45 -0500
User-agent: Gnus/5.130006 (Ma Gnus v0.6) Emacs/24.3.50 (gnu/linux)

On Wed, 19 Dec 2012 15:34:06 +0100 Michael Albinus <address@hidden> wrote: 

>> I started on the code but can't figure out how to fool mosh-server into
>> thinking it has a TTY.  It still exits if the terminal height is 0.

MA> "stty" is your friend.

Hmm, I swear I tried that.  I am attaching my attempt following your
example, using a `tramp-process-precommands' variable.

MA> Here is a patch (towards Tramp Git) which allows me to connect via mosh
MA> remotely, using my local machine as remote via "C-x C-f /mosh::". I have
MA> commented the setting of the process filter, in order to see the mosh
MA> call output in the debug buffer (tramp-verbose 10 is needed).

Unfortunately it didn't work for me, from Ubuntu to CentOS or from
Ubuntu to localhost.  The debug buffer shows nothing is received after
"exec mosh MACHINENAME", and the proces filter is never invoked (I
checked in *Messages*; see the stub `tramp-mosh-process-filter').

OTOH before I got a quick error from the mosh-server, and now I see the
mosh-client and mosh-server running, so *something* is happening :)

MA> I also needed to set "LC_ALL" to "C.UTF-8"; mosh requires that.

That locale is not available on many systems, e.g. CentOS.  My patch
explicitly adds `(setenv "LC_ALL" "en_US.UTF-8")' but I think it's
better to set that in the method parameters because only mosh needs it.
I hope you agree.

I am attaching an updated version of the mosh patch against trunk Emacs.
Sorry I haven't converted to the Tramp Git repository yet...  If you
think using the Tramp Git repo is essential, I'll rebase my patch and


=== modified file 'lisp/net/tramp-sh.el'
--- lisp/net/tramp-sh.el        2012-12-19 13:01:16 +0000
+++ lisp/net/tramp-sh.el        2012-12-21 10:17:52 +0000
@@ -85,6 +85,10 @@
 (defconst tramp-initial-end-of-output "#$ "
   "Prompt when establishing a connection.")
+(defconst tramp-mosh-method "mosh"
+  "When this method name is used, forward all calls to mosh.")
 ;; Initialize `tramp-methods' with the supported methods.
 (add-to-list 'tramp-methods
@@ -406,6 +410,33 @@
     (tramp-copy-program         "fcp")
     (tramp-copy-args            (("-p" "%k")))
     (tramp-copy-keep-date       t)))
+(add-to-list 'tramp-methods
+  `(,tramp-mosh-method
+    (tramp-login-program        "mosh")
+    (tramp-login-args           (("-p" "%p") ("%h")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
+    (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
+    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
+                                 ("-o" "UserKnownHostsFile=/dev/null")
+                                 ("-o" "StrictHostKeyChecking=no")))
+    (tramp-process-precommands ("stty rows 25" "stty cols 80")
+    (tramp-process-filter       'tramp-mosh-process-filter)
+    (tramp-default-port         22))))
+;; It must be a `defsubst' in order to push the whole code into
+;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
+(defsubst tramp-mosh-file-name-p (filename)
+  "Check if it's a filename that should be handled with mosh."
+  (string= (tramp-file-name-method (tramp-dissect-file-name filename))
+           tramp-mosh-method))
+(add-to-list 'tramp-foreign-file-name-handler-alist
+             (cons 'tramp-mosh-file-name-p 'tramp-sh-file-name-handler))
 (add-to-list 'tramp-default-method-alist
@@ -4392,7 +4423,8 @@
              (when (and p (processp p))
                (delete-process p))
              (setenv "TERM" tramp-terminal-type)
-             (setenv "LC_ALL" "C")
+             (setenv "LC_ALL" "C.UTF-8")
+             (setenv "LC_ALL" "en_US.UTF-8")
              (setenv "PROMPT_COMMAND")
              (setenv "PS1" tramp-initial-end-of-output)
              (let* ((target-alist (tramp-compute-multi-hops vec))
@@ -4428,6 +4460,11 @@
                 p 60
                 "Couldn't find local shell prompt %s" tramp-encoding-shell)
+                (dolist (command (tramp-get-method-parameter
+                                   (tramp-file-name-method vec)
+                                   'tramp-process-precommands))
+                  (tramp-send-command vec command t t))
                ;; Now do all the connections as specified.
                (while target-alist
                  (let* ((hop (car target-alist))
@@ -5159,6 +5196,10 @@
          (format "%s <%%s" coding)))))))
+(defun tramp-mosh-process-filter (process string)
+  (message "tramp mosh process filter got %s" string)
+  (insert string))
 ;;; Integration of eshell.el:

=== modified file 'lisp/net/tramp.el'
--- lisp/net/tramp.el   2012-12-18 13:37:06 +0000
+++ lisp/net/tramp.el   2012-12-21 10:13:47 +0000
@@ -3100,7 +3100,25 @@
          (setq mode-line-process '(":%s"))
          (set-process-sentinel p 'shell-command-sentinel)
-         (set-process-filter p 'comint-output-filter))
+         ;; maybe set the process filter to tramp-process-filter
+         ;; (wrapped in a check to ensure we don't overwrite an
+         ;; existing output filter)
+         (with-current-buffer output-buffer
+           (unless (process-filter (current-buffer))
+             (let ((filter
+                    (tramp-get-method-parameter
+                     (tramp-file-name-method
+                      (tramp-dissect-file-name default-directory))
+                     'tramp-process-filter)))
+               (when filter
+                 (set-process-filter p filter)))))
+         ;; maybe set the process filter to comint-output-filter
+         ;; (wrapped in a check to ensure we don't overwrite an
+         ;; existing output filter)
+         (unless (process-filter (current-buffer))
+           (set-process-filter p 'comint-output-filter)))
          ;; Run the process.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]