[インデックス 1091] ファイルの概要
このコミットは、Go言語の初期開発段階において、Darwin (macOS) システム上でのファイルステータス取得(stat
システムコール)に関するバグを修正したものです。具体的には、stat
システムコールを呼び出す際に使用されていたシステムコール番号が誤っていたため、正しい64ビット版のシステムコール番号であるSYS_STAT64
に修正されました。これにより、macOS環境でのファイル操作の正確性と安定性が向上しました。
コミット
commit 4328d44254787c30a32cdb7d93b2c6253ae3b5da
Author: Rob Pike <r@golang.org>
Date: Fri Nov 7 16:17:42 2008 -0800
wrong system call number for stat
TBR=rsc
OCL=18833
CL=18833
---
src/lib/syscall/file_darwin.go | 2 +--
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/syscall/file_darwin.go b/src/lib/syscall/file_darwin.go
index 4a2072d4d5..2cb78ffe5c 100644
--- a/src/lib/syscall/file_darwin.go
+++ b/src/lib/syscall/file_darwin.go
@@ -58,7 +58,7 @@ export func stat(name string, buf *Stat) (ret int64, errno int64) {
if !StringToBytes(&namebuf, name) {
return -1, ENAMETOOLONG
}
- r1, r2, err := Syscall(SYS_STAT, BytePtr(&namebuf[0]), StatPtr(buf), 0);
+ r1, r2, err := Syscall(SYS_STAT64, BytePtr(&namebuf[0]), StatPtr(buf), 0);
return r1, err;
}
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4328d44254787c30a32cdb7d93b2c6253ae3b5da
元コミット内容
wrong system call number for stat
TBR=rsc
OCL=18833
CL=18833
変更の背景
この変更は、Go言語がまだ初期段階にあった2008年に行われました。当時のGo言語のランタイムは、様々なオペレーティングシステム(OS)との低レベルなインタラクションを管理するsyscall
パッケージを通じて、OSの機能を利用していました。
stat
システムコールは、ファイルやディレクトリのメタデータ(サイズ、作成日時、更新日時、パーミッションなど)を取得するために広く使用される重要な機能です。しかし、Darwin(macOS)環境において、Goのsyscall
パッケージがstat
システムコールを呼び出す際に、誤ったシステムコール番号SYS_STAT
を使用していたことが判明しました。
当時のmacOSは既に64ビット環境が主流となっており、ファイルサイズやタイムスタンプなどの情報を正確に扱うためには、64ビット対応のstat
システムコール(通常はstat64
に対応するシステムコール番号)を使用する必要がありました。誤ったシステムコール番号を使用すると、ファイル情報の取得に失敗したり、不正な値が返されたりする可能性があり、GoプログラムがmacOS上でファイルシステムと正しく連携できないという問題を引き起こしていました。
このコミットは、この互換性の問題を解決し、Go言語がmacOS上で安定して動作するための基盤を強化することを目的としています。
前提知識の解説
システムコール (System Call)
システムコールは、ユーザー空間で実行されるプログラムが、カーネル空間で提供されるOSのサービス(ファイル操作、メモリ管理、プロセス管理など)を利用するためのインターフェースです。プログラムが直接ハードウェアにアクセスすることはセキュリティ上、安定性上の問題があるため、OSが提供するシステムコールを介して間接的にアクセスします。各システムコールには一意の番号(システムコール番号)が割り当てられており、プログラムはこの番号を指定してカーネルに処理を要求します。
stat
システムコール
stat
は、指定されたファイルパスに対応するファイルやディレクトリのステータス情報(メタデータ)を取得するためのシステムコールです。取得できる情報には、ファイルの種類(通常ファイル、ディレクトリ、シンボリックリンクなど)、ファイルサイズ、所有者ID、グループID、パーミッション、最終アクセス時刻、最終更新時刻、最終ステータス変更時刻などがあります。プログラミングにおいては、ファイルの存在確認、サイズ取得、パーミッションチェックなど、多岐にわたる場面で利用されます。
Darwin/macOS
Darwinは、AppleのmacOS(旧OS X)の基盤となっているオープンソースのUNIX系オペレーティングシステムです。macOSはDarwinの上に、AquaユーザーインターフェースやCocoaフレームワークなどのプロプライエタリなコンポーネントを加えて構築されています。このコミットは、Darwinカーネルが提供するシステムコールインターフェースに特化した修正です。
SYS_STAT
と SYS_STAT64
UNIX系OSでは、ファイルシステムが進化し、非常に大きなファイル(2GB以上)を扱えるようになるにつれて、従来の32ビットシステムコールではファイルサイズやオフセットを表現しきれない問題が発生しました。この問題を解決するために、64ビットのファイルサイズやオフセットを扱えるように拡張されたシステムコールが導入されました。
SYS_STAT
: 従来の32ビット環境向けのstat
システムコール番号を指すことが多いです。ファイルサイズやオフセットが32ビット整数で表現されるため、2GBを超えるファイルを正確に扱えない可能性があります。SYS_STAT64
: 64ビット環境向けに拡張されたstat
システムコール番号です。ファイルサイズやオフセットを64ビット整数で表現できるため、大容量ファイルを正確に扱うことができます。macOSのような64ビットOSでは、通常stat
関数は内部的にstat64
に相当するシステムコールを呼び出すように実装されています。
このコミットの時点では、Go言語がmacOS上でstat
を呼び出す際に、誤って古い(あるいは不適切な)SYS_STAT
システムコール番号を使用していたため、SYS_STAT64
への変更が必要とされました。
Go言語の syscall
パッケージ
Go言語の標準ライブラリにはsyscall
パッケージ(現在はgolang.org/x/sys/unix
などに移行)が含まれていました。このパッケージは、GoプログラムからOSの低レベルな機能(システムコール)を直接呼び出すための機能を提供します。OSに依存する処理(ファイルI/O、ネットワーク通信、プロセス管理など)の一部は、このパッケージを通じてOSのネイティブなシステムコールを呼び出すことで実現されていました。このコミットで修正されたsrc/lib/syscall/file_darwin.go
は、まさにこのsyscall
パッケージの一部であり、Darwin環境でのファイル関連のシステムコールをラップする役割を担っていました。
技術的詳細
このコミットの技術的な核心は、Darwinカーネルが提供するstat
システムコールの正しい呼び出し規約とシステムコール番号の理解にあります。
Go言語のsyscall
パッケージは、OSのシステムコールを抽象化してGoの関数として提供します。Syscall
関数は、第一引数にシステムコール番号、続く引数にシステムコールに渡すパラメータを取ります。
元のコードでは、src/lib/syscall/file_darwin.go
内のstat
関数が、ファイル名とStat
構造体へのポインタを引数として取り、内部でSyscall(SYS_STAT, ...)
を呼び出していました。しかし、Darwinの64ビット環境では、ファイルステータスを正確に取得するためには、SYS_STAT
ではなくSYS_STAT64
というシステムコール番号を使用する必要がありました。
SYS_STAT
とSYS_STAT64
は、同じstat
という概念のシステムコールですが、その内部的な実装や、特にファイルサイズやタイムスタンプなどのデータ構造のサイズが異なります。64ビット環境で32ビット版のシステムコールを呼び出すと、データ構造の不一致や、大きなファイルに対する情報が正しく取得できないといった問題が発生します。例えば、2GBを超えるファイルのサイズが負の値として報告されたり、全く異なる値になったりする可能性があります。
この修正は、単にシステムコール番号をSYS_STAT
からSYS_STAT64
に変更するだけですが、これによりGoプログラムがmacOS上でファイルシステムと完全に互換性を持つようになり、大容量ファイルの扱いを含むすべてのファイル操作が正確に行われるようになりました。これは、Go言語がクロスプラットフォームで安定して動作するための、非常に重要な低レベルの修正と言えます。
コアとなるコードの変更箇所
変更はsrc/lib/syscall/file_darwin.go
ファイルの一箇所のみです。
--- a/src/lib/syscall/file_darwin.go
+++ b/src/lib/syscall/file_darwin.go
@@ -58,7 +58,7 @@ export func stat(name string, buf *Stat) (ret int64, errno int64) {
if !StringToBytes(&namebuf, name) {
return -1, ENAMETOOLONG
}
- r1, r2, err := Syscall(SYS_STAT, BytePtr(&namebuf[0]), StatPtr(buf), 0);
+ r1, r2, err := Syscall(SYS_STAT64, BytePtr(&namebuf[0]), StatPtr(buf), 0);
return r1, err;
}
具体的には、Syscall
関数の第一引数であるシステムコール番号が、SYS_STAT
からSYS_STAT64
に変更されています。
コアとなるコードの解説
src/lib/syscall/file_darwin.go
内のstat
関数は、Goプログラムがファイルやディレクトリのメタデータを取得する際に、最終的にDarwinカーネルのstat
システムコールを呼び出すためのラッパー関数です。
export func stat(name string, buf *Stat) (ret int64, errno int64)
: この関数は、ファイル名(name
)と、取得したファイルステータスを格納するためのStat
構造体へのポインタ(buf
)を引数に取ります。戻り値は、システムコールの結果(成功時は0、失敗時は-1など)とエラーコード(errno
)です。if !StringToBytes(&namebuf, name) { ... }
: ファイル名をバイト配列に変換し、パスが長すぎる場合はエラーを返します。r1, r2, err := Syscall(SYS_STAT64, BytePtr(&namebuf[0]), StatPtr(buf), 0);
: ここが変更の核心です。Syscall
: Goのsyscall
パッケージが提供する、低レベルなシステムコール呼び出しを行う関数です。SYS_STAT64
: Darwinシステムにおける64ビット版のstat
システムコールの番号です。この修正により、GoプログラムはmacOS上でファイルシステムから正確な64ビットのファイル情報を取得できるようになりました。BytePtr(&namebuf[0])
: ファイル名のバイト配列の先頭へのポインタをシステムコールに渡します。StatPtr(buf)
:Stat
構造体へのポインタをシステムコールに渡し、カーネルがこのメモリ領域にファイルステータス情報を書き込めるようにします。0
: 3番目の引数は、この特定のシステムコールでは使用されないため0が渡されています。
return r1, err;
: システムコールの結果とエラーコードを返します。
この変更により、Go言語のstat
関数は、Darwin環境で期待通りに動作し、特に大容量ファイルのサイズなどを正確に報告できるようになりました。
関連リンク
- TBR=rsc: この表記は、"To Be Reviewed by rsc" の略で、Rob S. Pike氏のコミットがrsc(Russ Cox氏)によってレビューされることを示唆しています。Go言語の初期開発における内部的なレビュープロセスの一部です。
- OCL=18833, CL=18833: これらは、Go言語の内部的な変更リスト(Change List)またはコードレビューシステムにおけるIDである可能性が高いです。GitHubのコミットメッセージにしばしば見られる形式で、内部的な追跡システムへのリンクとして機能します。
参考にした情報源リンク
- Go言語の
syscall
パッケージに関するドキュメント(当時のもの、または現在のgolang.org/x/sys/unix
パッケージのドキュメント) - Darwin/macOSのシステムコールに関するドキュメント(例: XNUカーネルのソースコード、BSD系のmanページ)
stat
システムコールとstat64
システムコールの違いに関する一般的なUNIX/Linuxプログラミングの資料- Go言語の初期開発に関する歴史的資料やメーリングリストのアーカイブ(もしあれば)# [インデックス 1091] ファイルの概要
このコミットは、Go言語の初期開発段階において、Darwin (macOS) システム上でのファイルステータス取得(stat
システムコール)に関するバグを修正したものです。具体的には、stat
システムコールを呼び出す際に使用されていたシステムコール番号が誤っていたため、正しい64ビット版のシステムコール番号であるSYS_STAT64
に修正されました。これにより、macOS環境でのファイル操作の正確性と安定性が向上しました。
コミット
commit 4328d44254787c30a32cdb7d93b2c6253ae3b5da
Author: Rob Pike <r@golang.org>
Date: Fri Nov 7 16:17:42 2008 -0800
wrong system call number for stat
TBR=rsc
OCL=18833
CL=18833
---
src/lib/syscall/file_darwin.go | 2 +--
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/syscall/file_darwin.go b/src/lib/syscall/file_darwin.go
index 4a2072d4d5..2cb78ffe5c 100644
--- a/src/lib/syscall/file_darwin.go
+++ b/src/lib/syscall/file_darwin.go
@@ -58,7 +58,7 @@ export func stat(name string, buf *Stat) (ret int64, errno int64) {
if !StringToBytes(&namebuf, name) {
return -1, ENAMETOOLONG
}
- r1, r2, err := Syscall(SYS_STAT, BytePtr(&namebuf[0]), StatPtr(buf), 0);
+ r1, r2, err := Syscall(SYS_STAT64, BytePtr(&namebuf[0]), StatPtr(buf), 0);
return r1, err;
}
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4328d44254787c30a32cdb7d93b2c6253ae3b5da
元コミット内容
wrong system call number for stat
TBR=rsc
OCL=18833
CL=18833
変更の背景
この変更は、Go言語がまだ初期段階にあった2008年に行われました。当時のGo言語のランタイムは、様々なオペレーティングシステム(OS)との低レベルなインタラクションを管理するsyscall
パッケージを通じて、OSの機能を利用していました。
stat
システムコールは、ファイルやディレクトリのメタデータ(サイズ、作成日時、更新日時、パーミッションなど)を取得するために広く使用される重要な機能です。しかし、Darwin(macOS)環境において、Goのsyscall
パッケージがstat
システムコールを呼び出す際に、誤ったシステムコール番号SYS_STAT
を使用していたことが判明しました。
当時のmacOSは既に64ビット環境が主流となっており、ファイルサイズやタイムスタンプなどの情報を正確に扱うためには、64ビット対応のstat
システムコール(通常はstat64
に対応するシステムコール番号)を使用する必要がありました。誤ったシステムコール番号を使用すると、ファイル情報の取得に失敗したり、不正な値が返されたりする可能性があり、GoプログラムがmacOS上でファイルシステムと正しく連携できないという問題を引き起こしていました。
このコミットは、この互換性の問題を解決し、Go言語がmacOS上で安定して動作するための基盤を強化することを目的としています。
前提知識の解説
システムコール (System Call)
システムコールは、ユーザー空間で実行されるプログラムが、カーネル空間で提供されるOSのサービス(ファイル操作、メモリ管理、プロセス管理など)を利用するためのインターフェースです。プログラムが直接ハードウェアにアクセスすることはセキュリティ上、安定性上の問題があるため、OSが提供するシステムコールを介して間接的にアクセスします。各システムコールには一意の番号(システムコール番号)が割り当てられており、プログラムはこの番号を指定してカーネルに処理を要求します。
stat
システムコール
stat
は、指定されたファイルパスに対応するファイルやディレクトリのステータス情報(メタデータ)を取得するためのシステムコールです。取得できる情報には、ファイルの種類(通常ファイル、ディレクトリ、シンボリックリンクなど)、ファイルサイズ、所有者ID、グループID、パーミッション、最終アクセス時刻、最終更新時刻、最終ステータス変更時刻などがあります。プログラミングにおいては、ファイルの存在確認、サイズ取得、パーミッションチェックなど、多岐にわたる場面で利用されます。
Darwin/macOS
Darwinは、AppleのmacOS(旧OS X)の基盤となっているオープンソースのUNIX系オペレーティングシステムです。macOSはDarwinの上に、AquaユーザーインターフェースやCocoaフレームワークなどのプロプライエタリなコンポーネントを加えて構築されています。このコミットは、Darwinカーネルが提供するシステムコールインターフェースに特化した修正です。
SYS_STAT
と SYS_STAT64
UNIX系OSでは、ファイルシステムが進化し、非常に大きなファイル(2GB以上)を扱えるようになるにつれて、従来の32ビットシステムコールではファイルサイズやオフセットを表現しきれない問題が発生しました。この問題を解決するために、64ビットのファイルサイズやオフセットを扱えるように拡張されたシステムコールが導入されました。
SYS_STAT
: 従来の32ビット環境向けのstat
システムコール番号を指すことが多いです。ファイルサイズやオフセットが32ビット整数で表現されるため、2GBを超えるファイルを正確に扱えない可能性があります。SYS_STAT64
: 64ビット環境向けに拡張されたstat
システムコール番号です。ファイルサイズやオフセットを64ビット整数で表現できるため、大容量ファイルを正確に扱うことができます。macOSのような64ビットOSでは、通常stat
関数は内部的にstat64
に相当するシステムコールを呼び出すように実装されています。
このコミットの時点では、Go言語がmacOS上でstat
を呼び出す際に、誤って古い(あるいは不適切な)SYS_STAT
システムコール番号を使用していたため、SYS_STAT64
への変更が必要とされました。
Go言語の syscall
パッケージ
Go言語の標準ライブラリにはsyscall
パッケージ(現在はgolang.org/x/sys/unix
などに移行)が含まれていました。このパッケージは、GoプログラムからOSの低レベルな機能(システムコール)を直接呼び出すための機能を提供します。OSに依存する処理(ファイルI/O、ネットワーク通信、プロセス管理など)の一部は、このパッケージを通じてOSのネイティブなシステムコールを呼び出すことで実現されていました。このコミットで修正されたsrc/lib/syscall/file_darwin.go
は、まさにこのsyscall
パッケージの一部であり、Darwin環境でのファイル関連のシステムコールをラップする役割を担っていました。
技術的詳細
このコミットの技術的な核心は、Darwinカーネルが提供するstat
システムコールの正しい呼び出し規約とシステムコール番号の理解にあります。
Go言語のsyscall
パッケージは、OSのシステムコールを抽象化してGoの関数として提供します。Syscall
関数は、第一引数にシステムコール番号、続く引数にシステムコールに渡すパラメータを取ります。
元のコードでは、src/lib/syscall/file_darwin.go
内のstat
関数が、ファイル名とStat
構造体へのポインタを引数として取り、内部でSyscall(SYS_STAT, ...)
を呼び出していました。しかし、Darwinの64ビット環境では、ファイルステータスを正確に取得するためには、SYS_STAT
ではなくSYS_STAT64
というシステムコール番号を使用する必要がありました。
SYS_STAT
とSYS_STAT64
は、同じstat
という概念のシステムコールですが、その内部的な実装や、特にファイルサイズやタイムスタンプなどのデータ構造のサイズが異なります。64ビット環境で32ビット版のシステムコールを呼び出すと、データ構造の不一致や、大きなファイルに対する情報が正しく取得できないといった問題が発生します。例えば、2GBを超えるファイルのサイズが負の値として報告されたり、全く異なる値になったりする可能性があります。
この修正は、単にシステムコール番号をSYS_STAT
からSYS_STAT64
に変更するだけですが、これによりGoプログラムがmacOS上でファイルシステムと完全に互換性を持つようになり、大容量ファイルの扱いを含むすべてのファイル操作が正確に行われるようになりました。これは、Go言語がクロスプラットフォームで安定して動作するための、非常に重要な低レベルの修正と言えます。
コアとなるコードの変更箇所
変更はsrc/lib/syscall/file_darwin.go
ファイルの一箇所のみです。
--- a/src/lib/syscall/file_darwin.go
+++ b/src/lib/syscall/file_darwin.go
@@ -58,7 +58,7 @@ export func stat(name string, buf *Stat) (ret int64, errno int64) {
if !StringToBytes(&namebuf, name) {
return -1, ENAMETOOLONG
}
- r1, r2, err := Syscall(SYS_STAT, BytePtr(&namebuf[0]), StatPtr(buf), 0);
+ r1, r2, err := Syscall(SYS_STAT64, BytePtr(&namebuf[0]), StatPtr(buf), 0);
return r1, err;
}
具体的には、Syscall
関数の第一引数であるシステムコール番号が、SYS_STAT
からSYS_STAT64
に変更されています。
コアとなるコードの解説
src/lib/syscall/file_darwin.go
内のstat
関数は、Goプログラムがファイルやディレクトリのメタデータを取得する際に、最終的にDarwinカーネルのstat
システムコールを呼び出すためのラッパー関数です。
export func stat(name string, buf *Stat) (ret int64, errno int64)
: この関数は、ファイル名(name
)と、取得したファイルステータスを格納するためのStat
構造体へのポインタ(buf
)を引数に取ります。戻り値は、システムコールの結果(成功時は0、失敗時は-1など)とエラーコード(errno
)です。if !StringToBytes(&namebuf, name) { ... }
: ファイル名をバイト配列に変換し、パスが長すぎる場合はエラーを返します。r1, r2, err := Syscall(SYS_STAT64, BytePtr(&namebuf[0]), StatPtr(buf), 0);
: ここが変更の核心です。Syscall
: Goのsyscall
パッケージが提供する、低レベルなシステムコール呼び出しを行う関数です。SYS_STAT64
: Darwinシステムにおける64ビット版のstat
システムコールの番号です。この修正により、GoプログラムはmacOS上でファイルシステムから正確な64ビットのファイル情報を取得できるようになりました。BytePtr(&namebuf[0])
: ファイル名のバイト配列の先頭へのポインタをシステムコールに渡します。StatPtr(buf)
:Stat
構造体へのポインタをシステムコールに渡し、カーネルがこのメモリ領域にファイルステータス情報を書き込めるようにします。0
: 3番目の引数は、この特定のシステムコールでは使用されないため0が渡されています。
return r1, err;
: システムコールの結果とエラーコードを返します。
この変更により、Go言語のstat
関数は、Darwin環境で期待通りに動作し、特に大容量ファイルのサイズなどを正確に報告できるようになりました。
関連リンク
- TBR=rsc: この表記は、"To Be Reviewed by rsc" の略で、Rob S. Pike氏のコミットがrsc(Russ Cox氏)によってレビューされることを示唆しています。Go言語の初期開発における内部的なレビュープロセスの一部です。
- OCL=18833, CL=18833: これらは、Go言語の内部的な変更リスト(Change List)またはコードレビューシステムにおけるIDである可能性が高いです。GitHubのコミットメッセージにしばしば見られる形式で、内部的な追跡システムへのリンクとして機能します。
参考にした情報源リンク
- Go言語の
syscall
パッケージに関するドキュメント(当時のもの、または現在のgolang.org/x/sys/unix
パッケージのドキュメント) - Darwin/macOSのシステムコールに関するドキュメント(例: XNUカーネルのソースコード、BSD系のmanページ)
stat
システムコールとstat64
システムコールの違いに関する一般的なUNIX/Linuxプログラミングの資料- Go言語の初期開発に関する歴史的資料やメーリングリストのアーカイブ(もしあれば)