Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 1871] ファイルの概要

このコミットは、Go言語の初期開発段階におけるシステムコール互換性レイヤーの整理に関するものです。具体的には、compat.hで提供されていたカスタム互換性レイヤーの大部分を廃止し、lib9互換性レイヤーに一本化することで、コードベースの重複を削減し、よりクリーンな設計を目指しています。

コミット

commit 5a68303a15dadb6c5681f69f6e09a1ff0625883a
Author: Russ Cox <rsc@golang.org>
Date:   Tue Mar 24 12:12:57 2009 -0700

    throw away most of the compat.h compatibility layer
    in favor of the lib9 compatibility layer.  no need for two.
    
    now that mycreate is gone, .6 files are 0644 not 0755.
    
    TBR=r
    OCL=26679
    CL=26679

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/5a68303a15dadb6c5681f69f6e09a1ff0625883a

元コミット内容

compat.h互換性レイヤーの大部分を破棄し、lib9互換性レイヤーに一本化する。2つのレイヤーは不要である。 mycreateがなくなったため、.6ファイルは0755ではなく0644となる。

変更の背景

Go言語は、その設計思想においてPlan 9オペレーティングシステムの影響を強く受けています。初期のGoコンパイラやツールチェーンは、Plan 9のCコンパイラやリンカのコードベースを基盤としていました。しかし、GoがUnix系システム(Linux, macOSなど)やWindowsでも動作するようにするためには、これらの異なるOSのシステムコールを抽象化し、Goのコードから一貫したインターフェースで利用できるようにする必要がありました。

このコミット以前は、compat.hというヘッダーファイルを通じて、UnixやWindowsといった異なるOS環境でのシステムコールをラップする独自の互換性レイヤーが存在していました。同時に、Plan 9のシステムコールを模倣したlib9という別の互換性レイヤーも存在していました。

Russ Cox氏のコミットメッセージにある「no need for two」という言葉が示すように、2つの異なる互換性レイヤーが存在することは、コードの重複、保守の複雑さ、そして潜在的なバグの原因となっていました。この変更の背景には、Goのツールチェーンがより成熟し、Plan 9の遺産とUnix/Windowsの現実との間で、より効率的かつ統一されたシステムコール抽象化の必要性が認識されたことがあります。lib9レイヤーがPlan 9の設計哲学をより直接的に反映しており、Goの設計思想と親和性が高かったため、こちらに一本化する判断がなされたと考えられます。

また、mycreate関数の削除により、作成されるファイルのパーミッションが0755(実行可能)から0644(読み書き可能、実行不可)に変更されたことは、ファイル作成のセマンティクスがより標準的なものに近づいたことを示唆しています。これは、Goのビルドプロセスが生成する中間ファイルや最終バイナリのパーミッション管理が、より意図的かつ安全になったことを意味します。

前提知識の解説

Plan 9 from Bell Labs

Plan 9は、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、その設計哲学は「すべてをファイルとして扱う」という点に集約されます。デバイス、プロセス、ネットワーク接続など、システム内のあらゆるリソースがファイルシステム上のファイルとして表現され、標準的なファイル操作(読み書き、オープン、クローズなど)を通じてアクセスされます。この統一されたインターフェースは、システム設計を大幅に簡素化し、分散システムでのリソース共有を容易にしました。

Go言語の設計者の一部はPlan 9の開発にも携わっており、Goの設計にはPlan 9の思想が色濃く反映されています。例えば、Goのio.Readerio.Writerインターフェースは、Plan 9のファイルI/Oモデルに似ています。

lib9互換性レイヤー

lib9は、Plan 9のシステムコールやライブラリ関数を、Unix系システムなどの他のOS上でエミュレートするための互換性レイヤーです。これにより、Plan 9向けに書かれたコードを、比較的容易に他のOSに移植することが可能になります。Goの初期のツールチェーンがPlan 9のコードベースから派生したため、GoのコンパイラやリンカがPlan 9スタイルのシステムコールを利用できるように、lib9がGoのビルドシステムに組み込まれていました。

