Unixの歴史を再現したリポジトリを読む③

Git for WindowsでV3をcheckoutできない問題に遭遇。どうやら同名で大文字と小文字が異なるファイルが同一ディレクトリ内に混ざっているようです。

止むを得ずWSL2にgitをインストールしてリポジトリのクローンから仕切り直しました。WSL2経由でgitを操作すれば、ファイルはNTFSのドライブに置いても大丈夫なようです。またこれをWindowsのGitクライアントから見ることも基本的にできます。ただしWindows版gitでアクセスできないコミットは、当然Windowsからは読めません。

Windows NTのファイルシステムはファイルの大文字と小文字を区別していますが、過去の互換性を保つため、表面上は区別しないようになっています。ちなみにドライブレターも互換性のためにあるもので、ディスクをマウントするのにドライブレターは不要です。適当なディレクトリにパーティションをマウントすることもできます。

# V3

## コミット
V3のタイムスタンプは1973年2月。おかしなことに、このコミットにはカーネルがありません。つまりUNIXが入っていません。代わりにCコンパイラとmanが入っています。V3のUNIXはコードが残っておらず、Cコンパイラとmanのアーカイブだけが発掘された、ということなのでしょうか。

V2まではケン・トンプソンとデニス・リッチーのコミットだけしかありませんでしたが、V3ではYaccを書いたスティーヴン・カーティス・ジョンソン、Lexを書いたマイク・レスク、パイプを発明したダグラス・マキルロイの他、ロバート・モリス、ジョー・オサンナ、ロリンダ・チェリー、C.S.ロバートなどの名前がコミッターに入っています。

``` bash
uiweo@DESKTOP-HP:/mnt/d/Users/uiweo/Documents/unix-history-repo$ git log
commit 05f7221367e283f771ec583ed3494c52e8766d2f
Author: Ken Thompson <ken@research.uucp>
Date:   Thu Feb 15 15:47:21 1973 -0500

    Research V3 development
    Work on file man/man0/index

    Co-Authored-By: Dennis Ritchie <dmr@research.uucp>
    Synthesized-from: v3

commit f3527a5255d75fa00cd8bb8521cd7245a2f7c77d
Author: Stephen C. Johnson <scj@research.uucp>
Date:   Thu Feb 15 14:41:41 1973 -0500

    Research V3 development
    Work on file man/man6/yacc.6

    Synthesized-from: v3

commit 949b3a278a3535526000fa55d465ad936e246884
Author: Ken Thompson <ken@research.uucp>
Date:   Thu Feb 15 14:09:17 1973 -0500

    Research V3 development
    Work on file man/man5/utmp.5

    Co-Authored-By: Dennis Ritchie <dmr@research.uucp>
    Synthesized-from: v3
```

V1からV3に至るまでのコミットは、各ファイルの差分という形ではなく、1コミット1ファイルで追加する形になっており、gitで履歴が再現されているとは言い難いです。V3のコミットを1コミットにsquashしても意味的に変わりません。単にコミッターに貢献者たちの名前を入れたいので、このようなスタイルにしたものと思われます。

J.C.ロバートはファーストネームが分かりません。検索したところ、一部のUNIXの論文にJ.C.ロバートの名前が載っており、リポジトリ再現プロジェクトの人もそこから名前を拝借したのかもしれません。

## Cコンパイラ
cディレクトリの中を見ると、相変わらずデニス・リッチーがハードコーディングしたCコンパイラが入っていました。またファイル数が大幅に減っており、コンパイラとしてビルド可能であるような状態には見えません。再現リポジトリではV2の次のコミットで全ファイルを削除してから、V3のファイルを1つ1つコミットするというスタイルになっています。V3のバックアップに入っていなかったファイルはV2からマージされずに消える形をあえて取っているのだろうと思われます。

``` c:c00.c
main(argc, argv)
int argv[]; {
	extern extdef, eof;
	extern fout, fin, nerror, tmpfil, xdflg;

	if(argc<4) {
		error("Arg count");
		exit(1);
	}
	if((fin=open(argv[1],0))<0) {
		error("Can't find %s", argv[1]);
		exit(1);
	}
	if((fout=creat(argv[2], 017))<0) {
		error("Can't create %s", argv[2]);
		exit(1);
	}
	tmpfil = argv[3];
	xdflg++;
	init("int", 0);
	init("char", 1);
	init("float", 2);
	init("double", 3);
	init("struct", 4);
	init("auto", 5);
	init("extern", 6);
	init("static", 7);
	init("goto", 10);
	init("return", 11);
	init("if", 12);
	init("while", 13);
	init("else", 14);
	init("switch", 15);
	init("case", 16);
	init("break", 17);
	init("continue", 18);
	init("do", 19);
	init("default", 20);
	xdflg = 0;
	while(!eof) {
		extdef();
		blkend();
	}
	flush();
	flshw();
	exit(nerror!=0);
}
```

