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

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

このコミットは、Go言語のsyscallパッケージ内で使用されるmksysnum_dragonfly.plスクリプトの修正に関するものです。このスクリプトは、DragonFly BSDオペレーティングシステム向けのシステムコール番号を生成するために利用されます。

コミット

  • コミットハッシュ: b586f56e76f67bd482b51186bf45d6ada47421ad
  • 作者: Joel Sing jsing@google.com
  • 日付: 2014年3月6日 木曜日 00:08:34 +1100
  • コミットメッセージ:
    syscall: fix mksysnum_dragonfly.pl
    
    The format of the DragonFly BSD syscalls.master file has changed
    slightly - update mksysnum_dragonfly.pl to match.
    
    LGTM=mikioh.mikioh
    R=golang-codereviews, mikioh.mikioh
    CC=golang-codereviews
    https://golang.org/cl/71460044
    

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

https://github.com/golang/go/commit/b586f56e76f67bd482b51186bf45d6ada47421ad

元コミット内容

syscall: fix mksysnum_dragonfly.pl

The format of the DragonFly BSD syscalls.master file has changed
slightly - update mksysnum_dragonfly.pl to match.

LGTM=mikioh.mikioh
R=golang-codereviews, mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/71460044

変更の背景

このコミットの背景には、DragonFly BSDオペレーティングシステムのsyscalls.masterファイルのフォーマットがわずかに変更されたという事実があります。Go言語のsyscallパッケージは、各OSのシステムコールをGoプログラムから呼び出すためのインターフェースを提供しており、そのためにOS固有のシステムコール番号を正確に把握する必要があります。

mksysnum_dragonfly.plスクリプトは、DragonFly BSDのsyscalls.masterファイルを解析し、Go言語のソースコードに埋め込むためのシステムコール番号定数を生成する役割を担っています。syscalls.masterファイルのフォーマット変更により、既存のスクリプトでは正しくシステムコール情報を抽出できなくなり、GoがDragonFly BSD上でシステムコールを正しく扱えなくなる可能性が生じました。この問題を解決するために、スクリプトの正規表現を更新する必要がありました。

前提知識の解説

システムコール (System Call)

システムコールは、オペレーティングシステム (OS) のカーネルが提供するサービスを、ユーザー空間で動作するプログラムが利用するためのインターフェースです。ファイルI/O、メモリ管理、プロセス管理、ネットワーク通信など、OSの基本的な機能のほとんどはシステムコールを通じて提供されます。プログラムがこれらのサービスを利用する際には、対応するシステムコールを呼び出し、カーネルモードに切り替わって処理を実行します。各システムコールには一意の番号(システムコール番号)が割り当てられています。

DragonFly BSD

DragonFly BSDは、FreeBSD 4.8からフォークして開発されたオープンソースのUnix系オペレーティングシステムです。高性能でスケーラブルなシステムを目指しており、特にSMP (Symmetric Multi-Processing) 環境でのパフォーマンス向上に注力しています。独自のカーネル設計やファイルシステム(HAMMER)などの特徴を持っています。

syscalls.masterファイル

BSD系のOS(FreeBSD, OpenBSD, NetBSD, DragonFly BSDなど)では、システムコールの一覧とその定義がsyscalls.masterというファイルに記述されています。このファイルは、システムコール番号、システムコールの名前、引数の型と数、および関連する情報を含んでいます。OSのビルドプロセスにおいて、このファイルはシステムコールテーブルや関連するヘッダファイルを生成するために使用されます。Goのような言語が特定のOSのシステムコールをサポートするためには、このsyscalls.masterファイルから必要な情報を抽出し、言語固有の定数や関数にマッピングする必要があります。

mksysnum_dragonfly.plスクリプト

Go言語のソースツリー内にあるsrc/pkg/syscall/mksysnum_dragonfly.plは、Perlで書かれたスクリプトです。このスクリプトの目的は、DragonFly BSDのsyscalls.masterファイルを読み込み、そこからシステムコール番号とシステムコール名を抽出し、Go言語のsyscallパッケージが利用できる形式(Goの定数定義)で出力することです。これにより、GoプログラムはDragonFly BSDのシステムコールを、そのシステムコール番号を介して正しく呼び出すことができるようになります。

技術的詳細

