[インデックス 18273] ファイルの概要
このコミットは、Go言語の syscall
パッケージにLinux向けの Flock_t
構造体を追加するものです。これにより、Linux環境で flock(2)
システムコールを用いたアドバイザリファイルロックをGoアプリケーションから直接、かつポータブルに利用できるようになります。
コミット
commit 055b588e554ecf6bbf3aff3cdb5e663417ed4df4
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Thu Jan 16 14:08:32 2014 -0800
syscall: add Flock_t on Linux
Matches Darwin and the BSDs. This means leveldb-go, kv,
Camlistore, etc can stop defining these structs on Linux by
hand.
Update #7059
R=golang-codereviews, dave, iant
CC=golang-codereviews
https://golang.org/cl/53350043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/055b588e554ecf6bbf3aff3cdb5e663417ed4df4
元コミット内容
syscall: add Flock_t on Linux
このコミットは、Linux上で Flock_t
構造体を追加します。
これはDarwin(macOS)やBSD系OSと一致します。これにより、leveldb-go
、kv
、Camlistore
などのプロジェクトが、Linux上でこれらの構造体を手動で定義する必要がなくなります。
関連するIssue: #7059
変更の背景
Go言語の syscall
パッケージは、オペレーティングシステムが提供する低レベルなシステムコールへのインターフェースを提供します。ファイルロックは、複数のプロセスが同時に同じファイルにアクセスする際にデータの整合性を保つために不可欠なメカニズムです。Unix系システムでは、flock(2)
システムコールがアドバイザリファイルロックを提供します。
これまで、Goの syscall
パッケージはDarwin(macOS)やBSD系OS向けには Flock_t
構造体を定義していましたが、Linux向けにはこの構造体が欠けていました。このため、leveldb-go
(Goで実装されたLevelDBのバインディング)、kv
(キーバリューストア)、Camlistore
(パーソナルストレージシステム) といった、ファイルロックを必要とするGoアプリケーションは、Linux上で flock(2)
を利用するために、Flock_t
構造体を各々で手動で定義する必要がありました。これはコードの重複、保守性の低下、そしてプラットフォーム間のポータビリティの欠如を招いていました。
このコミットの目的は、Linux環境においても Flock_t
を syscall
パッケージに公式に含めることで、これらの問題を解決し、Goアプリケーションがより簡単に、かつ標準的な方法でファイルロックを利用できるようにすることです。Issue #7059でこの問題が報告され、このコミットによって解決されました。
前提知識の解説
1. システムコール (System Call)
システムコールは、オペレーティングシステム (OS) のカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。ファイル操作、プロセス管理、メモリ管理、ネットワーク通信など、OSの機能にアクセスする際に使用されます。Go言語の syscall
パッケージは、これらの低レベルなシステムコールをGoプログラムから呼び出すためのラッパーを提供します。
2. ファイルロック (File Locking)
ファイルロックは、複数のプロセスが共有ファイルに同時にアクセスする際に、データの破損や競合状態を防ぐためのメカニズムです。主に以下の2種類があります。
- アドバイザリロック (Advisory Lock): ロックの取得は強制ではなく、協調的なプロセスのみがロックを尊重します。ロックを無視するプロセスは、ロックされたファイルにアクセスできてしまいます。
flock(2)
はアドバイザリロックを提供します。 - 強制ロック (Mandatory Lock): OSカーネルがロックを強制し、ロックされたファイルへの不正なアクセスを防止します。
3. flock(2)
システムコール
flock(2)
はUnix系システムで利用されるアドバイザリファイルロックのシステムコールです。ファイルディスクリプタに対してロックを設定または解除します。主なロックの種類は以下の通りです。
- 共有ロック (Shared Lock /
LOCK_SH
): 複数のプロセスが同時に取得できます。主に読み取りアクセスに使用されます。 - 排他ロック (Exclusive Lock /
LOCK_EX
): 一度に1つのプロセスのみが取得できます。主に書き込みアクセスに使用されます。
flock(2)
は、ファイル全体をロックする性質があり、バイト範囲ロック (fcntl(2)
) とは異なります。
4. Flock_t
構造体
Flock_t
は、flock(2)
システムコールではなく、より汎用的な fcntl(2)
システムコールでバイト範囲ロックを操作する際に使用される struct flock
に対応するGoの構造体です。fcntl(2)
の F_GETLK
, F_SETLK
, F_SETLKW
コマンドで使用され、ロックの種類 (l_type
)、ロックの開始オフセット (l_start
)、ロックの長さ (l_len
)、ロックを保持しているプロセスのPID (l_pid
) などの情報を含みます。
このコミットの文脈では、flock(2)
システムコール自体が Flock_t
構造体を直接引数として取るわけではありませんが、Goの syscall
パッケージでは、Unix系システムコールに関連する構造体を統一的に _t
サフィックスで定義する慣習があります。したがって、flock(2)
のようなファイルロック操作に関連するGoのAPIを設計する上で、Flock_t
のような構造体が存在することは、そのAPIの引数や戻り値の型として利用される可能性があり、Goアプリケーションがファイルロック情報を表現する上で標準的な型を提供することになります。
5. ztypes_linux_*.go
ファイル
Goの syscall
パッケージには、各OSおよびアーキテクチャ固有の型定義が含まれています。ztypes_linux_386.go
、ztypes_linux_amd64.go
、ztypes_linux_arm.go
といったファイルは、それぞれLinuxの32ビット (x86)、64ビット (x86-64)、ARMアーキテクチャ向けのシステムコール関連のC言語の構造体や定数をGoの型にマッピングしたものです。これらのファイルは通常、自動生成されますが、手動で追加されることもあります。
技術的詳細
このコミットは、Linuxにおける Flock_t
構造体の定義を src/pkg/syscall/types_linux.go
および各アーキテクチャ固有の ztypes_linux_*.go
ファイルに追加することで、Goの syscall
パッケージのクロスプラットフォーム互換性を向上させています。
具体的には、以下の変更が行われました。
-
src/pkg/syscall/types_linux.go
:type Flock_t C.struct_flock
という行が追加されました。これは、C言語のstruct flock
をGoのFlock_t
型としてエイリアス(型定義)するものです。これにより、GoコードからCのstruct flock
に対応する型を直接参照できるようになります。
-
src/pkg/syscall/ztypes_linux_386.go
、src/pkg/syscall/ztypes_linux_amd64.go
、src/pkg/syscall/ztypes_linux_arm.go
:- 各アーキテクチャのファイルに
Flock_t
構造体のGoでの具体的な定義が追加されました。この定義は、C言語のstruct flock
のメンバとメモリレイアウトに厳密に一致するように設計されています。 Type
(int16): ロックの種類 (F_RDLCK
,F_WRLCK
,F_UNLCK
)Whence
(int16): ロックの開始オフセットの基準 (SEEK_SET
,SEEK_CUR
,SEEK_END
)Start
(int64): ロックの開始オフセットLen
(int64): ロックの長さPid
(int32): ロックを保持しているプロセスのID (F_GETLKの場合に設定される)ztypes_linux_amd64.go
では、64ビットアーキテクチャでのアライメント要件を満たすためにPad_cgo_0
とPad_cgo_1
というパディングバイトが追加されています。これは、Cgoを介してCの構造体とGoの構造体をやり取りする際に、メモリレイアウトが一致していることを保証するために重要です。
- 各アーキテクチャのファイルに
-
src/pkg/syscall/consistency_unix_test.go
:Flock_t
構造体が正しく定義され、アクセス可能であることを確認するためのテストコードが追加されました。このテストは、Flock_t
構造体のゼロ値を作成し、そのメンバにアクセスできることを確認するもので、コンパイルが通れば構造体の定義が正しいことを示します。
この変更により、GoプログラムはLinux上で Flock_t
構造体を直接利用し、syscall.FcntlFlock
のような関数(fcntl(2)
システムコールをGoから呼び出すためのラッパー)を通じてファイルロック操作を行うことが可能になります。これにより、Goアプリケーションは、C言語で書かれた既存のファイルロックコードとの互換性を保ちつつ、よりGoらしい方法でファイルロックを実装できるようになります。
コアとなるコードの変更箇所
src/pkg/syscall/types_linux.go
--- a/src/pkg/syscall/types_linux.go
+++ b/src/pkg/syscall/types_linux.go
@@ -158,6 +158,8 @@ type Dirent C.struct_dirent
type Fsid C.fsid_t
+type Flock_t C.struct_flock
+
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in
src/pkg/syscall/ztypes_linux_386.go
--- a/src/pkg/syscall/ztypes_linux_386.go
+++ b/src/pkg/syscall/ztypes_linux_386.go
@@ -142,6 +142,14 @@ type Fsid struct {
X__val [2]int32
}
+type Flock_t struct {
+ Type int16
+ Whence int16
+ Start int64
+ Len int64
+ Pid int32
+}
+
type RawSockaddrInet4 struct {
Family uint16
Port uint16
src/pkg/syscall/ztypes_linux_amd64.go
--- a/src/pkg/syscall/ztypes_linux_amd64.go
+++ b/src/pkg/syscall/ztypes_linux_amd64.go
@@ -142,6 +142,16 @@ type Fsid struct {
X__val [2]int32
}
+type Flock_t struct {
+ Type int16
+ Whence int16
+ Pad_cgo_0 [4]byte
+ Start int64
+ Len int64
+ Pid int32
+ Pad_cgo_1 [4]byte
+}
+
type RawSockaddrInet4 struct {
Family uint16
Port uint16
src/pkg/syscall/ztypes_linux_arm.go
--- a/src/pkg/syscall/ztypes_linux_arm.go
+++ b/src/pkg/syscall/ztypes_linux_arm.go
@@ -144,6 +144,14 @@ type Fsid struct {
X__val [2]int32
}
+type Flock_t struct {
+ Type int16
+ Whence int16
+ Start int64
+ Len int64
+ Pid int32
+}
+
type RawSockaddrInet4 struct {
Family uint16
Port uint16
src/pkg/syscall/consistency_unix_test.go
--- a/src/pkg/syscall/consistency_unix_test.go
+++ b/src/pkg/syscall/consistency_unix_test.go
@@ -32,3 +32,13 @@ func _() {
_ int = syscall.TCOFLUSH
)
}
+
+func _() {
+ _ = syscall.Flock_t{
+ Type: int16(0),
+ Whence: int16(0),
+ Start: 0,
+ Len: 0,
+ Pid: int32(0),
+ }
+}
コアとなるコードの解説
src/pkg/syscall/types_linux.go
の変更
このファイルは、Linux固有のシステムコール関連の型定義をGoで提供します。type Flock_t C.struct_flock
の追加は、C言語の struct flock
をGoの Flock_t
型として利用できるようにするためのエイリアス定義です。これにより、Goのコード内で Flock_t
を使用する際に、その背後にあるCの構造体とのマッピングが明確になります。これは、Cgoを介してCのライブラリと連携する際に特に重要です。
src/pkg/syscall/ztypes_linux_*.go
の変更
これらのファイルは、Goの syscall
パッケージが各アーキテクチャ(386, amd64, arm)でCのシステムコール構造体と互換性を持つように、Goの構造体を定義しています。追加された Flock_t
構造体は、Cの struct flock
のメンバ(l_type
, l_whence
, l_start
, l_len
, l_pid
)に対応するフィールドをGoの適切な型(int16
, int64
, int32
)で持ちます。
特に注目すべきは ztypes_linux_amd64.go
に追加された Pad_cgo_0
と Pad_cgo_1
です。これらはパディングバイトであり、64ビットシステムにおけるメモリのアライメント要件を満たすために挿入されます。C言語の構造体は、特定のデータ型が特定のバイト境界に配置されるようにコンパイラによってパディングされることがあります。Goの構造体がCの構造体とバイナリ互換性を持つためには、このパディングも正確に再現する必要があります。これにより、GoとCの間で Flock_t
構造体を安全に受け渡しできるようになります。
src/pkg/syscall/consistency_unix_test.go
の変更
このテストファイルは、Unix系システムにおける syscall
パッケージの型定義の整合性を検証するために使用されます。追加されたテストコードは、syscall.Flock_t
構造体をゼロ値で初期化し、そのフィールドにアクセスできることを確認します。これは、Flock_t
が正しく定義され、Goのコンパイラがそれを認識し、利用できることを保証するための基本的なコンパイル時チェックです。このテストが成功することで、Flock_t
の定義がGoの型システムに正しく統合されたことが確認できます。
これらの変更により、Go開発者はLinux上でファイルロックを扱う際に、手動で Flock_t
を定義する手間が省け、より標準的でポータブルなコードを書けるようになります。これは、leveldb-go
や Camlistore
のような、ファイルシステムと密接に連携するアプリケーションにとって特に大きなメリットとなります。
関連リンク
- Go Issue #7059: syscall: add Flock_t on Linux
- Go Code Review: https://golang.org/cl/53350043
flock(2)
man page (Linux): https://man7.org/linux/man-pages/man2/flock.2.htmlfcntl(2)
man page (Linux): https://man7.org/linux/man-pages/man2/fcntl.2.html
参考にした情報源リンク
- Go言語の
syscall
パッケージのドキュメント - Linuxの
flock(2)
およびfcntl(2)
システムコールのmanページ - Go言語のクロスコンパイルとCgoに関する一般的な情報
- Go言語のIssueトラッカーとコードレビューシステムI have generated the detailed technical explanation in Markdown format, following all the specified instructions and chapter structure. I have included background, prerequisite knowledge, technical details, core code changes, and explanations. I have also included relevant and reference links.
I will now output the generated Markdown to standard output.
# [インデックス 18273] ファイルの概要
このコミットは、Go言語の `syscall` パッケージにLinux向けの `Flock_t` 構造体を追加するものです。これにより、Linux環境で `flock(2)` システムコールを用いたアドバイザリファイルロックをGoアプリケーションから直接、かつポータブルに利用できるようになります。
## コミット
commit 055b588e554ecf6bbf3aff3cdb5e663417ed4df4 Author: Brad Fitzpatrick bradfitz@golang.org Date: Thu Jan 16 14:08:32 2014 -0800
syscall: add Flock_t on Linux
Matches Darwin and the BSDs. This means leveldb-go, kv,
Camlistore, etc can stop defining these structs on Linux by
hand.
Update #7059
R=golang-codereviews, dave, iant
CC=golang-codereviews
https://golang.org/cl/53350043
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/055b588e554ecf6bbf3aff3cdb5e663417ed4df4](https://github.com/golang/go/commit/055b588e554ecf6bbf3aff3cdb5e663417ed4df4)
## 元コミット内容
`syscall: add Flock_t on Linux`
このコミットは、Linux上で `Flock_t` 構造体を追加します。
これはDarwin(macOS)やBSD系OSと一致します。これにより、`leveldb-go`、`kv`、`Camlistore`などのプロジェクトが、Linux上でこれらの構造体を手動で定義する必要がなくなります。
関連するIssue: #7059
## 変更の背景
Go言語の `syscall` パッケージは、オペレーティングシステム (OS) のカーネルが提供する低レベルなシステムコールへのインターフェースを提供します。ファイルロックは、複数のプロセスが同時に同じファイルにアクセスする際にデータの整合性を保つために不可欠なメカニズムです。Unix系システムでは、`flock(2)` システムコールがアドバイザリファイルロックを提供します。
これまで、Goの `syscall` パッケージはDarwin(macOS)やBSD系OS向けには `Flock_t` 構造体を定義していましたが、Linux向けにはこの構造体が欠けていました。このため、`leveldb-go` (Goで実装されたLevelDBのバインディング)、`kv` (キーバリューストア)、`Camlistore` といった、ファイルロックを必要とするGoアプリケーションは、Linux上で `flock(2)` を利用するために、`Flock_t` 構造体を各々で手動で定義する必要がありました。これはコードの重複、保守性の低下、そしてプラットフォーム間のポータビリティの欠如を招いていました。
このコミットの目的は、Linux環境においても `Flock_t` を `syscall` パッケージに公式に含めることで、これらの問題を解決し、Goアプリケーションがより簡単に、かつ標準的な方法でファイルロックを利用できるようにすることです。Issue #7059でこの問題が報告され、このコミットによって解決されました。
## 前提知識の解説
### 1. システムコール (System Call)
システムコールは、オペレーティングシステム (OS) のカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。ファイル操作、プロセス管理、メモリ管理、ネットワーク通信など、OSの機能にアクセスする際に使用されます。Go言語の `syscall` パッケージは、これらの低レベルなシステムコールをGoプログラムから呼び出すためのラッパーを提供します。
### 2. ファイルロック (File Locking)
ファイルロックは、複数のプロセスが共有ファイルに同時にアクセスする際に、データの破損や競合状態を防ぐためのメカニズムです。主に以下の2種類があります。
* **アドバイザリロック (Advisory Lock)**: ロックの取得は強制ではなく、協調的なプロセスのみがロックを尊重します。ロックを無視するプロセスは、ロックされたファイルにアクセスできてしまいます。`flock(2)` はアドバイザリロックを提供します。
* **強制ロック (Mandatory Lock)**: OSカーネルがロックを強制し、ロックされたファイルへの不正なアクセスを防止します。
### 3. `flock(2)` システムコール
`flock(2)` はUnix系システムで利用されるアドバイザリファイルロックのシステムコールです。ファイルディスクリプタに対してロックを設定または解除します。主なロックの種類は以下の通りです。
* **共有ロック (Shared Lock / `LOCK_SH`)**: 複数のプロセスが同時に取得できます。主に読み取りアクセスに使用されます。
* **排他ロック (Exclusive Lock / `LOCK_EX`)**: 一度に1つのプロセスのみが取得できます。主に書き込みアクセスに使用されます。
`flock(2)` は、ファイル全体をロックする性質があり、バイト範囲ロック (`fcntl(2)`) とは異なります。
### 4. `Flock_t` 構造体
`Flock_t` は、`flock(2)` システムコールではなく、より汎用的な `fcntl(2)` システムコールでバイト範囲ロックを操作する際に使用される `struct flock` に対応するGoの構造体です。`fcntl(2)` の `F_GETLK`, `F_SETLK`, `F_SETLKW` コマンドで使用され、ロックの種類 (`l_type`)、ロックの開始オフセット (`l_start`)、ロックの長さ (`l_len`)、ロックを保持しているプロセスのPID (`l_pid`) などの情報を含みます。
このコミットの文脈では、`flock(2)` システムコール自体が `Flock_t` 構造体を直接引数として取るわけではありませんが、Goの `syscall` パッケージでは、Unix系システムコールに関連する構造体を統一的に `_t` サフィックスで定義する慣習があります。したがって、`flock(2)` のようなファイルロック操作に関連するGoのAPIを設計する上で、`Flock_t` のような構造体が存在することは、そのAPIの引数や戻り値の型として利用される可能性があり、Goアプリケーションがファイルロック情報を表現する上で標準的な型を提供することになります。
### 5. `ztypes_linux_*.go` ファイル
Goの `syscall` パッケージには、各OSおよびアーキテクチャ固有の型定義が含まれています。`ztypes_linux_386.go`、`ztypes_linux_amd64.go`、`ztypes_linux_arm.go` といったファイルは、それぞれLinuxの32ビット (x86)、64ビット (x86-64)、ARMアーキテクチャ向けのシステムコール関連のC言語の構造体や定数をGoの型にマッピングしたものです。これらのファイルは通常、自動生成されますが、手動で追加されることもあります。
## 技術的詳細
このコミットは、Linuxにおける `Flock_t` 構造体の定義を `src/pkg/syscall/types_linux.go` および各アーキテクチャ固有の `ztypes_linux_*.go` ファイルに追加することで、Goの `syscall` パッケージのクロスプラットフォーム互換性を向上させています。
具体的には、以下の変更が行われました。
1. **`src/pkg/syscall/types_linux.go`**:
* `type Flock_t C.struct_flock` という行が追加されました。これは、C言語の `struct flock` をGoの `Flock_t` 型としてエイリアス(型定義)するものです。これにより、GoコードからCの `struct flock` に対応する型を直接参照できるようになります。
2. **`src/pkg/syscall/ztypes_linux_386.go`、`src/pkg/syscall/ztypes_linux_amd64.go`、`src/pkg/syscall/ztypes_linux_arm.go`**:
* 各アーキテクチャのファイルに `Flock_t` 構造体のGoでの具体的な定義が追加されました。この定義は、C言語の `struct flock` のメンバとメモリレイアウトに厳密に一致するように設計されています。
* `Type` (int16): ロックの種類 (`F_RDLCK`, `F_WRLCK`, `F_UNLCK`)
* `Whence` (int16): ロックの開始オフセットの基準 (`SEEK_SET`, `SEEK_CUR`, `SEEK_END`)
* `Start` (int64): ロックの開始オフセット
* `Len` (int64): ロックの長さ
* `Pid` (int32): ロックを保持しているプロセスのID (F_GETLKの場合に設定される)
* `ztypes_linux_amd64.go` では、64ビットアーキテクチャでのアライメント要件を満たすために `Pad_cgo_0` と `Pad_cgo_1` というパディングバイトが追加されています。これは、Cgoを介してCの構造体とGoの構造体をやり取りする際に、メモリレイアウトが一致していることを保証するために重要です。
3. **`src/pkg/syscall/consistency_unix_test.go`**:
* `Flock_t` 構造体が正しく定義され、アクセス可能であることを確認するためのテストコードが追加されました。このテストは、`Flock_t` 構造体のゼロ値を作成し、そのメンバにアクセスできることを確認するもので、コンパイルが通れば構造体の定義が正しいことを示します。
この変更により、GoプログラムはLinux上で `Flock_t` 構造体を直接利用し、`syscall.FcntlFlock` のような関数(`fcntl(2)` システムコールをGoから呼び出すためのラッパー)を通じてファイルロック操作を行うことが可能になります。これにより、Goアプリケーションは、C言語で書かれた既存のファイルロックコードとの互換性を保ちつつ、よりGoらしい方法でファイルロックを実装できるようになります。
## コアとなるコードの変更箇所
### `src/pkg/syscall/types_linux.go`
```diff
--- a/src/pkg/syscall/types_linux.go
+++ b/src/pkg/syscall/types_linux.go
@@ -158,6 +158,8 @@ type Dirent C.struct_dirent
type Fsid C.fsid_t
+type Flock_t C.struct_flock
+
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in
src/pkg/syscall/ztypes_linux_386.go
--- a/src/pkg/syscall/ztypes_linux_386.go
+++ b/src/pkg/syscall/ztypes_linux_386.go
@@ -142,6 +142,14 @@ type Fsid struct {
X__val [2]int32
}
+type Flock_t struct {
+ Type int16
+ Whence int16
+ Start int64
+ Len int64
+ Pid int32
+}
+
type RawSockaddrInet4 struct {
Family uint16
Port uint16
src/pkg/syscall/ztypes_linux_amd64.go
--- a/src/pkg/syscall/ztypes_linux_amd64.go
+++ b/src/pkg/syscall/ztypes_linux_amd64.go
@@ -142,6 +142,16 @@ type Fsid struct {
X__val [2]int32
}
+type Flock_t struct {
+ Type int16
+ Whence int16
+ Pad_cgo_0 [4]byte
+ Start int64
+ Len int64
+ Pid int32
+ Pad_cgo_1 [4]byte
+}
+
type RawSockaddrInet4 struct {
Family uint16
Port uint16
src/pkg/syscall/ztypes_linux_arm.go
--- a/src/pkg/syscall/ztypes_linux_arm.go
+++ b/src/pkg/syscall/ztypes_linux_arm.go
@@ -144,6 +144,14 @@ type Fsid struct {
X__val [2]int32
}
+type Flock_t struct {
+ Type int16
+ Whence int16
+ Start int64
+ Len int64
+ Pid int32
+}
+
type RawSockaddrInet4 struct {
Family uint16
Port uint16
src/pkg/syscall/consistency_unix_test.go
--- a/src/pkg/syscall/consistency_unix_test.go
+++ b/src/pkg/syscall/consistency_unix_test.go
@@ -32,3 +32,13 @@ func _() {
_ int = syscall.TCOFLUSH
)
}
+
+func _() {
+ _ = syscall.Flock_t{
+ Type: int16(0),
+ Whence: int16(0),
+ Start: 0,
+ Len: 0,
+ Pid: int32(0),
+ }
+}
コアとなるコードの解説
src/pkg/syscall/types_linux.go
の変更
このファイルは、Linux固有のシステムコール関連の型定義をGoで提供します。type Flock_t C.struct_flock
の追加は、C言語の struct flock
をGoの Flock_t
型として利用できるようにするためのエイリアス定義です。これにより、Goのコード内で Flock_t
を使用する際に、その背後にあるCの構造体とのマッピングが明確になります。これは、Cgoを介してCのライブラリと連携する際に特に重要です。
src/pkg/syscall/ztypes_linux_*.go
の変更
これらのファイルは、Goの syscall
パッケージが各アーキテクチャ(386, amd64, arm)でCのシステムコール構造体と互換性を持つように、Goの構造体を定義しています。追加された Flock_t
構造体は、Cの struct flock
のメンバ(l_type
, l_whence
, l_start
, l_len
, l_pid
)に対応するフィールドをGoの適切な型(int16
, int64
, int32
)で持ちます。
特に注目すべきは ztypes_linux_amd64.go
に追加された Pad_cgo_0
と Pad_cgo_1
です。これらはパディングバイトであり、64ビットシステムにおけるメモリのアライメント要件を満たすために挿入されます。C言語の構造体は、特定のデータ型が特定のバイト境界に配置されるようにコンパイラによってパディングされることがあります。Goの構造体がCの構造体とバイナリ互換性を持つためには、このパディングも正確に再現する必要があります。これにより、GoとCの間で Flock_t
構造体を安全に受け渡しできるようになります。
src/pkg/syscall/consistency_unix_test.go
の変更
このテストファイルは、Unix系システムにおける syscall
パッケージの型定義の整合性を検証するために使用されます。追加されたテストコードは、syscall.Flock_t
構造体をゼロ値で初期化し、そのフィールドにアクセスできることを確認します。これは、Flock_t
が正しく定義され、Goのコンパイラがそれを認識し、利用できることを保証するための基本的なコンパイル時チェックです。このテストが成功することで、Flock_t
の定義がGoの型システムに正しく統合されたことが確認できます。
これらの変更により、Go開発者はLinux上でファイルロックを扱う際に、手動で Flock_t
を定義する手間が省け、より標準的でポータブルなコードを書けるようになります。これは、leveldb-go
や Camlistore
のような、ファイルシステムと密接に連携するアプリケーションにとって特に大きなメリットとなります。
関連リンク
- Go Issue #7059: syscall: add Flock_t on Linux
- Go Code Review: https://golang.org/cl/53350043
flock(2)
man page (Linux): https://man7.org/linux/man-pages/man2/flock.2.htmlfcntl(2)
man page (Linux): https://man7.org/linux/man-pages/man2/fcntl.2.html
参考にした情報源リンク
- Go言語の
syscall
パッケージのドキュメント - Linuxの
flock(2)
およびfcntl(2)
システムコールのmanページ - Go言語のクロスコンパイルとCgoに関する一般的な情報
- Go言語のIssueトラッカーとコードレビューシステム