lib9は、fork(), wait(), create(), open(), read(), write(), seek(), exec(), pipe(), dup(), getwd(), access(), exit()といった基本的なシステムコールを、Plan 9のセマンティクスに合わせて提供します。これらの関数は、UnixやWindowsの同名のシステムコールとは異なる挙動を持つ場合があり、lib9はその差異を吸収する役割を担っていました。

compat.h互換性レイヤー

compat.hは、このコミットで廃止されたもう一つの互換性レイヤーです。lib9がPlan 9のセマンティクスを重視していたのに対し、compat.hはより一般的なUnix/Windows互換性を目的としていた可能性があります。例えば、myfork, mywait, mycreateのように、標準的なシステムコール名にmyプレフィックスを付けてラップすることで、特定のOS環境での差異を吸収しようとしていたと考えられます。

2つの互換性レイヤーが存在したことは、Goの初期開発における試行錯誤の過程を示しています。最終的に、Plan 9の設計思想とより親和性の高いlib9が選択され、compat.hは冗長と判断されました。

ファイルパーミッション 06440755

Unix系システムにおけるファイルパーミッションは、3桁の8進数で表現されます。各桁はそれぞれ「所有者」「グループ」「その他」の権限を示し、各数字は以下の合計で構成されます。

  • 4: 読み取り (read)

  • 2: 書き込み (write)

  • 1: 実行 (execute)

  • 0644:

    • 所有者: 6 (読み取り + 書き込み)
    • グループ: 4 (読み取りのみ)
    • その他: 4 (読み取りのみ) これは、一般的なデータファイルや設定ファイルに適用されるパーミッションで、所有者のみが変更でき、他のユーザーは読み取りのみ可能です。
  • 0755:

    • 所有者: 7 (読み取り + 書き込み + 実行)
    • グループ: 5 (読み取り + 実行)
    • その他: 5 (読み取り + 実行) これは、実行可能ファイルやスクリプト、ディレクトリに適用されるパーミッションで、所有者とグループ、その他のユーザーが実行可能です。

このコミットで.6ファイルのパーミッションが0755から0644に変更されたのは、mycreateが削除され、ファイル作成のセマンティクスが変更されたためです。.6ファイルはGoのビルドプロセスで生成される中間ファイル(おそらくアセンブリコードのオブジェクトファイルなど)であり、通常は直接実行されるものではないため、実行権限を付与する必要がなくなりました。これにより、セキュリティとファイルシステムの整合性が向上します。

技術的詳細

このコミットの主要な技術的変更は、Goのツールチェーン(特にアセンブラ5a, 6a, 8a、リンカ6l、Cコンパイラcc、Goコンパイラgc)が使用していたカスタムシステムコールラッパーを、lib9互換の標準的なシステムコールに置き換えることです。

具体的には、以下の関数が変更されています。

  • myfork() -> fork()
  • mywait() -> wait()
  • mycreate() -> create()
  • mygetwd() -> getwd()
  • myseek() -> seek()
  • myaccess() -> access()
  • mypipe() -> pipe()
  • mydup() -> dup()
  • myexec() -> exec()
  • myopen() -> open()
  • myexit() -> exit()

これらの変更は、src/cmd/cc/cc.hからcompat.hのインクルードを削除し、my*プレフィックスを持つ関数の宣言を削除することで実現されています。代わりに、lib9が提供する標準的なシステムコール関数が直接使用されるようになります。

また、src/cmd/cc/cc.hsrc/cmd/cc/lex.cには、systemtypepathchar関数の定義が追加されています。これらは、Goのツールチェーンが動作しているOSの種類(Plan9, Unix, Windows)を識別し、パス区切り文字(/または\)を決定するために使用されます。これは、lib9が提供するクロスプラットフォーム互換性の一部として、OS固有の挙動を抽象化するために重要です。

さらに、src/cmd/cc/lex.cには、allocallocnというメモリ割り当て関数の実装が追加されています。これらは、mallocreallocをラップし、メモリ割り当てが失敗した場合にエラーメッセージを出力してプログラムを終了させることで、より堅牢なメモリ管理を提供します。これは、GoのツールチェーンがPlan 9のC言語環境で開発された名残であり、Plan 9のCライブラリが提供するメモリ管理関数に合わせたものと考えられます。

