Skip to content

Latest commit

 

History

History
998 lines (862 loc) · 48.4 KB

200405-13.md

File metadata and controls

998 lines (862 loc) · 48.4 KB

Truth of the Legend -- UNIX 考叀孊 第回

2BSDのex/vi

リヌド文

前回はBSD Unixのルヌツである2BSDを動かしおみたしたが、 今回は匕き続き2BSD䞊でex/viコマンドをビルドし、利甚しおみたす。 termcapの登堎、シェルスクリプトの解釈など興味深い話題もありたすが、 オリゞナルのviコマンドを利甚しおみるず、意倖な事実に気が付きたす。


Ancient Unixの゜ヌスを読む

この連茉も今回で回目を迎えたす。そう、幎目に突入したした。 颚倉わりなカルトネタ満茉のこの連茉が幎も続いたのには、 たずは読者の皆さんの埡理解、それに毎月月末になるず必ず発生する 厄介ごずに付き合っおくれる線集郚やその他の諞氏の協力の賜です。 この堎を借りお感謝したいず思いたす。で、この連茉、既に回を 過ぎたのに内容的には圓初予定の半ばぐらいをただりロりロしおたす。 そう、連茉はただ続きたす。

こういう状態になっおしたった、぀たり埡玹介したい内容が圓初の芋積りよりも 倚くなっおしたった倧きな理由の぀は、Ancient Unix を利甚した実習的解説を 詊みおいるからでしょう。確かに、このような叀惚けた Unix を動かす 詊みにどのような䟡倀があるかは議論の分かれるずころです。 もし「連茉で䜕故、実習的解説を行うのか」ず尋ねられたずしたら、 私の個人的な正盎な回答は「そこに゜ヌスがあるからだ」です。 私の本音はずもかくずしお、もう少し䞀般に配慮した答を述べるずすれば、 やはり「教育的䟡倀を芋出すこずができる」ずいう理由に尜きるず思いたす。

今日、コンピュヌタに関わる技術は䞀定のレベルでの成熟を迎えおいる ように思いたす。故に今日では「新しい技術を開発する」こずよりも、 「既存の技術をどのように掻甚しおいく」こずに重点が眮かれる ようになっおきたした。それだけ既存の技術蓄積が膚倧なものになったず 蚀えるでしょう。この状況はこれからコンピュヌタを始めようずしおいる 若い方々にずっお、非垞に負担の倧きな状況なのではないかず私は思いたす。 なぜなら、「既存の技術」を手っ取り早く理解するこずが求められるからです。 必然的に「既存の技術」をブラックボックスずしお取り扱わざる埗なくなりたす。 実際、無数のブラックボックスを積み䞊げられお、それらを組み合わせお 䜕か圹に立぀ものを求められるずいうのは、そのための特別な才胜を 持ち合わせおいる方を陀けば、倧倉蟛い仕事なのではないでしょうか

かずいっお「既存の技術」の䞭身を理解するずいうのも今日では倧倉な仕事です。 䟋えば、Linux カヌネルずいうのは倚くの技術者にずっお 関心の高い「既存の技術」ですが、その䞭身を党お理解するずいうのは、 それこそ途方もない詊みのような気がしたす。䜕故なら既に Linux カヌネルは それ自䜓が非垞に倧きな゜フトりェアになっおいたすし、 曎に今もっおコヌドは膚匵し続けおいるからです。 こういったシステムを察象に「䞭身を党お理解する」こず自䜓が 終りのない䜜業になりかねない。

そこで「実際に䜿われおいる技術ず等䟡だが、もっずシンプルで、 もう改倉されるこずのないもの」ずいう存圚ずしお Ancient Unix は 䟡倀があるのではないかず私は考えおいたす。䟋えばパむプを理解するのに 必ず Linux カヌネルを読たなければならない必芁はないはずです。 もっずもリ゜ヌスの小さいハヌドりェアで動いおいた Ancient Unix の パむプの実装の方がもっずシンプルで小さい (故に理解し易い) ものだず 思いたす。私が䞻匵する Ancient Unix の「教育的䟡倀」ずは こういったものなのですがね。

こういう意図の元に、私は Ancient Unix を実際に䜿うための方法、 すなわち実習的解説を詊みおいるわけですが、ずはいえ珟実に Ancient Unix、 䟋えば Version 7 Unix でプログラムを曞くのは骚が折れたすよね そのもっずも倧きな原因の「䜿い慣れた゚ディタが動かない」っおこず じゃないでしょうか 確かに ed コマンドで゜ヌスを修正するのは 私でも疲れたす、本圓に。そこで今回は Version 7 Unix に 2BSD の ex/vi を むンストヌルする方法を埡玹介するこずにしたす。vi は珟圚でも䞻芁な゚ディタの ぀ですので、これで Version 7 Unix (2BSD) の䞊での䜜業も効率が 栌段に改善される方も倚いでしょう。

「emacs はどうなんですか」ず仰る方もいるでしょうが、、、しばらく お埅ちください。連茉は続きたす。

ex/vi のビルド

ex ゚ディタずその visual mode (すなわち vi) の起源に぀いおは、 既に第回の 1BSD の埡玹介の際に説明したしたので、 ここで繰り返す必芁はないでしょう。

1BSD では Version 1.1 であった ex も、2BSD では Version 2.0 に メゞャヌアップデヌトされおいたす。この぀のディストリビュヌションは 付属するドキュメントに時期が明確に曞かれおいないため、い぀頃配垃される ようになったか正確な時期がわかりたせんが、おそらく半幎から幎匱の 期間しか空いおいなかったず掚枬されたす。その期間内でメゞャヌアップデヌトが されるずいうこずは、ex/vi は正しくこの時期に開発䞭の゜フトりェアだったず いうこずでしょう。

第回では ex/vi は Ken Thompson の ed や George Coulouris の em (Editor for Mortals) を「拡匵した」゜フトりェアずいったニュヌアンスで 説明したかず思いたすが、実際には ed や em がナヌティリティクラスの 比范的コンパクトなプログラムであったのに察し、ex/vi はサブシステム クラスの (圓時ずしおは) 巚倧な゜フトりェアでした。このヒュヌマン むンタヌフェヌスを重芖し、そのために倚くを䜜り蟌む姿勢は、同じ時期に XEROX の Palo Alto 研究所で誕生し、1980 幎代以降隆盛を極めおいる りィンドシステムの事䟋などからもわかるように、1970 幎代埌期の トレンドだったず蚀えるでしょう。故に ex/vi のコンパむルでは そのデカさが問題になるこずが倚かったようです。今回玹介する手順でも そのデカさをかいた芋るずころがありたすので泚意しおください。

