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

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

このコミットは、Go言語のsyscallパッケージにおいて、nacl(Native Client)環境向けにSO_ERROR定数を追加するものです。これにより、nacl環境下でもソケットのエラー状態を取得できるようになり、ネットワーク関連の処理におけるエラーハンドリングの堅牢性が向上します。

コミット

commit 4c75cab6783d7871987b99d72a310aa34b68e214
Author: Dave Cheney <dave@cheney.net>
Date:   Sun Mar 9 13:18:12 2014 +1100

    syscall: add missing SO_ERROR constant for nacl/*
    
    CL 69340044 requires that syscall.SO_ERROR be defined on all unix like platforms. Add SO_ERROR to the list of dummy constants in sycall/net_nacl.go.
    
    LGTM=bradfitz
    R=iant, rsc, mikioh.mikioh, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/73100043
---
 src/pkg/syscall/net_nacl.go | 1 +\n 1 file changed, 1 insertion(+)

diff --git a/src/pkg/syscall/net_nacl.go b/src/pkg/syscall/net_nacl.go
index f6d9e20f64..a2588d0419 100644
--- a/src/pkg/syscall/net_nacl.go
+++ b/src/pkg/syscall/net_nacl.go
@@ -112,6 +112,7 @@ const (
 	SO_SNDBUF
 	SO_KEEPALIVE
 	SO_LINGER
+\tSO_ERROR
 	IP_MULTICAST_IF
 	IP_MULTICAST_LOOP
 	IP_ADD_MEMBERSHIP

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

https://github.com/golang/go/commit/4c75cab6783d7871987b99d72a310aa34b68e214

元コミット内容

syscall: add missing SO_ERROR constant for nacl/*

このコミットは、syscallパッケージにおいて、nacl(Native Client)環境向けにSO_ERROR定数が不足していたため、これを追加するものです。コミットメッセージによると、CL 69340044という変更が、すべてのUnixライクなプラットフォームでsyscall.SO_ERRORが定義されていることを要求しており、その要件を満たすためにsyscall/net_nacl.go内のダミー定数リストにSO_ERRORが追加されました。

変更の背景

この変更の背景には、Go言語のsyscallパッケージが提供するネットワーク関連の機能が、特定のプラットフォーム(この場合はGoogle Native Client、nacl)で一貫して動作するようにするという目的があります。

CL 69340044という変更は、Goの標準ライブラリがUnixライクなシステム上でSO_ERROR定数を必要とするようになったことを示唆しています。SO_ERRORは、ソケットオプションの一つであり、ソケットに保留中のエラーがある場合にそのエラーコードを取得するために使用されます。ネットワークプログラミングにおいて、非同期操作や接続確立後のエラーチェックなどで重要な役割を果たします。

nacl環境は、セキュリティとポータビリティを重視したサンドボックス環境であり、通常のオペレーティングシステムとは異なるシステムコールやAPIのセットを持つことがあります。そのため、Goの標準ライブラリがnacl環境でも期待通りに動作するためには、nacl固有の実装で必要な定数や関数が適切に定義されている必要があります。

このコミットは、nacl環境におけるsyscallパッケージの完全性を確保し、Goのネットワーク関連コードがnacl上でも移植性を持って動作するための基盤を強化するものです。具体的には、SO_ERRORnacl環境で定義されていなかったために発生する可能性のあるコンパイルエラーやランタイムエラーを防ぐことが目的です。

前提知識の解説

1. syscallパッケージ

Go言語のsyscallパッケージは、オペレーティングシステムが提供する低レベルなシステムコールへのインターフェースを提供します。これにより、ファイル操作、ネットワーク通信、プロセス管理など、OSカーネルが提供する基本的な機能に直接アクセスできます。Goの標準ライブラリの多くの部分(特にosnetパッケージ)は、内部的にこのsyscallパッケージを利用してOSと対話しています。

2. ソケットオプション (Socket Options)

ソケットオプションは、ネットワークソケットの動作を制御するための設定です。setsockoptgetsockoptといったシステムコールを通じて設定・取得されます。これらは、ソケットのバッファサイズ、タイムアウト、再利用設定、エラー状態など、多岐にわたる側面を調整するために使用されます。

3. SO_ERROR

SO_ERRORは、ソケットオプションの一つで、ソケットに保留中のエラーがある場合にそのエラーコードを取得するために使用されます。例えば、非同期で接続を試みた場合や、ソケットに書き込みを行った際にエラーが発生したが、そのエラーがすぐに返されずにソケット内部に保持されているような場合に、後からSO_ERRORgetsockoptで取得することで、そのエラーの詳細を知ることができます。SO_ERRORは通常、エラーが発生していない場合は0を返します。

4. Google Native Client (nacl)

Google Native Client (NaCl) は、ウェブブラウザ内でネイティブコード(C/C++など)を安全に実行するためのサンドボックス技術です。NaClは、CPUアーキテクチャに依存しないポータブルな実行形式(PNaCl)も提供し、ウェブアプリケーションがネイティブのパフォーマンスで動作することを可能にします。Go言語は、かつてNaClをターゲットプラットフォームの一つとしてサポートしていました。これは、Goで書かれたプログラムをウェブブラウザ内で実行できるようにするためです。nacl/*という表記は、nacl環境向けの特定のアーキテクチャ(例: nacl/amd64, nacl/386など)を指します。

5. CL (Change List)

Goプロジェクトでは、コードレビューシステムとしてGerritを使用しており、各変更は「Change List (CL)」として管理されます。CL 69340044CL 73100043といった表記は、特定のコード変更の識別子です。これらのCLを参照することで、関連する議論や変更の経緯を追跡できます。

技術的詳細

このコミットの技術的詳細を理解するためには、SO_ERRORがどのように機能し、なぜnacl環境でその定義が必要とされたのかを掘り下げることが重要です。

SO_ERRORの機能

SO_ERRORは、ソケットの非同期エラー処理において特に有用です。例えば、connect()システムコールが非ブロッキングモードで呼び出され、接続がすぐに確立されなかった場合、EINPROGRESSなどのエラーが返されます。その後、接続が確立されたか、あるいはエラーが発生したかを判断するために、select()poll()などのI/O多重化メカニズムを使用します。これらの関数がソケットが書き込み可能(または読み込み可能)になったことを示した場合、通常はgetsockoptSO_ERRORオプションと共に呼び出すことで、接続試行中に発生した実際のエラーコード(例: ECONNREFUSEDETIMEDOUTなど)を取得します。このエラーコードが0であれば接続は成功しています。

nacl環境におけるSO_ERRORの必要性

Go言語のsyscallパッケージは、各OS/アーキテクチャの組み合わせに対して、その環境固有のシステムコール定数や関数を提供します。src/pkg/syscall/net_nacl.goファイルは、nacl環境におけるネットワーク関連のシステムコール定数を定義する役割を担っています。

コミットメッセージにある「CL 69340044 requires that syscall.SO_ERROR be defined on all unix like platforms」という記述は、Goのネットワークスタックのどこかで、SO_ERROR定数への依存が導入されたことを示しています。これは、Goの標準ライブラリが、ソケットのエラー状態をチェックするためにSO_ERRORを使用するようになったことを意味します。

nacl環境は、そのサンドボックスの性質上、通常のUnixシステムとは異なるシステムコールインターフェースを持つことがあります。しかし、Goの標準ライブラリは、可能な限りプラットフォーム間で一貫したAPIを提供しようとします。そのため、もしnacl環境でSO_ERRORが定義されていなければ、SO_ERRORを使用するGoのネットワークコードがnacl上でコンパイルエラーになったり、予期せぬランタイムエラーを引き起こしたりする可能性がありました。

このコミットでは、SO_ERRORnet_nacl.go内の「ダミー定数」として追加しています。これは、nacl環境が実際にSO_ERRORというソケットオプションをネイティブにサポートしているかどうかに関わらず、Goのコンパイラがsyscall.SO_ERRORというシンボルを見つけられるようにするための措置である可能性があります。もしnaclがこのオプションをサポートしていない場合でも、Goのコードがコンパイルできるように、値が0などのダミー値で定義されることが一般的です。これにより、Goのコードベース全体でSO_ERRORへの参照が解決され、クロスプラットフォームな互換性が維持されます。

net_nacl.goの役割

net_nacl.goのようなファイルは、Goのビルドシステムが特定のターゲット(この場合はnacl)向けにビルドする際にのみ含まれるように設計されています。これは、ファイル名に_naclというサフィックスが付いていることで示されます(Goのビルドタグの慣習)。このファイルには、nacl環境で必要となるが、他のUnixライクなシステムとは異なる定義を持つ可能性のある、ネットワーク関連の定数や関数が含まれています。

このコミットは、Goのネットワークスタックが進化し、より堅牢なエラーハンドリングを導入する中で、naclのような特殊な環境でもその変更が適切に反映されるようにするための、細かだが重要な調整と言えます。

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

--- a/src/pkg/syscall/net_nacl.go
+++ b/src/pkg/syscall/net_nacl.go
@@ -112,6 +112,7 @@ const (
 	SO_SNDBUF
 	SO_KEEPALIVE
 	SO_LINGER
+\tSO_ERROR
 	IP_MULTICAST_IF
 	IP_MULTICAST_LOOP
 	IP_ADD_MEMBERSHIP

変更はsrc/pkg/syscall/net_nacl.goファイルに対して行われました。具体的には、const (ブロックの既存のソケットオプション定数リストに、SO_ERRORが1行追加されています。

コアとなるコードの解説

この変更は非常にシンプルで、SO_ERRORという定数をsrc/pkg/syscall/net_nacl.go内のconstブロックに追加しているだけです。

const (ブロックは、Go言語で複数の定数をまとめて宣言する際に使用されます。このファイルでは、nacl環境で利用可能な(またはGoのコードが参照する)ソケットオプションやその他のネットワーク関連の定数が定義されています。

SO_ERRORがこのリストに追加されたことにより、Goのコンパイラはnacl環境向けにビルドする際に、syscall.SO_ERRORというシンボルを認識できるようになります。これにより、Goの標準ライブラリやユーザーコードがSO_ERRORを参照しても、未定義エラーが発生しなくなります。

前述の通り、nacl環境が実際にSO_ERRORソケットオプションをネイティブにサポートしているかどうかは、このコミットからは直接読み取れません。しかし、Goのクロスプラットフォームな互換性を維持するためには、たとえダミー値であっても、この定数が存在することが重要です。これにより、Goのネットワークコードがプラットフォーム間で一貫したインターフェースを持つことが保証されます。

この変更は、Goのネットワークスタックがより高度なエラー処理メカニズムを採用する中で、naclのような特定のターゲット環境でもその変更がスムーズに統合されるようにするための、基盤的な調整と言えます。

関連リンク

  • Go Gerrit Change-Id: I4c75cab6783d7871987b99d72a310aa34b68e214 (これはコミットハッシュと同じですが、GerritのChange-Id形式です)
  • Go CL 73100043: https://golang.org/cl/73100043 (このコミットがGerrit上でレビューされた際のリンク)

参考にした情報源リンク