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

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

このコミットは、Go言語のsyscallパッケージの一部であるmkerrors.shスクリプトに対する変更です。mkerrors.shは、様々なオペレーティングシステム(OS)のシステムコールに関連する定数(エラーコード、フラグなど)をC言語のヘッダーファイルから抽出し、Go言語のコードとして自動生成するために使用されるシェルスクリプトです。これにより、GoプログラムがOS固有のシステムコール定数を安全かつ効率的に利用できるようになります。

コミット

syscall: OS X Mavericks以降でRTF_BITS定数を生成しないようにする

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

https://github.com/golang/go/commit/753bdc0f47a4224387a31b92403ab543e9fbebfe

元コミット内容

commit 753bdc0f47a4224387a31b92403ab543e9fbebfe
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Fri Mar 28 13:27:14 2014 +0900

    syscall: don't generate RTF_BITS constant on OS X Mavericks and beyond
    
    LGTM=iant
    R=iant, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/80700044
---
 src/pkg/syscall/mkerrors.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/pkg/syscall/mkerrors.sh b/src/pkg/syscall/mkerrors.sh
index 2d33f24194..7ddd478455 100755
--- a/src/pkg/syscall/mkerrors.sh
+++ b/src/pkg/syscall/mkerrors.sh
@@ -269,6 +269,7 @@ ccflags="$@"
  		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
  		$2 ~ /^SIOC/ ||
  		$2 ~ /^TIOC/ ||
+\t\t$2 !~ "RTF_BITS" &&
  		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
  		$2 ~ /^BIOC/ ||
  		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||

変更の背景

この変更は、OS X Mavericks (macOS 10.9) 以降のバージョンにおいて、Go言語のsyscallパッケージがRTF_BITSという定数を正しく生成できなくなった、あるいは生成する必要がなくなったことに対応するためのものです。

mkerrors.shスクリプトは、C言語のヘッダーファイルを解析してGo言語の定数を生成しますが、OSのバージョンアップに伴い、ヘッダーファイルの構造や定数の定義方法が変更されることがあります。RTF_BITSはルーティングテーブルのフラグに関連する定数であり、OS X Mavericksでその定義が変更されたか、あるいはGoが利用するCヘッダーからアクセスできなくなった可能性があります。

このような状況でmkerrors.shRTF_BITSを無理に生成しようとすると、ビルドエラーや不正な定数値の生成につながる恐れがあります。そのため、Mavericks以降のOS X環境では、この定数の生成を明示的にスキップするよう修正されました。これにより、Goのsyscallパッケージが新しいOSバージョンでも安定して動作することが保証されます。

前提知識の解説

Go言語のsyscallパッケージ

syscallパッケージは、Goプログラムがオペレーティングシステムが提供する低レベルの機能(システムコール)にアクセスするためのインターフェースを提供します。ファイル操作、ネットワーク通信、プロセス管理など、OSと直接やり取りする多くの機能はシステムコールを通じて実現されます。Go言語はクロスプラットフォーム対応ですが、システムコールの詳細はOSによって異なるため、syscallパッケージは各OSの特性を吸収し、Goプログラムから統一的にシステムコールを呼び出せるように抽象化しています。

mkerrors.shスクリプト

mkerrors.shは、Goのsyscallパッケージのビルドプロセスの一部として実行されるシェルスクリプトです。このスクリプトの主な役割は以下の通りです。

  1. Cヘッダーファイルの解析: 各OSのC言語ヘッダーファイル(例: /usr/include/sys/socket.h, /usr/include/net/route.hなど)を読み込みます。
  2. 定数の抽出: ヘッダーファイル内に定義されている#defineなどのプリプロセッサディレクティブから、システムコールに関連する定数(エラーコード、フラグ、構造体オフセットなど)を正規表現などを用いて抽出します。
  3. Goコードの生成: 抽出した定数をGo言語の構文に変換し、zerrors_*.gozsysnum_*.goといったGoソースファイルとして自動生成します。これらのファイルはsyscallパッケージの一部としてコンパイルされ、GoプログラムからOS固有の定数を利用できるようにします。

この自動生成プロセスにより、Go開発者はOSごとの定数の違いを意識することなく、高レベルなAPIを通じてシステムコールを扱うことができます。

RTF_BITS定数

RTF_BITSは、ネットワークルーティングテーブルのエントリに関連するフラグのビットマスクを定義する定数です。ルーティングテーブルは、ネットワークパケットがどこに送られるべきかを決定するためにOSが使用する情報源です。各ルーティングエントリには、そのルートの特性を示す様々なフラグが関連付けられています。

例えば、以下のようなフラグがあります(これらはRTF_BITSの一部を構成する可能性のある個別のフラグです):

  • RTF_UP: ルートが有効であること。
  • RTF_GATEWAY: 宛先への到達にゲートウェイが必要であること。
  • RTF_HOST: 宛先がネットワークではなく特定のホストであること。
  • RTF_STATIC: ルートが静的に(手動で)追加されたものであること。
  • RTF_DYNAMIC: ルートが動的に(例: リダイレクトによって)追加されたものであること。

RTF_BITSは、これらの個々のフラグをまとめて表現するためのビットマスク、あるいはそれらのフラグの集合を扱うためのメタ定数として機能します。OS X Mavericksにおいて、この定数の定義方法や、mkerrors.shが解析するCヘッダーファイル内での表現に何らかの変更があったため、Goのビルドプロセスで問題が生じたと考えられます。

OS X Mavericks (macOS 10.9)