この変更により、Goのツールチェーンは、より統一されたシステムコールインターフェースを使用するようになり、コードベースの複雑さが軽減されます。また、lib9に一本化することで、Plan 9の設計思想との整合性が保たれつつ、他のOSへの移植性も維持されます。

コアとなるコードの変更箇所

このコミットは複数のファイルにわたる変更ですが、特に重要な変更箇所は以下の通りです。

  1. src/cmd/5a/lex.c, src/cmd/6a/lex.c, src/cmd/8a/lex.c (アセンブラ)

    • myfork() -> fork()
    • mywait() -> wait()
    • mycreate() -> create() (パーミッションが0664に明示的に変更)
    • Waitmsg *w; の追加と、mywait(&status) の代わりに w = wait(); if(w == nil)if(w->msg[0]) を使用する変更。これはPlan 9のwaitシステムコールがWaitmsg構造体を返すセマンティクスに合わせたものです。
  2. src/cmd/6a/lex.c

    • systemtypepathchar関数の定義が追加。
  3. src/cmd/6l/asm.c (リンカ)

    • myseek() -> seek()
  4. src/cmd/cc/cc.h (Cコンパイラのヘッダー)

    • #include "compat.h" の削除。
    • mywait, mycreat, myaccess, mygetwd, myexec, mydup, myfork, mypipe, mysbrkといったmyプレフィックス付き関数の宣言の削除。
    • Plan9, Unix, Windowsenum定義と、pathchar, systemtype, alloc, allocnの宣言が追加。
  5. src/cmd/cc/lex.c (Cコンパイラの字句解析)

    • systemtypepathchar関数の定義が追加。
    • myfork() -> fork()
    • mywait() -> wait()
    • mycreate() -> create()
    • myaccess() -> access() (引数にAREADが追加)
    • mypipe() -> pipe()
    • mydup() -> dup()
    • myexec() -> exec()
    • mygetwd() -> getwd()
    • allocallocn関数の実装が追加。
  6. src/cmd/cc/macbody

    • myopen() -> open() (引数にOREADが追加)
  7. src/cmd/gc/go.h (Goコンパイラのヘッダー)

    • void myexit(int); の宣言が削除。
  8. src/cmd/gc/lex.c, src/cmd/gc/subr.c (Goコンパイラ)

    • mygetwd() -> getwd()
    • myexit() -> exit()

コアとなるコードの解説

このコミットの核心は、Goのツールチェーンが使用するシステムコールインターフェースを、カスタムのmy*関数群から、lib9互換の標準的な関数群へと移行した点にあります。

例えば、src/cmd/5a/lex.cの以下の変更を見てみましょう。

