3

I used emacs' tramp-mode to edit root-owned files with the syntax /sudo::<filepath>

This works perfectly well, but I cannot seem to get tramp to end the sudo session without manually killing the subprocess via htop or some other process manager. The tramp-cleanup-*-connection commands do not end the session.

How do I get emacs to end the sudo session? Ideally, I would like it to end the session once all sudo-opened buffers are killed.

ramLlama
  • 33
  • 3

1 Answers1

0

I don't know why you say "The tramp-cleanup-*-connection commands do not end the session"; my quick test indicates that tramp-cleanup-this-connection forces Tramp to reconnect the next time I try to do something. (It caches the password separately, so you don't necessarily get a password prompt; but you should see "Opening connection" in the *Messages* buffer.)

Here is a quick stab at a function you could add to your kill-buffer-hook. It's not very elegant, but it seems to work.

(defun tramp-cleanup-sudo-maybe ()
  "If the current buffer is a Tramp \"/sudo:\" buffer, cleanup its connection
if there are no other sudo buffers remaining after killing this one."
  (save-match-data
    (let ((name (buffer-file-name))
          prefix buffers)
      (when (and name (string-match "\\`\\(/sudo:[^:]*:\\)" name))
        (setq prefix (match-string 1 name))
        (mapc (lambda (buf)
                (when (string-prefix-p prefix (or (buffer-file-name buf) ""))
                  (setq buffers (cons buf buffers)) ))
              (buffer-list) )
        (when (< (length buffers) 2)
          (tramp-cleanup-this-connection) ) ) )))

This could get slow if you have a lot of buffers. If you feel the need to optimize it, I suppose you could add something like a connection count per remote to an alist of your own (or maybe to some existing Tramp connection structure). Or actually just store the length of the buffer list (minus one, for the buffer we are about to kill) in a global, and then on the next invocation, simply decrement it -- only when it reaches zero, scan all buffers again and reinitialize the variable; and cleanup if it really is the last sudo buffer with this prefix.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Hm...you are right, it does actually work. Not sure why I thought it didn't... I'll look into making an alist for automatic cleanup. I didn't know about `kill-buffer-hook`, so that is useful, thanks! – ramLlama May 22 '15 at 23:54
  • The alist is probably overkill. As a first approximation, you could check the tramp file name, and if it's a `/sudo::` buffer, loop over open buffers and not do the cleanup if there's more than one of them. If it turns out to be slow, maybe set a global counter, decrement when you kill, and loop (and reinitialize the counter if there are new sudo buffers) only when it reaches zero. – tripleee May 23 '15 at 07:08
  • Updated with actual code; significantly refactored the text to reflect my somewhat improved understanding. – tripleee May 23 '15 at 08:43