OS X Mavericksは、2013年10月にリリースされたAppleのデスクトップオペレーティングシステムです。このバージョンでは、内部的なカーネルやシステムライブラリに多くの変更が加えられました。Go言語のような低レベルのシステムコールに依存するソフトウェアは、OSのこのような内部変更に敏感であり、互換性を維持するために調整が必要となることがあります。

技術的詳細

このコミットの技術的詳細を理解するためには、mkerrors.shスクリプトがどのように定数を抽出しているか、そして追加された正規表現の条件が何を意味するのかを深く掘り下げる必要があります。

mkerrors.shスクリプトは、grepsedといった標準的なUnixコマンドと正規表現を組み合わせて、Cヘッダーファイルから特定のパターンにマッチする行を抽出し、Go言語の定数定義に変換します。スクリプトの関連部分(変更前の269行目付近)は、以下のような論理構造を持っています。

# ...
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
$2 ~ /^SIOC/ ||
$2 ~ /^TIOC/ ||
$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
$2 ~ /^BIOC/ ||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
# ...

ここで $2 は、スクリプトが処理しているCヘッダーファイルから抽出された定数名(例: RTF_BITS)を表します。このコードは、|| (OR) 演算子で結合された複数の正規表現パターンを使用して、Goに含めるべき定数をフィルタリングしています。つまり、定数名がこれらのいずれかのパターンにマッチすれば、その定数はGoコードとして生成されます。

変更前は、RTF_BITSという定数名が、例えば $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ のパターン(特にRTF_で始まる定数にマッチする部分)に合致していたため、Goコードとして生成されていました。

このコミットで追加された行は以下の通りです。

--- a/src/pkg/syscall/mkerrors.sh
+++ b/src/pkg/syscall/mkerrors.sh
@@ -269,6 +269,7 @@ ccflags="$@"
  		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
  		$2 ~ /^SIOC/ ||
  		$2 ~ /^TIOC/ ||
+\t\t$2 !~ "RTF_BITS" &&
  		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
  		$2 ~ /^BIOC/ ||
  		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||

追加された行は \t\t$2 !~ "RTF_BITS" && です。

  • $2 !~ "RTF_BITS": これは、定数名($2)が文字列 "RTF_BITS" にマッチしない場合に真となる条件です。つまり、RTF_BITSという名前の定数は除外されます。
  • &&: これは論理AND演算子です。この条件が追加されたことで、以前の行の正規表現マッチングの結果と、RTF_BITSではないという条件の両方が真である場合にのみ、定数がGoコードとして生成されるようになりました。

この変更は、OS X Mavericks以降の環境でRTF_BITSの定義がGoのmkerrors.shスクリプトにとって問題となったため、その定数を明示的に生成対象から除外することで問題を回避しています。具体的な問題としては、以下のような可能性が考えられます。

  1. 定義の変更: RTF_BITSの定義がCヘッダーファイル内で変更され、mkerrors.shの既存の正規表現が正しく解析できなくなった。
  2. 値の変更: RTF_BITSの値が、Goのsyscallパッケージが期待する形式と異なるようになった。
  3. 非推奨化/削除: RTF_BITSが非推奨になったか、あるいは完全に削除された。しかし、他の関連するRTF_プレフィックスを持つ定数は依然として存在するため、広範な正規表現を変更するよりも、特定のRTF_BITSのみを除外する方が安全かつ効率的だった。

この修正により、GoのビルドシステムはOS X Mavericks以降の環境でRTF_BITSに関連するエラーを回避し、syscallパッケージの安定性を維持できるようになりました。

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

src/pkg/syscall/mkerrors.shファイルの270行目に以下の行が追加されました。

--- a/src/pkg/syscall/mkerrors.sh
+++ b/src/pkg/syscall/mkerrors.sh
@@ -269,6 +269,7 @@ ccflags="$@"
  		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
  		$2 ~ /^SIOC/ ||
  		$2 ~ /^TIOC/ ||
+\t\t$2 !~ "RTF_BITS" &&
  		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
  		$2 ~ /^BIOC/ ||
  		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||

コアとなるコードの解説

追加された行 \t\t$2 !~ "RTF_BITS" && は、mkerrors.shスクリプトがGo言語の定数を生成する際のフィルタリングロジックを修正しています。

このスクリプトは、Cヘッダーファイルから抽出された定数名(シェルスクリプトの変数$2に格納される)が、Goコードとして生成すべき対象であるかどうかを複数の正規表現パターンでチェックしています。これらのパターンは論理OR (||) で結合されており、いずれか一つにマッチすれば定数は採用されます。

追加された行は、既存の正規表現パターン群の途中に挿入され、論理AND (&&) で結合されています。これにより、以下の条件が課せられます。

  1. 既存のパターンにマッチすること: 例えば、RTF_BITSは以前から$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/というパターンにマッチしていました。
  2. かつ、RTF_BITSではないこと: 新しく追加された $2 !~ "RTF_BITS" という条件により、定数名が厳密に"RTF_BITS"である場合は、たとえ他のパターンにマッチしても除外されるようになりました。

つまり、この変更は「RTF_で始まるルーティング関連の定数は通常通り生成するが、その中でも特にRTF_BITSという名前の定数だけは生成しない」という明確な指示をスクリプトに与えています。これは、OS X Mavericks以降の環境でRTF_BITSの定義がGoのビルドプロセスにとって問題を引き起こすようになったため、その特定の定数のみをピンポイントで除外するための、非常に的を絞った修正と言えます。

関連リンク

参考にした情報源リンク