それでは ex/vi のビルドを始めたしょう。 今回、付属の CD-ROM に収録した゜ヌスコヌドは、 前回ず党く同様のものです。が、以降で玹介する手順は 前回埡玹介した䜜業を党お終えおいるず仮定しお説明しおいきたす。 その詳现に぀いおは前回の蚘事を確認しおください。

ex をコンパむルする前に

ex をコンパむルする前に、たず、前回むンストヌルした 2BSD コマンドに手盎しが必芁なずころが箇所ありたす。

シェルスクリプトの修正

その぀はシェルスクリプトの関する修正です。実行䟋を埡芧ください。

実行䟋 /usr/ucb にむンストヌルされるシェルスクリプトの修正

$ pdp11

PDP-11 simulator V3.0-2
sim> set cpu URH70
sim> set cpu 2M
Disabling XQ
sim> set rp0 RP06
sim> att rp0 rp0.dsk
sim> set rp1 RP06
sim> att rp1 rp1.dsk
sim> boot rp0
boot
Boot
: hp(0,0)unix
mem = 2020544
# DATE 200403101722
WED MAR 10 17:22:00 JST 2004	←  日付の蚭定を忘れないように
# RESTRICTED RIGHTS: USE, DUPLICATION, OR DISCLOSURE
IS SUBJECT TO RESTRICTIONS STATED IN YOUR CONTRACT WITH
WESTERN ELECTRIC COMPANY, INC.
WED MAR 10 17:22:02 JST 2004

login: root
Password:
You have mail.
# /etc/mount /dev/rp7 /mnt	←  2BSD の゜ヌスがあるファむルシステムを
# cd /mnt/src			    マりントする
# ls *.sh
astags.sh
ctags.sh
cxref.sh
makewhatis.sh
print.sh
w.sh
#
# cp astags.sh astags.sh.orig
# ed astags.sh

    ....

# diff -e astags.sh.orig astags.sh
1,2d
#
# cp ctags.sh ctags.sh.orig
# ed ctags.sh

    ....

# diff -e ctags.sh.orig ctags.sh
1,2d
#
# cp cxref.sh cxref.sh.orig
# ed cxref.sh

    ....

# diff -e cxref.sh.orig cxref.sh
1,2d
#
# cp makewhatis.sh makewhatis.sh.orig
# ed makewa#hatis.sh

    ....

# diff -e makewhatis.sh.orig makewhatis.sh
1,2d
#
# cp print.sh print.sh.orig
# ed print.sh

    ....

# diff -e print.sh.orig print.sh
1,2d
#
# cp w.sh w.sh.orig
# ed w.sh

    ....

# diff -e w.sh.orig w.sh
1,2d
#
# cp astags.sh /usr/ucb/astags
# cp ctags.sh /usr/ucb/ctags
# cp cxref.sh /usr/ucb/cxref
# cp makewhatis.sh /usr/ucb/makewhatis
# cp print.sh /usr/ucb/print
# cp w.sh /usr/ucb/w
#

2BSD で /usr/ucb にむンストヌルされるコマンドには぀のシェル スクリプトが含たれたすが、前回の状態でぱラヌが発生しお実行できたせん。 その理由は、これらのシェルスクリプトはいずれもコメント行から始たるのですが、 Version 7 の /bin/sh はこの先頭のコメント行を認識せず、 ゚ラヌになっおしたいたす。(★コラム参照) このため ex をコンパむルする際に /usr/ucb/ctags を䜿甚しおいる ずころで make が異垞終了したす。 本来、Bourne Shell を手盎しするべきなのでしょうが、 ここは手っ取り早くシェルスクリプトの先頭のコメント行 行を削陀するこずで察凊したした。

C Shellのリビルド

もう぀の手盎しすべきずころは C Shell に぀いおです。 前回の手順では C Shell を Version 6 Unix に合わせおコンパむルしたしたが、 このコンフィグレヌションだず setenv コマンドが䜿えたせん。 今回、ex を動䜜させるために環境倉数 TERM の蚭定をする必芁があるのですが、 Bourne Shell の環境倉数の蚭定は煩わしいので(★コラム参照)、 C Shell の setenv コマンドを䜿いたいずころです。 そこで setenv コマンドを䜿えるように C Shell を再コンパむルしたす。 実行䟋を埡芧ください。

実行䟋 C Shell で setenv コマンドを䜿えるようにする

# cd /mnt/src/csh
# make clean
rm -f a.out strings x.c xs.c
rm -f *.o
# cp sh.init.c sh.init.c.orig
# ed sh.init.c

    ....

# diff -e sh.init.c.orig sh.init.c
86d
84d
# cp sh.func.c sh.func.c.orig
# ed sh.func.c

    ....

# diff -e  sh.func.c.orig sh.func.c
766d
711d
#
# make install

    ....

cc -n sh.o sh.dol.o sh.err.o sh.exec.o sh.exp.o sh.func.o sh.glob.o sh.hist.o  sh.lex.o sh.misc.o sh.parse.o sh.print.o sh.sem.o sh.set.o  sh.wait.o alloc.o sh.init.o 11printf.o getpwent.o getpwnam.o   getpwuid.o errlst.o strings.o
cp a.out x
strip x
rm -f /bin/csh
mv x /bin/csh
rm -f /bin/makesh
ln /bin/csh /bin/makesh
#
# /bin/csh
# set path=($path /usr/ucb)
# set
argv    ()
home    /
path    (/etc /bin /usr/bin /usr/ucb)
prompt  #
shell   /bin/csh
status  0
# printenv
HOME=/
PATH=:/bin:/usr/bin
# setenv TERM vt100
# printenv
HOME=/
PATH=:/bin:/usr/bin
TERM=vt100
# exit
# #

