サブプロセスの中断とサスペンド

何だかお仲間を見付けるのは嬉しいものです。
Emacs on Cygwin という環境は、Windows を利用せざるを得ない状況では、非常に心強い環境なので、私は離れられません。
元々は XEmacs を利用していましたが、Emacs 22 の頃にようやく移行して、今では Emacs 23 が何とか馴染んできたかな、という具合です。

ところが少し前から bash の起動に異常に時間が掛かる様になり、なんだか非常に使い勝手が悪いと感じて Google さんに訊いていたところ、その問題とは違いますが、同じ shell 繋がりの悩みを持たれたお仲間を発見したのでした。
発見したのは、

Windows で Emacs 内部 shell をストレスなく動かす = Cygwin + sshd + XMing + VMWare + Ubuntu + Emacs + Tramp + shell-mode

で、当然のごとく Emacs + shell-mode を Cygwin で使おうとしたらこれが使えない:

  • コマンドを殺せない (C-c C-c)
  • コマンドをサスペンドできない(C-c C-z)

これはキツい。まるで、 unix 演習で学生が作った shell で仕事をするような辛さ。

という記事です。
Emacs の shell-mode が好き」と仰っている時点でお仲間認定です。(手前勝手な言い草ですが)

私の場合、XEmacs から Emacs 22 へ移行した (二年半くらい前かな?) 後、しばらくしてからこの現象に気が付き、やっぱり非常に難儀したのでした。

で、これ、id:camlspotter さんも仰られてますが、ssh-mode だと問題ないんですよね。なので、M-x ssh localhost すれば解決、そんなに極端に遅くないし……

という訳にも行かないので ssh-mode の中身を覗いてみたところ、shell-mode とは実装が違うのですよね。当然ですが。
shell-mode では `interrupt-process' とか `stop-process' などのシグナルを送るインタフェースを使ってるんですが、ssh-mode では `process-send-string' を利用して制御文字を送ってました。

なので、こいつを拝借して、

;; ssh の関数 `ssh-send-Ctrl-C', `ssh-send-Ctrl-Z' の実装を流用して乗っ取る。
(defadvice comint-interrupt-subjob (around ad-comint-interrupt-subjob activate)
	(process-send-string nil "\C-c"))
(defadvice comint-stop-subjob (around ad-comint-interrupt-subjob activate)
	(process-send-string nil "\C-z"))

と、shell-mode の関数を乗っ取ってしまいました。包囲アドバイスで `process-send-string' を呼び出して終了してしまいます。実体の関数は呼び出しません。

本来は shell-mode の実装の方が良いのでしょうが、これで取り敢えず、サブプロセスの中断と一時停止はできる様になっています。
id:camlspotter さんは、Linux 上の Emacs が使える様になったので、もう不要かもしれませんが。
やっぱり Unix 上 の Emacs の方が反応が良くて良いのですよね。Cygwinsshd は反応悪いですけど、Tramp で Cygwin に login する分には、一旦、login してしまえば、補完も含めて反応もそんなに悪くないですし。
母艦は Linux だよなあ…… 「天麩羅いやざんす」とか言う奴のせい ;-) で難しかったんだけど、そろそろ会社でも Linux のマシンを使えそうだから移行するかなあ。

ああ、bash の起動が遅くなった件は何も解決していない…… 一体、何が影響してるんでしょうか……