このコミットの技術的な核心は、mksysnum_dragonfly.plスクリプト内の正規表現の変更です。syscalls.masterファイルのフォーマット変更により、システムコール定義行の構造がわずかに変わりました。

元の正規表現: /^([0-9]+)\s+STD\s+\S+\s+({ \S+\s+(\w+).*)$/

変更後の正規表現: /^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/

この変更は、正規表現の\S+\s+の部分が削除されたことにあります。

  • ^([0-9]+): 行の先頭から1つ以上の数字(システムコール番号)をキャプチャします。
  • \s+STD\s+: 1つ以上の空白文字、"STD"という文字列、1つ以上の空白文字にマッチします。"STD"は標準的なシステムコールを示すキーワードです。
  • 変更点:
    • 変更前: \S+\s+ がありました。これは「1つ以上の非空白文字」の後に「1つ以上の空白文字」が続くパターンにマッチします。これは、システムコール番号と"STD"の後に、何らかの識別子(例えば、システムコールの種類を示す短い文字列など)が追加されていたことを示唆します。
    • 変更後: \S+\s+ が削除されました。これは、syscalls.masterファイルにおいて、システムコール番号と"STD"の直後に、システムコールのプロトタイプ定義が続くようになったことを意味します。つまり、間に余分なフィールドがなくなったということです。
  • ({ \S+\s+(\w+).*)$: これはシステムコールのプロトタイプ定義全体をキャプチャします。
    • { : 波括弧と空白文字で始まる部分にマッチします。
    • \S+\s+: 1つ以上の非空白文字の後に1つ以上の空白文字が続く部分にマッチします。これは通常、戻り値の型や最初の引数の型に該当します。
    • (\w+): 1つ以上の単語文字(英数字とアンダースコア)をキャプチャします。これがシステムコールの名前(例: read, write)に該当し、$3で取得されます。
    • .*): その後続く任意の文字にマッチし、行の終わりまでをキャプチャします。

この正規表現の変更により、mksysnum_dragonfly.plは、DragonFly BSDの新しいsyscalls.masterファイルのフォーマットから、システムコール番号とシステムコール名を正しく抽出し、Go言語のsyscallパッケージが利用できるGoコードを生成できるようになりました。

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

--- a/src/pkg/syscall/mksysnum_dragonfly.pl
+++ b/src/pkg/syscall/mksysnum_dragonfly.pl
@@ -20,7 +20,7 @@ const (
 EOF
 
 while(<>){
-	if(/^([0-9]+)\\s+STD\\s+\\S+\\s+({ \\S+\\s+(\\w+).*)$/){\
+	if(/^([0-9]+)\\s+STD\\s+({ \\S+\\s+(\\w+).*)$/){\
 		my $num = $1;\
 		my $proto = $2;\
 		my $name = \"SYS_$3\";

コアとなるコードの解説

変更された行は、mksysnum_dragonfly.plスクリプト内でsyscalls.masterファイルの各行を解析するために使用される正規表現を定義しています。

元の正規表現: if(/^([0-9]+)\\s+STD\\s+\\S+\\s+({ \\S+\\s+(\\w+).*)$/)

この正規表現は、システムコール番号、STDキーワード、そしてその後に続く何らかの非空白文字のシーケンス(\S+)と空白文字(\s+)を期待していました。この\S+\s+の部分が、syscalls.masterファイルのフォーマット変更によって不要になった余分なフィールドに対応していました。

変更後の正規表現: if(/^([0-9]+)\\s+STD\\s+({ \\S+\\s+(\\w+).*)$/)

この変更では、\S+\s+が削除されました。これにより、正規表現はシステムコール番号とSTDキーワードの直後に、システムコールのプロトタイプ定義({ \S+\s+(\w+).*)が続くことを期待するようになります。

具体的には、syscalls.masterの行が例えば 123 STD SOME_OLD_FIELD { int sys_foo(void) } のような形式から、123 STD { int sys_foo(void) } のような形式に変わったことを意味します。この修正によって、スクリプトは新しいフォーマットの行を正しくパースし、システムコール番号($1)、プロトタイプ定義全体($2)、およびシステムコール名($3)を正確に抽出できるようになりました。これにより、GoのsyscallパッケージがDragonFly BSDのシステムコールを正しく利用するための基盤が維持されます。

関連リンク

参考にした情報源リンク