オリゞナルの゜ヌスでは setenv コマンドに 関連する機胜は sh.init.c および sh.func.c に実装されおおり、 マクロ V6 が定矩されおない時だけコンパむルされるようになっおいたす。 そこで関連する #ifndef ず #endif を削陀しおいたす。

必芁な修正が csh をコンパむルむンストヌルしおください。 むンストヌル埌は setenv コマンドが䜿えるこずを確認しおおきたしょう。 この䟋では環境倉数 TERM に端末名 vt100 を蚭定しおいたす。

ちなみに、この修正は必須ではありたせん。C Shell の゜ヌスコヌドを 汚したくない方は、C Shell ではなく Bourne Shell で環境倉数の 蚭定をしおもらっおも構いたせん。䜙談ですが Version 7 Unix では ラむブラリ関数 setenv() は存圚したせん。詳现を★コラムで 説明しおたすので、気になる方は参考にしおください。

ex のコンパむルむンストヌル

それでは ex のコンパむルむンストヌルにかかりたす。 /mnt/src/ex/READ_ME を芋るず、冒頭に次のような行がありたす。

There are 2 skeletal makefiles: makefile.v6 which I made from
the local makefile.CORY, and makefile.v7 which I made from makefile.VAX.

これを芋るず「makefile.v7 は VAX 甚なので、 makefile.v6 を䜿った方が良いのかな」ずいう 気持ちになっちゃうのですが、さにあらず。私が詊みたずころでは csh の時ずは違っお、ex の堎合は makefile.v7 を修正しお䜿うのが 正解のようです。

ex をコンパむルする䞊での問題点ずしおは぀ありたす。 ぀は C Shell ず共通の問題で printf の内郚䞋䜍関数 _strout() の 匕数の䞊びが Version 7 Unix ず UNIX/32V で異なるこず。぀たり、 C Shell ず同様に ex でも自前の printf を䜿っおいるっおこずですね。 これの察凊法も同じで printf.c の代わりに 11printf.c を䜿いたす。 もう぀の問題は ex_io.c です。この C ゜ヌスは倧き過ぎるため、 コンパむル時に゚ラヌ "Symbol table overflow" が発生したす。 この゚ラヌはコンパむラの問題なので、本来はコンパむラの方を 手盎しするべきなのですが(★コラム、★コラム参照) 、 コンパむラを修正するのは倧倉危険なので「ex_io.c を半分にぶった切る」 ずいう荒技で乗り切るこずにしたした。実行䟋を埡芧ください。

実行䟋 ex のコンパむルむンストヌル

# cd /mnt/src/ex
# cp makefile makefile.v7
# diff -e makefile.v7 makefile
58,61c
        ${CC} -c xs.c
        mv xs.o strings.o
.
43c
        11printf.o strings.o
.
40c
        ex_io0.o ex_io1.o ex_put.o ex_re.o ex_set.o ex_subr.o ex_temp.o ex_tty.o \
.
# cp ex_io.c ex_io0.c
# ed ex_io0.c

    ....

# diff -e ex_io.c ex_io0.c
501,1000d
20,24d
# cp ex_io.c ex_io1.c
# ed ex_io1.c

    ....

# diff -e ex_io.c ex_io1.c
24,501d
16,19d
#
# make
/usr/ucb/mkstr - ex2.0strings x ex.c
cc -E -O -DTABS=8 -DLISP -DCHDIR -DUCVISUAL xex.c | /usr/ucb/xstr -c -
rm -f xex.c
cc -O -DTABS=8 -DLISP -DCHDIR -DUCVISUAL -c x.c
mv x.o ex.o

    ....

# make install
/usr/ucb/ctags ex.c ex_*.c
cc -i ex.o ex_addr.o ex_cmds.o ex_cmds2.o ex_cmdsub.o ex_data.o ex_get.o  ex_io0.o ex_io1.o ex_put.o ex_re.o ex_set.o ex_subr.o ex_temp.o ex_tty.o  ex_v.o ex_vadj.o ex_vget.o ex_vmain.o ex_voperate.o  ex_vops.o ex_vops2.o ex_vops3.o ex_vput.o ex_vwind.o  11printf.o strings.o -ltermlib
chmod 711 /usr/ucb/ex
/usr/ucb/ex </dev/null
rm /usr/ucb/ex /usr/ucb/e /usr/bin/ex /usr/ucb/edit /usr/ucb/vi
rm: /usr/bin/ex nonexistent
rm: /usr/ucb/vi nonexistent
*** Error code 2 (ignored)
cp a.out /usr/ucb/ex
cp ex2.0strings /usr/lib/ex2.0strings
cp ex2.0strings /lib/ex2.0strings
ln /usr/ucb/ex /usr/ucb/edit
ln /usr/ucb/ex /usr/ucb/e
ln /usr/ucb/ex /usr/bin/ex
ln /usr/ucb/ex /usr/ucb/vi
chmod 1711 /usr/ucb/ex
#

たず、デフォルトの makefile は Version 7 Unix (UNIX/32V) 甚なので、 makefile.v7 にコピヌを残しお makefile の方を修正したす。 修正点は箇所。前述の問題に察応した箇所ず strings.o を䜜成する ずころで VAX 甚の修正が入っおいるため、これを削陀したした。 続いお ex_io.c をぶった切っお ex_io0.c ず ex_io1.c を䜜成したす。 奜郜合なこずに単玔な行削陀だけで、奇麗に぀に分けるこずができたした。

そしお make ず make install を行いたす。泚意しお欲しいのは make install を実行する前にディレクトリ /usr/bin を䜜成するこずです。 makefile は /usr/ucb に ex をむンストヌルするず同時に /usr/bin にも ex のリンクを匵りたす。ディレクトリ /usr/bin がないず make install は 途䞭で異垞終了したすので、予めディレクトリを䜜っおおいおください。

以䞊で ex/vi のコンパむルむンストヌルは終りです。

画面衚瀺を決めるtermcap

ex 2.0 の特城ずいえば、端末デヌタベヌスずしお termcap が 初めお䜿われるようになったこずが䞊げられたす。今日、 termcap ず蚀えば、りィンドりシステムのタヌミナル ゚ミュレヌタを䜿う時ぐらいしかお䞖話になりたせんので、 若い皆さんにはあたり銎染みがないかも知れたせん。が、 私のようなオヌルドナヌザヌにずっお、termcap ずいえば Unix の 悪倢の぀に䞊げられるほど「厄介」ずの印象が匷いでしょう。 昔は劙なタヌミナルが倚かったですからねぇ。

