tmux
termcap and terminfo
termcap(5) terminfo(5) term(5) あたりに詳しい説明が有る。初代はtermcapな文字列で 端末の挙動を記述したもの。それが巨大になってきたのでtic(1)と言うコンパイラーを 使ってバイナリーにした。それがterminfo。アプリから手軽に利用可能としたのが (n)cursesになる。
初代の文字列ベースが、/usr/src/share/termtypes/termtypes.masterとしてOpenBSDに 収録されてる。
ob$ egrep '^[a-z]' termtypes.master | wc 1813 9207 89204
雑に調べただけで、1800種類の端末が登録されてる。
ob$ egrep '^[a-z]' termtypes.master | sort | grep kterm kterm-color|kterm-co|kterm with ANSI colors, kterm|kterm kanji terminal emulator (X window system), tt|tkterm|Don Libes' tk text widget terminal emulator,
超昔に世話になった、漢字ターミナルなんてのも残っている。歴史博物館だな。
#### KTERM # (kterm: this had extension capabilities ":KJ:TY=ascii:" -- esr) # (kterm should not invoke DEC Graphics as the alternate character set # -- Kenji Rikitake) # (proper setting of enacs, smacs, rmacs makes kterm to use DEC Graphics # -- MATSUMOTO Shoji) # kterm implements acsc via built-in table of X Drawable's kterm|kterm kanji terminal emulator (X window system), XT, ncv@, acsc=``aajjkkllmmnnooppqqrrssttuuvvwwxx~~, csr=\E[%i%p1%d;%p2%dr, enacs=, kmous=\E[M, rc=\E8, rmacs=\E(B, rmam=\E[?7l, sc=\E7, sgr=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;m%?%p9%t\E(0%e \E(B%;, sgr0=\E[m\E(B, smacs=\E(0, smam=\E[?7h, use=x10term+sl, use=xterm-r6, use=ecma+color, kterm-color|kterm-co|kterm with ANSI colors, ncv@, use=kterm, use=ecma+color,
中身はこんな暗号に近い記述になってる。termcap(5)が解読用の説明書なんで、読ん でくれたまえ(あなたが古文書学者なら。そう言えば武士の家計簿を解析して大出世 された先生がおおられるな)
infocmp
暗号解読の一助になるユーティリティーが昔から提供されている。本来は各種の terminfoを比較するもの。なんだけど、単独のterminfoでも大丈夫。例として 馬鹿端末(通常の端末はインテリ端末 - これじゃどこかの大学出みたいなんで、 インテリジェント端末と言う)である、dumbを例にしてみる。
ob$ infocmp -l dumb # Reconstructed via infocmp from file: /usr/share/terminfo/d/dumb dumb|80-column dumb tty, am, cols#80, bel=^G, cr=\r, cud1=\n, ind=\n,
逆アセしてくれるんだけど、短縮系でピンとこない。
ob$ infocmp -L dumb # Reconstructed via infocmp from file: /usr/share/terminfo/d/dumb dumb|80-column dumb tty, auto_right_margin, columns#80, bell=^G, carriage_return=\r, cursor_down=\n, scroll_forward=\n,
これなら多分大丈夫(GUIユーザー意外の人ね)。
ob$ infocmp -c dumb comparing dumb to tmux. comparing booleans. am= T. bce= F. bw= F. : comparing numbers. cols= 80. comparing strings. bel= '^G'. cr= '\r'. cud1= '\n'. ind= '\n'.
そしてこちらは、そこはかとなくC言語風。infocmpの本性が表われて、今設定してる 端末(この場合はtmux)との比較結果が表示される。論理値の場合でdumbに存在 しない定義は、Fと表示される。こういったユーティリティもC言語対応になってる。 ubuntuの次期バージョンは、コア・コマンドがrust製になると言われているけど、 そうなると、こう言った資産はどうなるの? そこはかとなく心配。
だったら、そういうのは頑無視して、OpenBSDを母港にすれば宜しい。7.7も順調に リリースされた事だしね。
tty/pty
プロセスのツリーを表示してみる。
sakae@lu:~$ pstree | lv : |-sddm-+-Xorg---5*[{Xorg}] | |-sddm-helper---lxqt-session-+-agent---3*[{agent}] | | |-mlterm---bash---TOGO---tmux: client | | |-tmux: server-+-bash-+-less | | | | `-pstree | | | |-bash---emacsclient | | | `-bash---ssh
ttyなんてコマンドも有ったな。 vmwareして起動し、ssh した場合。
vm$ tty /dev/ttyp0
ソースはこんな所に有った。 /usr/src/usr.bin/tty/tty.c
t = ttyname(STDIN_FILENO); if (!sflag) puts(t ? t : "not a tty"); exit(t ? 0 : 1);
wscons
前回目を付けてvt100のエミュレーションが動作するだろと思った奴が駄目だった。 少々悔しかったのでmanしたのさ。そしたら
NAME wscons - workstation console access
やっとwsの意味が判明。パソコンなのにワークステーションとはおそれ入った 名前だなあ。
Alt-Ctl-Fnでコンソールを切り替えられるようになってる。いわゆる仮想 コンソールだ。リナにも同様な機能が搭載されてるから当たり前の機能か。 まあ、普通の人はOS起動時からGUIに行ってしまうから、余り目にする事は 無いだろうけど。
qemu-kvmから使っているOpenBSD-i386 VGAな端末は表示しない設定で、起動時 からcom1画面を展開してる。
qe$ stty -a speed 38400 baud; 34 rows; 0 columns; lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo -extproc -xcase iflags: -istrip icrnl -inlcr -igncr -iuclc ixon -ixoff ixany imaxbel -ignbrk brkint -inpck -ignpar -parmrk oflags: opost onlcr -ocrnl -onocr -onlret -olcuc -oxtabs -onoeot cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -mdmbuf cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>; eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q; status = <undef>; stop = ^S; susp = ^Z; time = 0; werase = ^W; qe$ echo $TERM tmux
こんな風な確認は初めてだな。
qe$ sysctl -a | grep cons kern.consdev=tty00 kern.consbufsize=16364 machdep.console_device=tty00 ddb.console=0
そして、これも初見だ。
qe$ doas wsconscfg 1 wsconscfg: screen 1 is already configured qe$ doas wsconscfg 10 wsdisplay0: screen 10 added (80x25, vt100 emulation)
今、どんな設定になってるかも詳細にレポート出来るぞ。
te$ doas wsconsctl -a keyboard.type=pc-xt keyboard.bell.pitch=400 keyboard.bell.period=100 keyboard.bell.volume=50 keyboard.bell.pitch.default=400 keyboard.bell.period.default=100 keyboard.bell.volume.default=50 wsconsctl: Use explicit arg to view keyboard.map. keyboard.repeat.del1=400 keyboard.repeat.deln=100 keyboard.repeat.del1.default=400 keyboard.repeat.deln.default=100 keyboard.ledstate=0 keyboard.encoding=us mouse.type=ps2 mouse.reverse_scrolling=0 display.type=vga-pci display.fontwidth=8 display.fontheight=16 display.emulations=vt100 display.screentypes=80x25,80x25bf,80x40,80x40bf,80x50,80x50bf display.focus=0 display.screen_on=250 display.screen_off=0 display.vblank=off display.kbdact=on display.msact=on display.outact=on
これを見る限り、VGAな端末上で動作する仮想端末では、vt100のエミュレーション 機能が動作すると思われる。
VGAな端末から操作すると、カーネルのそれなりの場所でブレークしたよ。雪辱を果た して大成功であります。
(gdb) bt 12 #0 wsemul_vt100_output_esc (edp=0xd0f1f2f0 <wsemul_vt100_console_emuldata>, instate=0xd0f1f3fc <wsemul_vt100_console_emuldata\ +268>) at /usr/src/sys/dev/wscons/wsemul_vt100.c:512 #1 0xd04187b2 in wsemul_vt100_output (cookie=0xd0f1f2f0 <wsemul_vt100_console_emuldata>, data=0xd23a6002 "H\033[J\033[3JI+pU \ 0:00.11 /usr/libexec/getty std.9600 ttyC5\r\n\n 10-100 startups (sshd)\r\ny secure Unix-like operating system.\r\n\r\nPlea\ se use the sendbug(1) utility to report bugs in the system.\r\nBefore re"..., count=8, kernel=0) at /usr/src/sys/dev/wscons/ws\ emul_vt100.c:1228 #2 0xd03908e3 in wsdisplaystart (tp=0xd23a3600) at /usr/src/sys/dev/wscons/wsdisplay.c:1534 #3 0xd075394c in ttstart (tp=0xd23a3600) at /usr/src/sys/kern/tty.c:1370 #4 0xd0756d3f in ttwrite (tp=0xd23a3600, uio=0xf0b5eda4, flag=1) at /usr/src/sys/kern/tty.c:1869 #5 0xd0391166 in wsdisplaywrite (dev=3072, uio=0xf0b5eda4, flag=1) at /usr/src/sys/dev/wscons/wsdisplay.c:1031 #6 0xd04d554b in spec_write (v=0xf0b5ecf0) at /usr/src/sys/kern/spec_vnops.c:302 #7 0xd038cb79 in VOP_WRITE (vp=0xd2295b00, uio=0xf0b5eda4, ioflag=1, cred=0xd2395e10) at /usr/src/sys/kern/vfs_vops.c:245 #8 0xd0346446 in vn_write (fp=0xd22fa964, uio=0xf0b5eda4, fflags=0) at /usr/src/sys/kern/vfs_vnops.c:408 #9 0xd0232cb4 in dofilewritev (p=0xd236d008, fd=1, uio=0xf0b5eda4, flags=0, retval=0xf0b5ee28) at /usr/src/sys/kern/sys_gener\ ic.c:380 #10 0xd0232aa3 in sys_write (p=0xd236d008, v=0xf0b5ee30, retval=0xf0b5ee28) at /usr/src/sys/kern/sys_generic.c:300 #11 0xd06be629 in mi_syscall (p=0xd236d008, code=<optimized out>, argp=<optimized out>, retval=<optimized out>, callp=<optimiz\ ed out>) at /usr/src/sys/sys/syscall_mi.h:179 (More stack frames follow...)
これを見ると、きっかけはユーザーランド側が発するwriteシステムコールって事だ。 このバックトレースを元に、提示されたファイルをトラバースしてくれるアプリを 作りたいぞ。どうもgdb中は落ち付いて閲覧するのを躊躇うってしまうからね。 本気で考えたいぞ。
tmux
コンソールってか端末を切り替える操作なら、何時もお世話になってるぞ。sshで リモート・ホストにログイン。して、ログイン先であたかも端末が複数存在するが ごとく振る舞う奴だ。これが表の顔だ。が、地味だけど、とっても嬉しい裏の顔も 存在してる。何かの拍子に接続が切れてしまっても、またログイン仕直して 再接続すれば、切断前の 状況に戻れる事。
人によっては、こちらの方が嬉しいかも知れない。リモートで作業開始。例えば OSのrelease(8)メディアを作成する場合とかだ。あんた勝手に作業を進めておいてね。 私は帰宅するから。こんな場合は、心情的にリモートとの切断を切ってしまいたい。 そして、翌朝、リモートに接続して、作業具合を確認するとかね。
これから、この興味深いtmuxを調べていきたいと思うけど、その前に少し下調べしとく。 linux sideでqemuを起動。リソースの割り当てを確認。
sakae@lu:~$ ps a | grep qemu 3465 pts/3 Sl+ 6:22 qemu-system-i386 -m 512 -nographic -no-fd-bootchk -s -net nic -net user,hostfwd=tcp::2022-:22 -hda disk sakae@lu:~$ lsof -p 3465 : qemu-syst 3465 sakae 0u CHR 136,3 0t0 6 /dev/pts/3 qemu-syst 3465 sakae 1u CHR 136,3 0t0 6 /dev/pts/3 qemu-syst 3465 sakae 2u CHR 136,3 0t0 6 /dev/pts/3 qemu-syst 3465 sakae 3u IPv4 29382 0t0 TCP *:2022 (LISTEN) qemu-syst 3465 sakae 4u a_inode 0,15 0 3102 [eventfd:80] qemu-syst 3465 sakae 5u a_inode 0,15 0 3102 [signalfd] qemu-syst 3465 sakae 6u a_inode 0,15 0 3102 [eventfd:82] qemu-syst 3465 sakae 7u a_inode 0,15 0 3102 [eventfd:81] qemu-syst 3465 sakae 8u REG 8,2 4644143104 4610775 /var/my/qemu/qe/disk qemu-syst 3465 sakae 9u unix 0x0000000000000000 0t0 14952 type=STREAM (CONNECTED) qemu-syst 3465 sakae 10u unix 0x0000000000000000 0t0 14953 type=STREAM (CONNECTED) qemu-syst 3465 sakae 11u unix 0x0000000000000000 0t0 15791 type=STREAM (CONNECTED) qemu-syst 3465 sakae 12u unix 0x0000000000000000 0t0 15792 type=STREAM (CONNECTED) qemu-syst 3465 sakae 13u IPv4 29386 0t0 TCP *:1234 (LISTEN) qemu-syst 3465 sakae 14u IPv6 29387 0t0 TCP *:1234 (LISTEN) qemu-syst 3465 sakae 21r a_inode 0,15 0 3102 inotify
OpenBSD sideは、端末起動時、tty00だった。そこからtmuxを起動して、2つのkshを 動作させた。サーバーの配下でkshは動作してる。
qe$ pstree -+= 00001 root /sbin/init |--= 10384 root sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups (sshd) |-+= 65817 sakae tmux: server (/tmp/tmux-1000/default) (tmux) | |--= 91425 sakae -ksh (ksh) | \-+= 12331 sakae -ksh (ksh) | \-+= 23918 sakae pstree | \-+- 82513 sakae sh -c ps -kaxwwo user,pid,ppid,pgid,command | \--- 93163 sakae ps -kaxwwo user
pstreeのCUI版でも確認。
qe$ ps xj USER PID PPID PGID SESS JOBC STAT TT TIME COMMAND sakae 65817 1 65817 0 0 Sp ?? 0:11.43 tmux: server (/tm sakae 91425 65817 91425 0 0 I+p p0 0:00.55 -ksh (ksh) sakae 12331 65817 12331 0 0 Sp p1 0:00.63 -ksh (ksh) sakae 88446 12331 88446 0 1 R+pU p1 0:00.03 ps -xj sakae 95525 1 95525 0 0 Ip 00 0:00.57 -ksh (ksh) sakae 41126 95525 41126 0 1 I+p 00 0:00.29 tmux: client (/tm
fstatはリナのlsofに相当する(情報量は違うけど)。
qe$ fstat -p 12331 USER CMD PID FD MOUNT INUM MODE R/W SZ|DV sakae ksh 12331 text / 959059 -r-xr-xr-x r 706784 sakae ksh 12331 wd / 1036801 drwxr-xr-x r 512 sakae ksh 12331 0 / 416487 crw--w---- rw ttyp1 sakae ksh 12331 1 / 416487 crw--w---- rw ttyp1 sakae ksh 12331 2 / 416487 crw--w---- rw ttyp1 sakae ksh 12331 10 / 417149 crw-rw-rw- rwep tty qe$ tty /dev/ttyp1
ttyコマンドは、ちゃんと動作してるな。
裏の顔の確認
急に端末が切れたをやってもいいんだけど、それじゃあんまりなんで tmux detach で、自主的に切ってみる。
tmuxして起動。時間がかかるコンパイルを実施。その間に2番目の端末で起動 状態を確認。そしてdetach
te$ ps awx | grep tmux | grep -v grep 13012 ?? Sp 0:01.10 tmux: server (/tmp/tmux-1000/default) (tmux) 77164 p0 I+p 0:00.12 tmux: client (/tmp/tmux-1000/default) (tmux) te$ tmux detach
tmuxのステータス・バーは消失した。けど、コンパイルは継続されてる。
te$ tmux [detached (from session 0)] te$ ps a PID TT STAT TIME COMMAND 66096 p0 Sp 0:00.05 -ksh (ksh) 21598 p0 R+pU 0:00.01 ps -a 43628 p1 S+p 0:00.24 -ksh (ksh) 53694 p2 Ip 0:00.12 -ksh (ksh) 74956 p2 S+p 0:00.16 make 48787 p2 R+ 0:00.55 cc -g -O0 -I/usr/src/usr.bin/tmux -Werror-implicit-f te$ ps awx | grep tmux | grep -v grep 13012 ?? Ip 0:01.25 tmux: server (/tmp/tmux-1000/default) (tmux) te$ tmux attach
アッタッチすると、再びステータス・ラインが出現。
: cc -o tmux alerts.o ... -lutil -lcurses -levent -lm te$ ps awx | grep tmux | grep -v grep 13012 ?? Sp 0:01.49 tmux: server (/tmp/tmux-1000/default) (tmux) 24090 p0 I+p 0:00.09 tmux: client (/tmp/tmux-1000/default) (tmux)
コンパイルは無事に完了してた(記録が残る、ありがたい仕様)。そしてtmux clientは新たに創成されてた。 serverの方はそのまま鎮座してた。このserverが消えるのは、tmuxで起動してる アプリ(通常はshell)が全て終了した時だ。
なお、このtmuxはOpenBSDの標準配布物になってる。昔、そんな事を知らないオイラーは GNU screenを使ってた。余計な物は入れるな主義なんでtmuxに乗り換えた経緯がある。 何と言ってもソースが目の前に有る安心。そして現在もたぬまぬ拡張が続いている。 OpenSSHやらLibresslと同様に大事にメンテナンスされてる証拠。これはもう見るしかないね。
README
ポップな表紙につられて手に取ってみた。表紙のオネーさんは誰? ちょいと気に なるぞ。ちあきなおみの '喝采' とか、奥村チヨさんの '終着駅' を絶賛されて たから、このどちらかだろう。ああ、なおみさんだった。
先生の勧めで YouTube を聞いてみた。昭和歌謡メドレー とかで検索すると山の ように出てくる。著作権大丈夫か??
アメリカン・フィーリング サーカス これならJALのCMソングだったから大丈夫だな。 懐かしい曲だな。