[インデックス 11255] ファイルの概要
このコミットは、Go言語のsyscall
パッケージにおけるPlan 9オペレーティングシステム向けのビルド問題を修正するものです。具体的には、syscall_plan9.go
ファイルにTimespec
構造体の定義を追加することで、システムコールが正しく機能するようにしています。
コミット
- コミットハッシュ:
e3e93b0f4398e57aae02a9eb05b1226731fc05e1
- 作者: Mikio Hara mikioh.mikioh@gmail.com
- 日付: 2012年1月19日 (木) 14:52:28 +0900
- コミットメッセージ:
syscall: fix plan9 build
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e3e93b0f4398e57aae02a9eb05b1226731fc05e1
元コミット内容
syscall: fix plan9 build
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5532097
変更の背景
このコミットの主な背景は、Go言語のsyscall
パッケージがPlan 9オペレーティングシステム上で正しくビルドできない、または実行時に必要なシステムコールインターフェースが不足しているという問題です。syscall
パッケージは、Goプログラムが基盤となるオペレーティングシステムの機能(ファイル操作、プロセス管理、ネットワーク通信など)に直接アクセスするための低レベルなインターフェースを提供します。
Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、そのシステムコールインターフェースはUNIX系システムとは異なる場合があります。Go言語はクロスプラットフォーム対応を目指しており、各OS固有のシステムコールを適切にラップする必要があります。このコミット以前は、Plan 9環境で特定の時間関連のシステムコールを扱う際に、必要なTimespec
構造体がsyscall_plan9.go
に定義されていなかったため、コンパイルエラーや実行時エラーが発生していたと考えられます。
この修正は、Go言語がPlan 9環境でも安定して動作するための互換性向上の一環として行われました。
前提知識の解説
1. Go言語の syscall
パッケージ
Go言語の標準ライブラリに含まれるsyscall
パッケージは、オペレーティングシステムが提供する低レベルなシステムコールに直接アクセスするための機能を提供します。これにより、Goプログラムはファイルシステム、プロセス、ネットワーク、メモリ管理など、OSカーネルの機能を直接利用できます。このパッケージはOSごとに異なる実装を持ち、各OSのシステムコールインターフェースに合わせて調整されています。例えば、UNIX系OSではPOSIX標準に準拠したシステムコールが、WindowsではWin32 APIが利用されます。
2. Plan 9 オペレーティングシステム
Plan 9 from Bell Labsは、UNIXの後継としてベル研究所で開発された分散オペレーティングシステムです。UNIXの哲学をさらに推し進め、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルとして表現し、それらをファイルシステムを通じてアクセスするという特徴を持っています。そのシステムコールインターフェースはUNIXとは異なる部分が多く、Go言語のようなクロスプラットフォーム言語がPlan 9をサポートするためには、専用のラッパーや定義が必要となります。
3. Timespec
構造体
Timespec
は、多くのUNIX系システムやPOSIX標準において、秒とナノ秒の精度で時間を表現するために使用される構造体です。通常、以下のような形式で定義されます。
struct timespec {
time_t tv_sec; // 秒
long tv_nsec; // ナノ秒 (0から999,999,999まで)
};
この構造体は、ファイルのタイムスタンプ(アクセス時刻、変更時刻など)や、高精度なタイマー、スリープ関数など、時間に関連する様々なシステムコールで使用されます。Go言語のsyscall
パッケージでは、OSネイティブのtimespec
構造体に対応するGoの型を定義し、Goプログラムからこれらのシステムコールを呼び出せるようにする必要があります。
4. Timeval
構造体
Timeval
もまた、秒とマイクロ秒の精度で時間を表現するために使用される構造体です。
struct timeval {
time_t tv_sec; // 秒
suseconds_t tv_usec; // マイクロ秒 (0から999,999まで)
};
Timeval
はTimespec
よりも古い時代から使われており、主にselect()
やgettimeofday()
といったシステムコールで利用されます。このコミットではTimeval
の定義は既に存在しており、Timespec
が追加されたことが示唆されています。
技術的詳細
このコミットの技術的な核心は、Go言語のsyscall
パッケージがPlan 9環境で時間関連のシステムコールを正しく扱うために、Timespec
構造体のGo言語での定義が不足していた点にあります。
Go言語のsyscall
パッケージは、各オペレーティングシステム固有のシステムコールをGoの関数としてラップし、Goプログラムから透過的に利用できるようにします。この際、OSネイティブのC言語の構造体に対応するGoの構造体を定義する必要があります。
Plan 9では、特定のシステムコール(例えば、ファイルのタイムスタンプを設定するutimensat
のような関数や、高精度なスリープ関数など)がTimespec
構造体を引数として要求する場合があります。syscall_plan9.go
ファイルは、Plan 9固有のシステムコールインターフェースを定義する場所です。このファイルにTimespec
構造体のGo言語での定義がなかったため、Timespec
を必要とするGoのコードがPlan 9上でコンパイルされる際に、未定義の型としてエラーが発生していました。
追加されたTimespec
構造体は、Sec
(秒)とNsec
(ナノ秒)という2つのint32
型のフィールドを持ちます。これは、Plan 9のネイティブなtimespec
構造体(もし存在すれば)や、一般的なPOSIXのtimespec
構造体と互換性を持たせるためのものです。int32
が選択されているのは、当時のPlan 9のシステムコールインターフェースやGoの内部表現の都合によるものと考えられます。
この定義を追加することで、GoコンパイラはTimespec
型を認識し、Plan 9固有のシステムコールを呼び出す際に必要な引数の型チェックやメモリレイアウトを正しく処理できるようになります。結果として、Plan 9上でのGoプログラムのビルドが成功し、時間関連のシステムコールが期待通りに動作するようになります。
コアとなるコードの変更箇所
変更はsrc/pkg/syscall/syscall_plan9.go
ファイルに対して行われました。
diff --git a/src/pkg/syscall/syscall_plan9.go b/src/pkg/syscall/syscall_plan9.go
index cd348f890d..0bbb7ece99 100644
--- a/src/pkg/syscall/syscall_plan9.go
+++ b/src/pkg/syscall/syscall_plan9.go
@@ -268,6 +268,11 @@ func Fchdir(fd int) (err error) {
return Chdir(path)
}
+type Timespec struct {
+\tSec int32
+\tNsec int32
+}
+
type Timeval struct {
Sec int32
Usec int32
コアとなるコードの解説
このコミットのコアとなる変更は、src/pkg/syscall/syscall_plan9.go
ファイルに以下のTimespec
構造体を追加したことです。
type Timespec struct {
Sec int32
Nsec int32
}
このコードは、Go言語におけるTimespec
構造体の定義です。
type Timespec struct { ... }
:Timespec
という名前の新しい構造体型を定義しています。Sec int32
:Sec
という名前のフィールドを定義しており、これは秒を表すために使用されます。型はint32
です。Nsec int32
:Nsec
という名前のフィールドを定義しており、これはナノ秒を表すために使用されます。型はint32
です。
この定義が追加されることで、syscall
パッケージ内の他の関数や、syscall
パッケージを利用するGoのコードが、Plan 9環境でTimespec
型の値を生成したり、システムコールに渡したり、システムコールから受け取ったりすることが可能になります。
例えば、もしPlan 9にutimensat
のようなシステムコールがあり、それがTimespec
構造体を引数として取る場合、この定義がなければGoのコードはコンパイルエラーになります。この定義が追加されたことで、Goのsyscall
パッケージはPlan 9のネイティブな時間表現とGoの型システムとの間の橋渡しができるようになり、Plan 9上でのGoプログラムの互換性と機能性が向上しました。
この変更は、既存のTimeval
構造体の定義の直前に追加されており、時間関連の構造体がまとまって配置されるように配慮されています。
関連リンク
- Go Gerrit Change-ID: https://golang.org/cl/5532097
参考にした情報源リンク
- Go言語のsyscallパッケージに関する公式ドキュメント (当時の情報に基づく) (現在のドキュメントは変更されている可能性がありますが、概念は共通です)
- Plan 9 from Bell Labs (Wikipedia)
- POSIX
timespec
構造体に関する情報 (一般的なtimespec
の理解のため) - POSIX
timeval
構造体に関する情報 (一般的なtimeval
の理解のため) - Go言語のクロスコンパイルとOS固有のコードに関する情報 (Goのクロスプラットフォーム開発の背景理解のため)