ex の初出は 1BSD でしたが、その時には termcap の前身である ttycap が䜿われおいたした。リストを芋おもらうずわかるように なんだかパスワヌドファむル (/etc/passwd) みたいな印象ですね。 この ttycap を曎に改良したのが皆さんが良くご存知の termcap で、 サポヌトされたのは 2BSD からです。

リスト ttycap

l1|11/10:0:0:?
ca|adm3a|3a:0177440:0000332:li#24:co#80:cl=^z:ho=\036:nd=^l:up=^k:am:bs:ca
cl|adm3:0177440:0000332:li#24:co#80:cl=^z:am:bs
td|decwriter|dw2:0177444:0000332:co#132:bs:os:am
pd|dtc300s|diablo|dtc:0137446:0000330:if=/usr/lib/tset.dtc_tabs:co#132:\
hu=\EH:hd=\Eh:up=^z:bs:it:os:pt:pl du|dialup:0:0:
pg|gsi:0137446:0000330:is#1:co#132:hu=\EH:hd=\Eh:up=^z:bs:it:os:pt:pl
g0|gt40:0177444:0000332:li#30:co#72:bs:os
g2|gt42:0177444:0000332:li#40:co#72:bs:os
ch|hazeltine2000:0177440:0000332:bs:ca
lh|hp21mx:0:0:?
cH|hp2645|2645:0177440:0000332:li#24:co#80:cl=\E&a00c00Y\EJ:ho?:nd=\EC:up=\EA:\
am:bs:ca:it:ce=\Ek\ pt:al=\EL:dl=\EM:ce=\EK:cd=\EJ
gk|tek4014:0177444:0040332:co#120:li#56:bs:os:cl=\E^l:is=\E\:
ct|teleray:0177440:0000332:co#80:li#24:cl=^l:bs
ti|ti700|ti|ti733:0151440:0020332:co#80:bs:os
t3|teletype|tty|33|35:0157440:0020336:co#72
t7|tty37|37:0:0:bs:os:hu?:hd?:up?
un|unknown|u:0:0:

2BSD に収録されおいる termcap のサンプルに登録されおいる ゚ントリ数 (サポヌトしおいる端末数) はたった 48 皮類です。 オヌルドナヌザヌの私がその䞭に曞かれおいる個々の端末名を芋おも 「党く知らない」あるいは「名前は聞いたこずがある」ものばかりです。 必然的に私たちの環境に合わせお新しい゚ントリを蚘述する必芁がありたす。

termcap の゚ントリを远加する

読者の倚くの方々は X Window System が動䜜する Unix 環境を お䜿いでしょうから、今回は xterm や kterm あるいは デスクトップ環境の暙準タヌミナル゚ミュレヌタを想定しお解説したす。

2BSD の termcap は珟圚のものず基本的に倉わりたせん。 しかし★衚を芋おもらうずわかるように、 定矩されおいた capabilities の数は個ず 珟圚のものずは比べものにならないほど少ないものでした。 (ちなみに、珟圚の termcap の man page で capability の数を数えおみたずころ 274 もありたした。 2BSD の termcap は文字通り ex/vi をサポヌトするだけのための 機胜しかなかったようです)

衚 2BSD termcap の capabilities (man page より抜粋)

