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

[インデックス 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_STATSYS_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_STATSYS_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_STATSYS_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_STATSYS_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言語の初期開発に関する歴史的資料やメーリングリストのアーカイブ(もしあれば)