--- a/src/cmd/5a/lex.c
+++ b/src/cmd/5a/lex.c
@@ -86,16 +86,13 @@ main(int argc, char *argv[])
 		c = 0;
 		nout = 0;
 		for(;;) {
+			Waitmsg *w;
+
 			while(nout < nproc && argc > 0) {
-				i = myfork();
+				i = fork();
 				if(i < 0) {
-					i = mywait(&status);
-					if(i < 0)
-						errorexit();
-					if(status)
-						c++;
-					nout--;
-					continue;
+					fprint(2, "fork: %r\n");
+					errorexit();
 				}
 				if(i == 0) {
 					print("%s:\n", *argv);
@@ -107,13 +104,13 @@ main(int argc, char *argv[])
 				argc--;
 				argv++;
 			}
-			i = mywait(&status);
-			if(i < 0) {
+			w = wait();
+			if(w == nil) {
 				if(c)
 					errorexit();
 				exits(0);
 			}
-			if(status)
+			if(w->msg[0])
 				c++;
 			nout--;
 		}
@@ -160,7 +157,7 @@ assemble(char *file)\n 		}\n 	}\n 
-	of = mycreat(outfile, 0664);\n+	of = create(outfile, OWRITE, 0664);\
 	if(of < 0) {
 		yyerror("%ca: cannot create %s", thechar, outfile);
 		errorexit();
  • myfork()からfork(): myfork()は、おそらくOS間のforkシステムコールの差異を吸収するためのラッパーでしたが、これが直接fork()に置き換えられました。これは、lib9が提供するfork()が、Goのツールチェーンが必要とするセマンティクスを十分に満たしていることを示唆しています。
  • mywait()からwait()へ、そしてWaitmsgの導入: mywait(&status)は、子プロセスの終了ステータスをstatus変数に格納するUnixライクなインターフェースでした。しかし、Plan 9のwait()システムコールは、Waitmsgという構造体を返します。この構造体には、終了ステータスだけでなく、終了メッセージなどの詳細情報が含まれています。この変更は、GoのツールチェーンがPlan 9のwaitセマンティクスに準拠するように移行したことを明確に示しています。w->msg[0]で終了メッセージの有無をチェックしている点も、Plan 9のwaitの利用方法に合致しています。
  • mycreat()からcreate(): mycreat()もまた、ファイル作成のためのラッパーでしたが、create()に置き換えられました。create()はPlan 9のシステムコールであり、ファイル名とパーミッション(0664)に加えて、OWRITEというフラグを引数に取ります。これは、ファイルを開くモードを明示的に指定するPlan 9の慣習に従ったものです。

これらの変更は、Goのツールチェーンが、よりPlan 9のシステムコールインターフェースに密接に結合されるようになったことを意味します。これにより、compat.hのような中間的な抽象化レイヤーが不要になり、コードベースが簡素化され、Plan 9の設計思想との整合性が高まりました。

また、src/cmd/cc/cc.hからcompat.hのインクルードが削除されたことは、このコミットが単なる関数名の変更に留まらず、compat.hが提供していた互換性レイヤー全体をシステムから取り除いたことを示しています。

関連リンク

  • Plan 9 from Bell Labs: https://9p.io/plan9/
  • Go言語の歴史: Go言語の初期開発に関する公式ドキュメントやブログ記事には、Plan 9の影響について言及されているものがあります。

参考にした情報源リンク

  • Go言語の公式リポジトリのコミット履歴
  • Plan 9 from Bell Labsのドキュメント
  • Unix系システムコールに関する一般的なドキュメント
  • Go言語の初期開発に関する技術ブログや論文 (Web検索を通じて得られた情報)

[インデックス 1871] ファイルの概要

このコミットは、Go言語の初期開発段階におけるシステムコール互換性レイヤーの整理に関するものです。具体的には、compat.hで提供されていたカスタム互換性レイヤーの大部分を廃止し、lib9互換性レイヤーに一本化することで、コードベースの重複を削減し、よりクリーンな設計を目指しています。

コミット

commit 5a68303a15dadb6c5681f69f6e09a1ff0625883a
Author: Russ Cox <rsc@golang.org>
Date:   Tue Mar 24 12:12:57 2009 -0700

    throw away most of the compat.h compatibility layer
    in favor of the lib9 compatibility layer.  no need for two.
    
    now that mycreate is gone, .6 files are 0644 not 0755.
    
    TBR=r
    OCL=26679
    CL=26679

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/5a68303a15dadb6c5681f69f6e09a1ff0625883a

元コミット内容

compat.h互換性レイヤーの大部分を破棄し、lib9互換性レイヤーに一本化する。2つのレイヤーは不要である。 mycreateがなくなったため、.6ファイルは0755ではなく0644となる。

変更の背景

Go言語は、その設計思想においてPlan 9オペレーティングシステムの影響を強く受けています。初期のGoコンパイラやツールチェーンは、Plan 9のCコンパイラやリンカのコードベースを基盤としていました。しかし、GoがUnix系システム(Linux, macOSなど)やWindowsでも動作するようにするためには、これらの異なるOSのシステムコールを抽象化し、Goのコードから一貫したインターフェースで利用できるようにする必要がありました。

このコミット以前は、compat.hというヘッダーファイルを通じて、UnixやWindowsといった異なるOS環境でのシステムコールをラップする独自の互換性レイヤーが存在していました。同時に、Plan 9のシステムコールを模倣したlib9という別の互換性レイヤーも存在していました。

Russ Cox氏のコミットメッセージにある「no need for two」という言葉が示すように、2つの異なる互換性レイヤーが存在することは、コードの重複、保守の複雑さ、そして潜在的なバグの原因となっていました。この変更の背景には、Goのツールチェーンがより成熟し、Plan 9の遺産とUnix/Windowsの現実との間で、より効率的かつ統一されたシステムコール抽象化の必要性が認識されたことがあります。lib9レイヤーがPlan 9の設計哲学をより直接的に反映しており、Goの設計思想と親和性が高かったため、こちらに一本化する判断がなされたと考えられます。

また、mycreate関数の削除により、作成されるファイルのパーミッションが0755から0644に変更されたことは、ファイル作成のセマンティクスがより標準的なものに近づいたことを示唆しています。これは、Goのビルドプロセスが生成する中間ファイルや最終バイナリのパーミッション管理が、より意図的かつ安全になったことを意味します。

前提知識の解説

Plan 9 from Bell Labs

Plan 9は、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、その設計哲学は「すべてをファイルとして扱う」という点に集約されます。デバイス、プロセス、ネットワーク接続など、システム内のあらゆるリソースがファイルシステム上のファイルとして表現され、標準的なファイル操作(読み書き、オープン、クローズなど)を通じてアクセスされます。この統一されたインターフェースは、システム設計を大幅に簡素化し、分散システムでのリソース共有を容易にしました。

Go言語の設計者の一部はPlan 9の開発にも携わっており、Goの設計にはPlan 9の思想が色濃く反映されています。例えば、Goのio.Readerio.Writerインターフェースは、Plan 9のファイルI/Oモデルに似ています。

lib9互換性レイヤー

lib9は、Plan 9のシステムコールやライブラリ関数を、Unix系システムなどの他のOS上でエミュレートするための互換性レイヤーです。これにより、Plan 9向けに書かれたコードを、比較的容易に他のOSに移植することが可能になります。Goの初期のツールチェーンがPlan 9のコードベースから派生したため、GoのコンパイラやリンカがPlan 9スタイルのシステムコールを利用できるように、lib9がGoのビルドシステムに組み込まれていました。

lib9は、fork(), wait(), create(), open(), read(), write(), seek(), exec(), pipe(), dup(), getwd(), access(), exit()といった基本的なシステムコールを、Plan 9のセマンティクスに合わせて提供します。これらの関数は、UnixやWindowsの同名のシステムコールとは異なる挙動を持つ場合があり、lib9はその差異を吸収する役割を担っていました。

compat.h互換性レイヤー

compat.hは、このコミットで廃止されたもう一つの互換性レイヤーです。lib9がPlan 9のセマンティクスを重視していたのに対し、compat.hはより一般的なUnix/Windows互換性を目的としていた可能性があります。例えば、myfork, mywait, mycreateのように、標準的なシステムコール名にmyプレフィックスを付けてラップすることで、特定のOS環境での差異を吸収しようとしていたと考えられます。

2つの互換性レイヤーが存在したことは、Goの初期開発における試行錯誤の過程を示しています。最終的に、Plan 9の設計思想とより親和性の高いlib9が選択され、compat.hは冗長と判断されました。

ファイルパーミッション 06440755

Unix系システムにおけるファイルパーミッションは、3桁の8進数で表現されます。各桁はそれぞれ「所有者」「グループ」「その他」の権限を示し、各数字は以下の合計で構成されます。

  • 4: 読み取り (read)

  • 2: 書き込み (write)

  • 1: 実行 (execute)

  • 0644:

    • 所有者: 6 (読み取り + 書き込み)
    • グループ: 4 (読み取りのみ)
    • その他: 4 (読み取りのみ) これは、一般的なデータファイルや設定ファイルに適用されるパーミッションで、所有者のみが変更でき、他のユーザーは読み取りのみ可能です。
  • 0755:

    • 所有者: 7 (読み取り + 書き込み + 実行)
    • グループ: 5 (読み取り + 実行)
    • その他: 5 (読み取り + 実行) これは、実行可能ファイルやスクリプト、ディレクトリに適用されるパーミッションで、所有者とグループ、その他のユーザーが実行可能です。

このコミットで.6ファイルのパーミッションが0755から0644に変更されたのは、mycreateが削除され、ファイル作成のセマンティクスが変更されたためです。.6ファイルはGoのビルドプロセスで生成される中間ファイル(おそらくアセンブリコードのオブジェクトファイルなど)であり、通常は直接実行されるものではないため、実行権限を付与する必要がなくなりました。これにより、セキュリティとファイルシステムの整合性が向上します。

技術的詳細

このコミットの主要な技術的変更は、Goのツールチェーン(特にアセンブラ5a, 6a, 8a、リンカ6l、Cコンパイラcc、Goコンパイラgc)が使用していたカスタムシステムコールラッパーを、lib9互換の標準的なシステムコールに置き換えることです。

具体的には、以下の関数が変更されています。

  • myfork() -> fork()
  • mywait() -> wait()
  • mycreate() -> create()
  • mygetwd() -> getwd()
  • myseek() -> seek()
  • myaccess() -> access()
  • mypipe() -> pipe()
  • mydup() -> dup()
  • myexec() -> exec()
  • myopen() -> open()
  • myexit() -> exit()

これらの変更は、src/cmd/cc/cc.hからcompat.hのインクルードを削除し、my*プレフィックスを持つ関数の宣言を削除することで実現されています。代わりに、lib9が提供する標準的なシステムコール関数が直接使用されるようになります。

また、src/cmd/cc/cc.hsrc/cmd/cc/lex.cには、systemtypepathchar関数の定義が追加されています。これらは、Goのツールチェーンが動作しているOSの種類(Plan9, Unix, Windows)を識別し、パス区切り文字(/または\)を決定するために使用されます。これは、lib9が提供するクロスプラットフォーム互換性の一部として、OS固有の挙動を抽象化するために重要です。

さらに、src/cmd/cc/lex.cには、allocallocnというメモリ割り当て関数の実装が追加されています。これらは、mallocreallocをラップし、メモリ割り当てが失敗した場合にエラーメッセージを出力してプログラムを終了させることで、より堅牢なメモリ管理を提供します。これは、GoのツールチェーンがPlan 9のC言語環境で開発された名残であり、Plan 9のCライブラリが提供するメモリ管理関数に合わせたものと考えられます。

この変更により、Goのツールチェーンは、より統一されたシステムコールインターフェースを使用するようになり、コードベースの複雑さが軽減されます。また、lib9に一本化することで、Plan 9の設計思想との整合性が保たれつつ、他のOSへの移植性も維持されます。

コアとなるコードの変更箇所

このコミットは複数のファイルにわたる変更ですが、特に重要な変更箇所は以下の通りです。

  1. src/cmd/5a/lex.c, src/cmd/6a/lex.c, src/cmd/8a/lex.c (アセンブラ)

    • myfork() -> fork()
    • mywait() -> wait()
    • mycreate() -> create() (パーミッションが0664に明示的に変更)
    • Waitmsg *w; の追加と、mywait(&status) の代わりに w = wait(); if(w == nil)if(w->msg[0]) を使用する変更。これはPlan 9のwaitシステムコールがWaitmsg構造体を返すセマンティクスに合わせたものです。
  2. src/cmd/6a/lex.c

    • systemtypepathchar関数の定義が追加。
  3. src/cmd/6l/asm.c (リンカ)

    • myseek() -> seek()
  4. src/cmd/cc/cc.h (Cコンパイラのヘッダー)

    • #include "compat.h" の削除。
    • mywait, mycreat, myaccess, mygetwd, myexec, mydup, myfork, mypipe, mysbrkといったmyプレフィックス付き関数の宣言の削除。
    • Plan9, Unix, Windowsenum定義と、pathchar, systemtype, alloc, allocnの宣言が追加。
  5. src/cmd/cc/lex.c (Cコンパイラの字句解析)

    • systemtypepathchar関数の定義が追加。
    • myfork() -> fork()
    • mywait() -> wait()
    • mycreate() -> create()
    • myaccess() -> access() (引数にAREADが追加)
    • mypipe() -> pipe()
    • mydup() -> dup()
    • myexec() -> exec()
    • mygetwd() -> getwd()
    • allocallocn関数の実装が追加。
  6. src/cmd/cc/macbody

    • myopen() -> open() (引数にOREADが追加)
  7. src/cmd/gc/go.h (Goコンパイラのヘッダー)

    • void myexit(int); の宣言が削除。
  8. src/cmd/gc/lex.c, src/cmd/gc/subr.c (Goコンパイラ)

    • mygetwd() -> getwd()
    • myexit() -> exit()

コアとなるコードの解説

このコミットの核心は、Goのツールチェーンが使用するシステムコールインターフェースを、カスタムのmy*関数群から、lib9互換の標準的な関数群へと移行した点にあります。

例えば、src/cmd/5a/lex.cの以下の変更を見てみましょう。

--- a/src/cmd/5a/lex.c
+++ b/src/cmd/5a/lex.c
@@ -86,16 +86,13 @@ main(int argc, char *argv[])
 		c = 0;
 		nout = 0;
 		for(;;) {
+			Waitmsg *w;
+
 			while(nout < nproc && argc > 0) {
-				i = myfork();
+				i = fork();
 				if(i < 0) {
-					i = mywait(&status);
-					if(i < 0)
-						errorexit();
-					if(status)
-						c++;
-					nout--;
-					continue;
+					fprint(2, "fork: %r\n");
+					errorexit();
 				}
 				if(i == 0) {
 					print("%s:\n", *argv);
@@ -107,13 +104,13 @@ main(int argc, char *argv[])
 				argc--;
 				argv++;
 			}
-			i = mywait(&status);
-			if(i < 0) {
+			w = wait();
+			if(w == nil) {
 				if(c)
 					errorexit();
 				exits(0);
 			}
-			if(status)
+			if(w->msg[0])
 				c++;
 			nout--;
 		}
@@ -160,7 +157,7 @@ assemble(char *file)\n 		}\n 	}\n 
-	of = mycreat(outfile, 0664);\n+	of = create(outfile, OWRITE, 0664);\
 	if(of < 0) {
 		yyerror("%ca: cannot create %s", thechar, outfile);
 		errorexit();
  • myfork()からfork(): myfork()は、おそらくOS間のforkシステムコールの差異を吸収するためのラッパーでしたが、これが直接fork()に置き換えられました。これは、lib9が提供するfork()が、Goのツールチェーンが必要とするセマンティクスを十分に満たしていることを示唆しています。
  • mywait()からwait()へ、そしてWaitmsgの導入: mywait(&status)は、子プロセスの終了ステータスをstatus変数に格納するUnixライクなインターフェースでした。しかし、Plan 9のwait()システムコールは、Waitmsgという構造体を返します。この構造体には、終了ステータスだけでなく、終了メッセージなどの詳細情報が含まれています。この変更は、GoのツールチェーンがPlan 9のwaitセマンティクスに準拠するように移行したことを明確に示しています。w->msg[0]で終了メッセージの有無をチェックしている点も、Plan 9のwaitの利用方法に合致しています。
  • mycreat()からcreate(): mycreat()もまた、ファイル作成のためのラッパーでしたが、create()に置き換えられました。create()はPlan 9のシステムコールであり、ファイル名とパーミッション(0664)に加えて、OWRITEというフラグを引数に取ります。これは、ファイルを開くモードを明示的に指定するPlan 9の慣習に従ったものです。

これらの変更は、Goのツールチェーンが、よりPlan 9のシステムコールインターフェースに密接に結合されるようになったことを意味します。これにより、compat.hのような中間的な抽象化レイヤーが不要になり、コードベースが簡素化され、Plan 9の設計思想との整合性が高まりました。

また、src/cmd/cc/cc.hからcompat.hのインクルードが削除されたことは、このコミットが単なる関数名の変更に留まらず、compat.hが提供していた互換性レイヤー全体をシステムから取り除いたことを示しています。

関連リンク

  • Plan 9 from Bell Labs: https://9p.io/plan9/
  • Go言語の歴史: Go言語の初期開発に関する公式ドキュメントやブログ記事には、Plan 9の影響について言及されているものがあります。

参考にした情報源リンク

  • Go言語の公式リポジトリのコミット履歴
  • Plan 9 from Bell Labsのドキュメント
  • Unix系システムコールに関する一般的なドキュメント
  • Go言語の初期開発に関する技術ブログや論文 (Web検索を通じて得られた情報)