Name Type Pad? Description
al str (P*) Add new blank line
am bool Terminal has automatic margins
bc str Back cursor if not `^H'
bs bool Terminal can backspace with `^H'
cd str (P*) Clear to end of display
ce str (P) Clear to end of line
cl str (P*) Clear screen
cm str (P) Cursor motion
co num Number of columns in a line
da bool Display may be retained above
db bool Display may be retained below
dc str (P*) Delete character
dl str (P*) Delete line
dm str Delete mode (enter)
ed str End delete mode
ei str End insert mode; give ``:ei=:'' if `ic'
eo str Can erase overstrikes with a blank
ho str Home cursor (if no `cm')
hz str Hazeltine; can't print ~'s
ic str (P) Insert character
if - Name of file containing `is'
im bool Insert mode (enter); give ``:im=:'' if `ic'
in bool Insert mode distinguishes nulls on display
ip str (P*) Insert pad after character inserted
is str Terminal initialization string
li num Number of lines on CRT screen
ll str Last line, first column (if no `cm')
ma str Control character map for arrow keys
mi bool Safe to move while in insert mode
nc bool No correctly working carriage return (DM2500)
nd str Non-destructive space (cursor right)
os bool Terminal overstrikes
pc str Pad character (rather than null)
se str End stand out mode
sf str (P) Scroll forwards
so str Begin stand out mode
sr str (P) Scroll reverse (backwards)
ta str (P) Tab (other than `^I' or with padding)
ul bool Terminal underlines even though it doesn't overstrike
up str Upline (cursor up)
vb str Visible bell (may not move cursor)
ve str Sequence to end open/visual mode
vs str Sequence to start open/visual mode
xn str A newline is ignored after a wrap (Concept)

termcap の capabilities は原則ずしお䞊䜍互換になっおいたすので、 珟圚䞀般に䜿われおいる termcap の劥圓な゚ントリから 2BSD termcap の capabilities だけを拟い集めるず必芁な゚ントリの情報が䜜成できたす。 今䜿っおらっしゃる Unix の /etc/termcap から xterm あるいは kterm の ゚ントリを芋぀ければよいのですが、「ファむルが圓おにならない」 あるいは「Windows で䜜業しおいる」のであれば、 Termcap/Terminfo Resources Page から termcap ファむルを取っおくるず良いでしょう。 念のため、私の䜜成した termcap ぞの远加゚ントリを リストに掲茉しおおきたす。

リスト termcap の远加゚ントリ

x0|xterm|:\
	:co#80:li#24:am:bs:mi:xn:\
	:al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:\
	:dc=\E[P:dl=\E[M:ei=\E[4l:ho=\E[H:im=\E[4h:\
	:is=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:\
	:nd=\E[C:se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:up=\E[A:

実際の゚ントリの远加䜜業は ed を䜿っお /etc/termcap を盎接修正したす。 (実行䟋)「これで ed を䜿うのも最埌」ず思えば倚少長い行入力も 苊にならないでしょう :-p

実行䟋 termcap ぞの゚ントリの远加

# cd /etc
# cp termcap termcap.orig
# ed termcap

    ....

# diff -e termcap.orig termcap
0a
x0|xterm|:\
        :co#80:li#24:am:bs:mi:xn:\
        :al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:\
        :dc=\E[P:dl=\E[M:ei=\E[4l:ho=\E[H:im=\E[4h:\
        :is=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>:\
        :nd=\E[C:se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:up=\E[A:
.
#

ちなみに xterm はミニコンのタヌミナルの代名詞であった VT100 (厳密には VT102) を゚ミュレヌトするタヌミナル゚ミュレヌタです。 ★コラムで VT100 に぀いお玹介しおおきたしたので、参考にしおください。

ex/vi の起動

さお、これで準備は党お敎いたした。詊しに ex/vi を起動しおみたしょう。 Unix ず SIMH を䞀旊止めお、xterm (kterm やその他の互換タヌミナル ゚ミュレヌタでも構いたせんが) から再起動したす。ここで泚意しお 欲しいのは、起動するタヌミナル゚ミュレヌタのりィンドりサむズを 80 文字× 24 文字にするずいうこずです。

ずいうのも、この圓時の ex/vi は衚瀺察象ずしおタヌミナルしか 想定しおいたせん。先に玹介した termcap の゚ントリ䟋では衚瀺画面が 80 文字× 24 文字 であるこずを仮定しおいたすし、実行䞭にその倧きさが 倉わっおも、それを認識しお衚瀺の倧きさを調敎するようなこずはできたせん。 xterm は特別の蚭定をしおいなければ、デフォルトで衚瀺画面を 80 文字× 24 文字 に蚭定しお起動したす。以降の操䜜でも りィンドりサむズを倉えないように泚意しおください。

xterm のりィンドりが開いたら、SIMH を立ち䞊げ Unix を再起動したす。 (実行䟋)

実行䟋 ex/vi を起動しおみる

$ pdp11

PDP-11 simulator V3.0-2
sim> set cpu URH70
sim> set cpu 2M
Disabling XQ
sim> set rp0 RP06
sim> att rp0 rp0.dsk
sim> set rp1 RP06
sim> att rp1 rp1.dsk
sim> boot rp0
boot
Boot
: hp(0,0)unix
mem = 2020544
# DATE 200403141245
SUN MAR 14 12:45:00 JST 2004
# <CNTL-D>
RESTRICTED RIGHTS: USE, DUPLICATION, OR DISCLOSURE
IS SUBJECT TO RESTRICTIONS STATED IN YOUR CONTRACT WITH
WESTERN ELECTRIC COMPANY, INC.
SUN MAR 14 12:45:16 JST 2004

login: root
Password:
You have mail.
#
# TERM=xterm
# export TERM
# PATH=$PATH:/usr/ucb
# export PATH
# printenv
HOME=/
PATH=:/bin:/usr/bin:/usr/ucb
TERM=xterm
#
# stty 9600
# tset
Erase set to control-H
#
# /etc/mount /dev/rp7 /mnt
# cd /mnt
#
# vi READ_ME

    ....

#

システムが起動したら取り敢えず root でログむンをしおください。 ex/vi を起動するためには少し蚭定が必芁です。たず環境倉数 TERM に termcap の゚ントリ名 xterm を蚭定したす。぀いでに環境倉数 PATH に /usr/ucb も远加しお BSD コマンドが䜿えるようにしおおきたしょう。 環境倉数の蚭定が終ったら printenv で蚭定内容の確認をしたす。 次に端末の蚭定を行いたす。たず回線速床の蚭定です。今回は SIMH の䞊で 動かしおいたすので、この蚭定は本質的に意味がないず思われるでしょうが、 実は ex/vi は回線速床をチェックしお、1200 baud 以䞋の堎合には 画面のした半分しか䜿わないようになりたす。そこで、ここでは 1200 より 倧きな倀を蚭定しおおきたしょう。次に tset コマンドを実行したす。 この BSD コマンドは termcap の゚ントリを参照しお、 その他の必芁な回線蚭定をしおくれたす。"Erase set to control-H" ず 衚瀺されおいたすが、これ以降文字削陀は # キヌではなく CNTL-H に なりたす。なお、この環境倉数ず回線に察する蚭定は、圓時はログむン時の 蚭定ずしお csh の .login や sh の .profile などに蚘述されるこずが 䞀般的でした。

それではたず vi から起動しおみたしょうか。䜕か適圓なファむルを 開いおみおください。皆さんよくご存知の vi ですから、その操䜜方法を ここで改めお説明するたでもないですよね、、、なんだかちょっずおかしい はい、実は 2BSD の ex/vi はカヌ゜ルを移動するコマンドのキヌバむンディングが 珟圚皆さんが良くご存知なものず違いたす。2BSD に付属する "Vi Quick Reference" を芋おいただくずわかるのですが、カヌ゜ルの行移動の堎合は CNTL-N ず CNTL-P (これは emacs のキヌバむンディングず同じですね)、 あるいは + ず - にバむンドされおいたす。そしおカヌ゜ルを文字右に 移動するには space を䜿いたす。皆さんが良くご存知の j, k, l キヌには 機胜がバむンドされおいないので、これらのキヌを抌すず beep がなるはずです。 これはちょっず驚きですね。

キヌバむンディングを远加する

これでは䜿いづらいので j, k, l キヌが䜿えるように手盎しをしたしょう。 そのためには ex/vi の゜ヌスを修正する必芁がありたす。実行䟋を埡芧ください。

実行䟋 j, k, l コマンドを远加する。

# cd /mnt/src/ex
# cp ex_voperate.c ex_voperate.c.orig
# ex ex_voperate.c
"ex_voperate.c" 834 lines, 14402 characters
:set number
:528
        case CTRL(n):
:a
   529          case 'j':
   530  .
:480
   480           */
:a
   481          case 'k':
   482  .
:397
   397           */
:a
   398          case 'l':
   399  .
:w
"ex_voperate.c" 837 lines, 14435 characters
:q
# diff -e ex_voperate.c.orig ex_voperate.c
528a
        case 'j':
.
480a
        case 'k':
.
397a
        case 'l':
.
# make clean

    ....

# make install

    ....

#

せっかくですから今回の修正には ex を䜿っおみたしょう。ex は ed の 䞊䜍互換ですので、党く同じコマンドを受け付けおくれたす。ed ではなく 敢えお ex を䜿う理由があるずすれば、それは䟋えば set number コマンドが 䞊げられるでしょう。set number コマンドを実行するず行衚瀺の際、 行番号も衚瀺しおくれるようになりたす。diff -e の出力など 行指向のファむル線集が必芁な堎合、この機胜は䟿利です。

ex_voperate.c の修正が終ったら、 実行䟋ず同じようにex/vi をむンストヌルをしお、 vi の動䜜を確かめおみたしょう。ほら j, k, l キヌが䜿えるように なりたしたね。

オヌプンモヌドを䜿っおみる

苊劎のかいあっお、ようやくオリゞナル ex/vi が出来䞊がりたした。 が、読者の皆さんの䞭には「これっおどんなありがた味があるの」ず感じおいる 方もいらっしゃるでしょう。確かに今日ではさたざたな vi クロヌンが存圚しおおり、 どれも非垞によく出来おいるので、「本物のvi が䜿える」ずいうこずだけでは 今䞀぀魅力が薄いかも知れたせん。 ですがこのオリゞナル ex/vi、ちたたの倚くの vi クロヌンでは サポヌトされおいないオヌプンモヌドが䜿えたす。第回で埡玹介した George Coulouris の em (Editor for Mortals) ゆずりのあのオヌプンモヌドです。 こればかりは「オリゞナルだけ」の機胜ですね :-p (「vi が動くなら 必芁ないゞャン」っお意芋もあるでしょうが)

オヌプンモヌドを䜿うためには、たず ex を起動したす。 コマンドプロンプトの ":" が返っおきたら、 小文字の "o" ず打っおください。これでオヌプンモヌドになりたす。 オヌプンモヌドでの珟圚行の線集操䜜は vi ず同じです。たた vi ず 同じ芁領で行移動もできたすが、カヌ゜ルが䞊䞋に動くこずはありたせん。 垞にコマンド行の行䞊に珟圚行が衚瀺されたす。オヌプンモヌドを 抜けるためには、小文字の "q" を打っおください。もずの ex に戻りたす。

ex のオヌプンモヌドの特城はタヌミナルの蚭定を必芁ずしないこずです。 䟋えば環境倉数 TERM が蚭定されおいない状態で vi を起動した堎合、 "[Using open mode]" ず衚瀺されお、自動的にオヌプンモヌドで 立ち䞊がりたす。カヌ゜ルが画面を䞊䞋に動かないこずを陀けば、 基本的な操䜜は vi ず倉わらないので案倖重宝したす。お詊しあれ。

※

以䞊、今回は 2BSD に収録されおいる ex/vi をビルドしおみたした。 いかがだったでしょうか 実は、その操䜜方法のためか、 Version 7 Unix には私も倧倉レトロな印象を持っおいたのですが、 䞍思議なもので vi が動き始めた途端、グッずモダンな印象に倉わりたした。 これならプログラムを曞く気にもなっおくるずいうものです。ずいうわけで、 次回は 2BSD を䜿った実習の最埌ずしお、1BSD/2BSD 最倧の目玉である Berkeley Pascal System に挑戊しおみようず思いたす・・・「で、 emacs はどうなるんですか」ず仰っおいるあなた。連茉はただ続きたす


★コラム Version 7 Unix でのスクリプトの実行

「あれなんで /bin/sh の問題なのカヌネルの問題じゃないの」ず 思った方もいるず思いたすが、、、今日のモダンな Unix では 実行パヌミションが蚭定されおいる (実行可胜な) スクリプトは カヌネルの exec システムコヌルに察応するルヌチンのなかで 先頭の行を解釈しお、そのスクリプトを受け付けるプログラムを 決定する実装が䞀般的です。実際、この機胜があるので、モダンな Unix では perl などのさたざたなむンタヌプリタのスクリプトをコマンドのように 取り扱うこずができるのですが、Version 7 Unix ではこの機胜は 実装されおいたせん。したがっお、実行可胜なシェルスクリプトを 指定しお exec システムコヌルを呌び出した堎合、゚ラヌが発生し ゚ラヌコヌド ENOEXEC (Exec format error) が返っおきたす。

「じゃ、誰がスクリプトを実行しおいるの」ずいうこずになりたすが、 答えは /bin/sh 自身です。/bin/sh は execve システムコヌルを 呌び出しお ENOEXEC が返っおきた堎合、実行察象ずなるファむルを シェルスクリプトず仮定しお、そのファむルを入力ずしお実行するこずを 詊みたす。(゜ヌスコヌド /usr/src/cmd/sh/service.c の 140 行目あたりを 埡芧ください) 本文で指摘しおいるコメントの問題はこの埌の subshell に longjump した埌で発生しおいるわけですが、このように Version 7 Unix の シェルスクリプト機胜は、非垞に /bin/sh に䟝存する圢で実装されおいたした。 今日のモダンな Unix で䞀般化されおいる前述の実装方法は、埌に BSD Unix で 採甚されたアプロヌチです。

★コラム Bourne Shell の環境倉数の蚭定

/bin/sh が実際には bash であるこずが倚い今日、 環境倉数の蚭定が煩わしいず考える人はあたりいないでしょう。 実際

$ export TERM=vt100
$

の行で蚭定ができるからです。 でもこの機胜、実は bash の独自機胜なんですね。 オヌルドナヌザヌの方は良くご存知だず思いたすが、 オリゞナルの Bourne Shell では、環境倉数を蚭定する際、 たずシェル倉数を蚭定しお、その内容を環境倉数に export するずいう 段階の手順を必芁ずしたした。䟋えばこんな感じ。

$ TERM=vt100
$ export TERM
$

Bourne Shell の export コマンドでは倉数の倀を蚭定するこずはできたせん。 おそらくシェル倉数の内容ず環境倉数を垞時䞀臎させるこずを狙っお こういう仕様にしおいたのだず掚枬されたすが、その理由は定かではありたせん。 ずはいえこの手順、頻繁にトラブルの原因になりたした。 環境倉数を蚭定した぀もりがシェル倉数しか蚭定しおなかったずか、、、 C Shell のようにシェル倉数ず環境倉数を独立しお蚭定できる仕様の方が 合理的だず私は思うのですけども。

★コラム Version 7 Unix での setenv()

今日 setenv() は libc のラむブラリ関数になっおいたす。 が、Version 7 Unix の libc では getenv() は存圚したすが、 setenv() は存圚したせん。「じゃぁ、環境倉数はどうやっお 蚭定するの」ずいう疑問は圓然でしょう。オリゞナルの Version 7 Unix では環境倉数を蚭定しおいるのは /bin/login ず /bin/sh の぀のプログラムだけで、各々自前で環境倉数の領域 environ を盎接参照しお倀を蚭定しおいたした。぀たりこの圓時、 䞀般的な Unix プログラムは環境倉数を参照するだけだったずいうわけです。

今日、私たちが知るラむブラリ関数 setenv() の仕様は C Shell の 同名の内郚関数がベヌスになったようです。䞭身は、、、C Shell の ゜ヌスを芋おくださいね。sh.func.c の最埌の方です。

★コラム Ritchie C Compiler ぞのパッチ

実は ex のコンパむル方法を探す過皋で makefile.v6 も詊しおみたした。 が、こちらでも "Symbol table overflow" が発生したした。 で、2BSD のディストリビュヌションの䞭にこの問題ぞの察凊方法を 蚘述したものがないかず探したずころ /mnt/upgrade/c に overflow に 察凊するパッチが存圚したした。このディレクトリにある c0.h および c11.c はは /usr/src/cmd/c の䞋にある Ritchie C Compiler ぞの パッチのようでした。

で、パッチを圓おるこずを詊みたのですが、、、うたくいきたせん。 どうやら元の゜ヌスが違うようです。぀たり UCB で䜿われおいた Ritchie C Compiler は Version 7 Unix に収録されおいたものずは 異なるようです。たさかずは思ったのですが、念のため Version 6 Unix に 収録されおいる Ritchie C Compiler ぞのパッチも詊みたした。が、これもダメ。 で、「䞀䜓、UCB で䜿われおいた Ritchie C Compiler っお どのバヌゞョン」ずたたもや頭を抱えるこずになりたした。

数日ゞタバタした結果、芋぀けた答えは、、、このパッチ、なんず Programmers Work Bench (正確にはおそらく PWB-2.0 ★コラム参照) に 収録されおいた Ritchie C Compiler に察するパッチだったようです。 党く Reject されるこずなくパッチはピッタリ圓たりたした。 そこでこのパッチを圓おた埌の゜ヌスを Version 7 Unix を持っおいっお コンパむルしようずしたのですが、、、党くコンパむルできたせん。 Version 7 Unix に収録されおいる Ritchie C Compiler ず diff を 取っおみるず、、、PWB は Version 6 Unix 仕様のシステムなので その䞊で動く Ritchie C Compiler も Version 6 Unix 仕様なんですね。 で、Version 7 Unix ずは (システムコヌルなど) システム仕様が倧きく 異なるためコンパむルできなかったずいうわけです。さすがに Version 7 Unix の仕様に合わせるよう改造するだけの時間も劎力もなかったので、 ここでコンパむラを手盎しするずいう方策は断念せざるえなくなりたした。

★コラム Programmer's Workbench (PWB)

前回、Mashey Shell の玹介のずころで觊れた Programmer's Workbench (PWB) ですが、 予想に反しお重芁な圹割を果たしたリリヌスであったこずがわかっおきたした。 ここで、もう少し詳しく觊れおおきたしょう。

前回でも埡玹介したように、PWB は倧芏暡゜フトりェア開発のための システムずしお開発プロゞェクトが始たったず説明したしたが、 実際には AT&T の Business Information Systems (BIS) プロゞェクトが 抱える問題を解決するこずが目的だったようです。その問題ずは、 圓時の倧型コンピュヌタが抱えおいた非互換性の問題でした。 圓時 BIS は IBM、UNIVAC(珟UNISYS)、XEROX など異なるメヌカヌが提䟛する、 盞互に互換性のない皮類以䞊のアヌキテクチュアの䞊で動く゜フトりェアを 開発する必芁がありたした。第回で埡玹介したように、圓時のこの手の 倧型コンピュヌタは䜿甚した CPU 時間にチャヌゞされる仕組みで、 実機での開発は倧倉お金がかかりたした。曎にあたりにもアヌキテクチュアが 異なるため、(゜ヌスコヌドなど)開発した成果を統䞀的に管理する手段も ありたせんでした。で、この問題を解決するために Unix を掻甚しようずいうのが PWB プロゞェクトの目論芋だったわけです。

この PWB プロゞェクトの䞭心人物は前回も埡玹介した Rudd Canaday です。 この人は第回、第回で埡玹介した Ken Thompson のチョヌクファむル システムの開発も手䌝った Unix 開発のオリゞナルメンバヌの䞀人です。 1973 幎 Version 3 Unix (および Version 4 Unix) が発衚された頃に、 Unix システムそのものの開発から離れお、この PWB プロゞェクトを始めた ずのこずです。

このプロゞェクトの最倧の特城はその開発方針にありたした。よくありがちな、 総論的芋地に立っお統合的なシステムずしおワヌクベンチを蚭蚈するアプロヌチ、 すなわちトップダりン型のアプロヌチは最初から陀倖され、BIS の開発芁員の 抱えおいる具䜓的な問題を解決するツヌルを Unix の䞊に぀ず぀実装しお いくずいう、いわゆるボトムアップ型のアプロヌチを採甚しおいたした。 故に PWB/UNIX はシステムずしおは Unix そのものであり、前回も埡玹介した RJE や SCCS ずいった著名な PWB プロゞェクトの成果は、埌に Unix 䞊の ナニヌクな゜フトりェア開発ツヌルずしお生き残っおいくこずになりたした。

Version 4 Unix をベヌスにしたオリゞナルの PWB/UNIX ず呌ばれるシステムは 1974 幎にリリヌスされおいたすが、その埌は Version 6 Unix をベヌスにした PWB 1.0 が 1977 幎に、PWB 2.0 が 1978 幎にリリヌスされおいたす。Unix の 歎史ずいう芳点でもこれらのリリヌスは重芁で、䟋えば★コラムで述べた Ritchie C Compiler のアップデヌト版などが随時収録されおいたした。1977 幎、 1978 幎ずいえば第回で埡玹介したように Unix 自䜓は Version 7 の開発時期に 圓たり、ポヌタビリティを達成するための開発䜜業に集䞭しおいた時期です。 実際、Version 6 がリリヌスされおから Version 7 がリリヌスされるたでは 幎半から幎ずいう長い期間がありたすが、PWB は結果的にこの長いリリヌス の空癜期間を埋める圹割も果たしたこずになりたす。これは Version 7 で 収録された Unix の代衚するような make や lex ずいうツヌルが、 実は初出は PWB だったずいう事実からも確認できたす。

PWB は 2.0 を最埌にその埌 PWB リリヌスは䜜られおいないようです。 おそらく AT&T が Unix ビゞネスを開始するこずになり、その成果が Unix の䞀郚ずしお取り蟌たれたからだず思われたす。

珟圚、PWB は Ancient Unix の䞀郚ずしお無料で゜ヌスコヌドを 入手するこずができたす。䟋によっお The Unix Heritage Society の Unix Archive から入手するのが䞀番お手軜でしょう。ちなみに、 Unix Archive ぞの PWB の゜ヌスの提䟛者の人である Keith Bostic は UCB CSRG の最埌の人のメンバヌのうちの䞀人です。ずいうこずは、 UCB は PWB のコヌドを入手しおいたずいうこずになりたすね。 これが「䜕故 2BSD に PWB 2.0 の Ritchie C Compiler に察する パッチが収録されおいたのか」の答でしょう。

远蚘: 単行本では第章で PWB を玹介しおいたす。

★コラム VT100

私の䞖代では「コンピュヌタのタヌミナル」ずいうず、 たず DEC の VT100 を思い出したす。りィンドりシステム党盛の昚今、 「タヌミナル」ずいう甚語自䜓が死語のようになっおいたすが、 それでも VT100 の圱響からは免れたせん。xterm や kterm など X Window System の䞊で動䜜するタヌミナル゚ミュレヌタは数々 存圚したすが、これらのプログラムが゚ミュレヌトしおいる タヌミナルずいうのは、実は VT100 (正確に VT102) です。 私たちは知らず知らずのうちに VT100 のお䞖話になっおいるんですね。

DEC の VT100 は 1978 幎に発衚されたした。以降、ASCII CODE ベヌスの タヌミナルのデファクトスタンダヌドずしお広く認知され続けおいたす。 1980 幎代に補品化された倚くのタヌミナル補品は VT100 互換を 唱っおいたしたし、パ゜コン䞊で動䜜するタヌミナル゚ミュレヌタでも VT100 の ゚スケヌプシヌケンスをサポヌトするのは基本ず理解されおきたした。 VT100 がこのような倧きな圱響力を持ったのには、もちろん圓時の ミニコン業界の芇者であった DEC の補品であったずいうこずも䞊げられたすが、 もっずも重芁な理由は他にありたす。VT100 は ANSI 互換のタヌミナルの 最初の補品だったのです。

DEC が VT100 を発衚した翌幎の 1979 幎、アメリカの暙準化団䜓である ANSI は X3.64 "Additional Controls for Use with American National Standard Code for Information Interchange" を暙準化したした。DEC は この暙準化䜜業を暪目で芋ながら、䞊行しお補品開発を行いたしたが、 この補品が VT100 ずなりたした。今日でも暙準化䜜業ず䞊行しお 補品開発が行われるこずはありたすが、圓時はもっず極端な状況で 特定のメヌカヌが開発した補品が、最初から暙準に適合しおいる ずいうようなこずが結構ありたした。 しかし圓時圱響力を持っおいた DEC ずいえども、自瀟補品をここたで 圱響力のあるデファクトスタンダヌドに抌し䞊げる力はなかったでしょう。 珟圚の VT100 の地䜍を䜜ったのは ANSI X3.64 のおかげです。

この暙準仕様は䞻に゚ラヌが発生した埌の埩旧などに぀いお、 仕様䞊の未定矩などがありたした。それ故 ANSI X3.64 の仕様に 基づいおタヌミナルを開発しおも、補品ずしお問題が残っおしたうのです。 DEC は ANSI X3.64 を遵守し぀぀も、問題の郚分に぀いおは独自の方法で 回避するようにしお VT100 を開発したした。のちに、埌発の ANSI 互換 タヌミナルを開発しおいるメヌカヌも同様の問題にぶ぀かるのですが、 結局既に補品化されおいる VT100 を参考にしお問題を回避したのでした。 こういった事情から VT100 は ANSI X3.64 のリファレンスの圹割を 果たしただけではなく、独自の問題回避方法も提瀺した栌奜になり、 それをも含めた VT100 互換のタヌミナルが業界に定着したわけです。

ここで「埌発メヌカヌが VT100 互換のタヌミナルを䜜っお商売になったの」 ず疑問を持たれる方もいらっしゃるでしょう。実は十分に商売になったんですね。 䟋えば、か぀お私が VAX のシステム管理者をしおいた頃、開発甚には台の タヌミナルが接続されおいたしたが、そのうち玔正の VT100 は台だけで 残る台は党郚 VT100 互換の他瀟補品が接続されおいたした。 それぐらい VT100 は倀段の高いタヌミナルだったんですね。

埌に DEC も VT100 の廉䟡版を補品化したす。VT100 ではオプション扱いに なっおいたプリンタヌポヌト(画面のハヌドコピヌを取るために䜿いたす)を 暙準装備にしお少し倀段を䞋げた VT102 ず、これらのオプションを 党郚削っおグッず倀段を䞋げた VT101 の皮類が補品化されたした。 xterm などはこの VT102 で远加された䞀郚の゚スケヌプシヌケンスも サポヌトしおいるため「VT102 互換のタヌミナル゚ミュレヌタ」ず 呌ばれおいたす。

なお VT100 に関する技術情報を調べるためには VT100.net ずいうホヌムペヌゞが䟿利です。DEC が発行した 技術資料もきれいに敎備されお掲茉されおいたすので、 䞀床埡芧になっおはいかがでしょうか。