ソースを見ると、V2にはコメントの形で入っていたlongが消えて、代わりにstructが入っています。ここで構造体が追加されたようです。

ぐちゃぐちゃだったn1ディレクトリのコンパイラは消えました。

## man

``` :index
          20boot(VIII): reboot  11/20 system
                            tm  9-track magtape
                                :(I): place label
                                a.out(V): assembler and loader output
              chmod(I): change  access mode of files
           crypt(III): encrypt  according to a keyword
                   getty(VII):  adapt to typewriter
              chk(VIII): check  all file systems
          salloc(III): storage  allocator
            dup(II): duplicate  an open file
                 yacc(VI): yet  another compiler-compiler
         mail(I): send mail to  another user
                   archive(V):  archive file
                                archive(V): archive file
                    atan(III):  arctangent
                    glob(VII):  argument expander
        echo(I): print command  arguments
                                ar(I): archive (combine) files
                 sort(I): sort  ASCII file
            atof(III): convert  ASCII to floating
            atoi(III): convert  ASCII to integer
                                ascii(VII): map of ASCII
            ascii(VII): map of  ASCII
   ctime(III): convert time to  ASCII
           convert floating to  ASCII...ftoa(III):
 itoa(III): convert integer to  ASCII
                                as(I): assembler
                        as(I):  assembler
               bc(VI): compile  B program
                       bas(I):  BASIC dialect
                                bc(VI): compile B program
                       bj(VI):  blackjack
                       cdb(I):  C debugger
                cc(I): compile  C program
                   dc(I): desk  calculator
                     chmod(I):  change access mode of files
                    chmod(II):  change mode of file
                     chown(I):  change owner of files
                    chown(II):  change owner of file
                     chdir(I):  change working directory
                    chdir(II):  change working directory
  pipe(II): open inter process  channel
                getc(III): get  character
                                chdir(I): change working directory
                                chdir(II): change working directory
                    chk(VIII):  check all file systems
                    close(II):  close open file
                                close(II): close open file
                                clri(VIII): clear file's i-node
                                cmp(I): compare file contents
                  exit(I): end  command sequence
                      goto(I):  command transfer
            if(I): conditional  command
                       cmp(I):  compare file contents
                        fc(I):  compile Fortran program
                       sno(I):  compile Snobol program
                       tmg(I):  compile tmgl program
         yacc(VI): yet another  compiler-compiler
                       cat(I):  concatenate (or print) files
                   ls(I): list  contents of directory
                   makdir(II):  create directory
                     mkdir(I):  create directory
                    creat(II):  create file
                     fork(II):  create new process
                                creat(II): create file
                                cref(I): cross reference table
                     cdb(I): C  debugger
               db(I): symbolic  debugger
                     kill(II):  destroy process
                                df(I): find free disk space
                   ed(I): text  editor
                     exec(II):  execute program file
          check consistency of  file system...check(VIII):
             link(II): link to  file
```

manのインデックスの抜粋。(II)などの表記は、バージョン2のコマンドであることを表していると思われますので、VIIIという表記があるということは、VIIIのコマンドまで混入していのでしょうか? もしそうであれば、IVからB言語のコンパイルに対応しているというのも変な感じです。このあたりUNIX界隈の方には常識なのでしょうかね?

目を引くのはatof、atoi、itoaなどのC言語の関数がそのままコマンドになっているところです。yaccも見られます。lkはリンカではなく、ファイルのシンボリックリンクを作るコマンドです。

# で
結局このV3のコミットには事実上manしかなく、大きな収穫はありませんでした。

すでにV4の探索を始めていますが、V1やV2で色々な見落としがあったことがわかったので、改めてV1とV2を見直してバックナンバーをかなり書き換えました。これに時間を取られてしまいV4の探索は遅れています。

# バックナンバー
[Unixの歴史を再現したリポジトリを読む①] (https://qiita.com/hayashida-katsutoshi/items/37afd9acbce117aa223c)
[Unixの歴史を再現したリポジトリを読む②] (https://qiita.com/hayashida-katsutoshi/items/3c4bc05ab4c627286be8)
[Unixの歴史を再現したリポジトリを読む③] (https://qiita.com/hayashida-katsutoshi/items/eb80ebd5667af10193f5)
[Unixの歴史を再現したリポジトリを読む④] (https://qiita.com/hayashida-katsutoshi/items/5edde08b01b81dac26b7)
[Unixの歴史を再現したリポジトリを読む⑤] (https://qiita.com/hayashida-katsutoshi/items/df9c08c4c5011f04b45e)