2002-10-21 (Mon) [長年日記]

Meadow2: Emacs Internals - Lisp_Object と Lisp_Symbol と intern() について

宴会にて伝授してもらったことを忘れないうちにメモ。himiさん、林くん、後藤さん、ありがとう。

intern() とは Emacs の obarray 名前空間の中で唯一無二の Symbol を生成する(参照を返す?)のが intern() の役割。Lisp_Object は Emacs ではもっとも primitive な要素である。

File System の i-node と i-node 番号、とファイル名の関係になぞらえると理解しやすい。

Lisp_Symbol は valiable,function,plist,obarray の 4 つの slot を持ち、make_symbol() や build_string() 等によって、それぞれの slot へset される。

intern() によって初期化された Lisp_Object へ make_symbol() すると別の instance となり、もともとの Lisp_Object とは EQ が成立しなくなる。

値を「束縛」できるのは variable のみ。

Meadow2: Emacs Internals - 接頭辞が QC の Lisp_Object とはなにか

Collon の C である。Common Lisp の慣習として関数へ渡す keyward の接頭辞として ":" を使用するところからきている。

接頭辞が ":" の Symbol はデフォルトで評価されなくなるので、クォートする必要がなくなる。ちょっと便利。

constness (defconst) とは無関係。

Meadow2: Emacs Internals - C の Lisp_Object の 変数名は、なぜ Q を接頭辞にするのか

慣習。そういうもんだ。

Meadow2: Emacs Internals - GC と GC PROTECTION の使いどころ

Emacs の GC や GC PROTECTION は環境ごとにカリカリにハンドオプティマイズされているため、一概に「こう使え」と言えるものではない。以下は指針のようなもの。

Emacs では GC の発生しうる操作が決まっており、それは (eval) と (funcall) のみである。C で Lisp_Object を操作するにあたって、(eval) や (funcall) が呼び出され再配置が発生する可能性があるコードブロックの前に Lisp_Object を GCPRO() で保護する。

簡単な操作(Fcons, XCAR, XCDR 等)では、GC が発生しないので保護しなくてもよい場面は多い。

しかし hook 等で簡単に予想外の GC が起こる可能性があるので注意。迷ったら保護しておくに越したことはない。

たとえば C から Lisp_Object を新規に生成する場合は GCPRO() したほうがよい。

もっとも注意しなくてはならないのが GCPRO() は初期化済みのLisp_Object のみを扱えるということ。未初期化の変数を GCPRO() へ渡すと関数と勘違いして退避したりしてしまうので、恐ろしい bug を誘発する。必ず Qnil などで初期化する必要がある。

mw32_file_dialog() は GCPRO() しすぎている上に肝心なところが GCPRO() されていない。要修正。

Zebedee

先日の stone が切れてしまう件は、サーバ側の stone が core を吐いて落ちていたため。今度はひとつの port から複数サーバにトンネリングできる Zebedee を実験してみる。

Asumi日記よりトンネル掘削機を参考にしたが、実行するコマンドの例などに間違いがあるようだ。

また最後に「マルチターゲットで接続すると ssh で 「Permission error」で失敗」とあるが、これは localhost という同じホスト名のサーバがポートによって異なる fingerprint を返すようになるため、.ssh/known_hosts にすでに登録されている id と異なってしまうのが原因と推測されるがどうだろうか。こちらでは .ssh/known_hosts の該当行を削除することで、マルチターゲットのどちらも接続することができた。

Zebedee サーバ側の設定 トンネル掘削機では checkidfile のファイル名に typo あり。
#! /usr/bin/zebedee -f
server true
compression zlib:9      # Allow maximum zlib compression
checkidfile '/usr/local/etc/zebedee/server.id' # public keys
logfile '/var/log/zebedee.log'
serverhost localhost
serverport https
redirect ssh
target server1:22
target server2:22

Client の HTTP Proxy 越え用 stone

"/http"オプションがないとうまく動作しなかった。またトンネル掘削機では port 番号も typo しているように思われる。
stone.exe proxy:8080/http 10443 "CONNECT server:443 HTTP/1.0"

Client 側 Zebedee 設定(Win)

include するファイル名はフルパスのほうが確実。またパスに空白がある場合は " でクオートする。
#!/usr/local/bin/zebedee -f
#debug true
#verbosity 5
server false
include 'C:\user\.zebedee\zebedee.key' # private key
logfile 'zebedee.log'
localsource true
serverhost localhost  # server host name
serverport 10443
tunnel 10022:server1:22
tunnel 10122:server2:22

これで会社から安心して Meadow リポジトリにアクセスできるようになった。快適。

Re: tDiary: 本日のハンティング

捕獲ありがとうございます。トンネル掘削機のお陰で非常に快適な環境になりました。

known_hosts は実験済みですか。う〜ん。

うちも DNS が引けないので最初は同じように hosts と .ssh/config に登録していたのですが、これだとサーバ側の Zebedee が target を見誤るようで、127.0.0.1 へトンネリングしようとして失敗してしまう感じでした。client にも server にも複数インターフェースあるので、そのへんも関係するかも?

今は、 OpenSSH は Meadow リポジトリ用、PuTTY は自宅サーバ用と known_hosts が別れているので、あまり困らないため hosts への登録を削除しています。