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

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

このコミットは、Go言語のsyscallパッケージにおいて、Darwin (macOS) および FreeBSD オペレーティングシステム向けの自動生成ファイル(通称 z-files)を再生成したものです。これにより、これらのOSで利用可能な新しいシステムコール定数やエラー定数がGoのsyscallパッケージに適切に反映され、GoプログラムからこれらのOS固有の機能にアクセスできるようになります。

コミット

commit 0643aacee97359ba542a4b0e4600a0d029fe1c79
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Dec 13 10:27:23 2011 +0900

    syscall: regenerate z-files for darwin, freebsd

    R=golang-dev, jsing, rsc
    CC=golang-dev
    https://golang.org/cl/5479054

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

https://github.com/golang/go/commit/0643aacee97359ba542a4b0e4600a0d029fe1c79

元コミット内容

このコミットの元の内容は、GoのsyscallパッケージにおけるDarwin (macOS) および FreeBSD 用のz-filesを再生成することです。具体的には、以下のファイルが変更されています。

  • src/pkg/syscall/zerrors_darwin_386.go
  • src/pkg/syscall/zerrors_darwin_amd64.go
  • src/pkg/syscall/zerrors_freebsd_386.go
  • src/pkg/syscall/zerrors_freebsd_amd64.go
  • src/pkg/syscall/zsysnum_freebsd_386.go
  • src/pkg/syscall/zsysnum_freebsd_amd64.go

変更の主な内容は、新しい定数(F_OK, LOCK_*, RLIMIT_*, RUSAGE_*など)の追加と、FreeBSDにおけるシステムコール番号の定義の更新です。

変更の背景

Go言語のsyscallパッケージは、オペレーティングシステムが提供する低レベルなシステムコールへのインターフェースを提供します。これらのシステムコールは、ファイル操作、プロセス管理、ネットワーク通信など、OSの基本的な機能にアクセスするために使用されます。

syscallパッケージ内のz-files(例: zerrors_darwin_386.go, zsysnum_freebsd_amd64.goなど)は、C言語のヘッダーファイルから自動的に生成されるGoのソースファイルです。これらには、システムコール番号、エラーコード、フラグなどのOS固有の定数が定義されています。

このコミットの背景には、以下のいずれか、または複数の理由が考えられます。

  1. OSの更新: Darwin (macOS) や FreeBSD の新しいバージョンがリリースされ、新しいシステムコールや定数が導入されたため、Goのsyscallパッケージもそれらに対応する必要があった。
  2. 既存の定数の不足: 既存のz-filesに、Goプログラムから利用したいOS固有の重要な定数が含まれていなかったため、それらを追加する必要があった。
  3. 生成スクリプトの改善: z-filesを生成するスクリプトやツール(go tool cgo -godefsなど)が改善され、より多くの定数を自動的に取り込めるようになったため、再生成が行われた。
  4. バグ修正: 既存のz-filesに誤った定数定義や不足があったため、それを修正するために再生成が行われた。

このコミットメッセージからは「regenerate」という言葉が使われているため、既存の生成プロセスを再度実行し、最新のOSヘッダーファイルに基づいてGoの定数定義を更新したことが示唆されます。これにより、GoプログラムがこれらのOSの最新の機能や挙動に正確に対応できるようになります。

前提知識の解説

このコミットを理解するためには、以下の前提知識が役立ちます。

  1. システムコール (System Call): オペレーティングシステムが提供する、アプリケーションプログラムがOSのカーネル機能にアクセスするためのインターフェースです。ファイルI/O、メモリ管理、プロセス制御、ネットワーク通信など、OSの基本的な操作はシステムコールを通じて行われます。Go言語のsyscallパッケージは、これらのシステムコールをGoプログラムから呼び出すためのラッパーを提供します。

  2. Go言語の syscall パッケージ: Go標準ライブラリの一部であり、低レベルなOSプリミティブへのアクセスを提供します。このパッケージは、OS固有の定数(エラーコード、フラグ、システムコール番号など)や、システムコールを直接呼び出すための関数を含んでいます。異なるOSやアーキテクチャ(例: Linux/amd64, Darwin/386, FreeBSD/amd64)ごとに異なる実装を持ちます。

  3. z-files (Generated Files): Goのsyscallパッケージにおいて、zerrors_*.gozsysnum_*.goといったファイルは、C言語のヘッダーファイルから自動的に生成されます。これらのファイルは、OSのCヘッダーファイルに定義されている定数や構造体をGoのコードとして表現するために使用されます。生成にはgo tool cgo -godefsのようなツールが用いられます。これにより、手動でOS固有の定数をGoコードに移植する手間を省き、OSの変更に追従しやすくなります。

  4. ファイルアクセス権限とモード (File Access Permissions and Modes):

    • access()システムコール: ファイルやディレクトリへのアクセス権限(読み取り、書き込み、実行)を確認するために使用されます。
    • F_OK: access()システムコールで使用されるフラグの一つで、ファイルが存在するかどうかを確認します。
    • amode vs flags: access()システムコールの引数として、amodeはアクセスモード(例: R_OK, W_OK, X_OK, F_OK)を指定し、flagsはより一般的なフラグを指すことがあります。このコミットでは、access関連のシステムコールの引数名がflagsからamodeに修正されており、よりセマンティックな正確性を追求しています。
  5. ファイルロック (File Locking):

    • flock()システムコール: ファイル全体をロックするためのシステムコールです。複数のプロセスが同時にファイルにアクセスする際に、データの整合性を保つために使用されます。
    • LOCK_EX (Exclusive Lock): 排他ロック。他のプロセスからの読み書きを禁止します。
    • LOCK_SH (Shared Lock): 共有ロック。複数のプロセスが同時に読み取りアクセスすることを許可しますが、書き込みは禁止します。
    • LOCK_NB (Non-Blocking): ロックが取得できない場合にブロックせず、すぐにエラーを返します。
    • LOCK_UN (Unlock): ロックを解除します。
  6. リソース制限 (Resource Limits):

    • RLIMIT_*: プロセスが使用できるシステムリソース(CPU時間、ファイルサイズ、オープンできるファイルの数など)の上限を定義する定数です。
    • RLIM_INFINITY: リソース制限がないことを示す値です。
    • getrlimit()/setrlimit()システムコール: プロセスのリソース制限を取得/設定するために使用されます。
  7. リソース使用量 (Resource Usage):

    • RUSAGE_SELF: 現在のプロセスのリソース使用量を取得するためのフラグです。
    • RUSAGE_CHILDREN: 子プロセスのリソース使用量を取得するためのフラグです。
    • getrusage()システムコール: プロセスやその子プロセスのCPU時間、メモリ使用量などのリソース使用量を取得するために使用されます。
  8. FreeBSDのffclock: ffclock (Fast Forward Clock) は、FreeBSDで導入された高精度な時間計測メカニズムです。通常のシステムクロックよりも高速かつ正確な時間情報を提供することを目的としています。これは、特にネットワークアプリケーションやリアルタイムシステムにおいて、より正確なタイムスタンプや時間同期が必要な場合に有用です。

    • SYS_FFCLOCK_GETCOUNTER: ffclockのカウンタ値を取得するシステムコール。
    • SYS_FFCLOCK_SETESTIMATE: ffclockの推定値を設定するシステムコール。
    • SYS_FFCLOCK_GETESTIMATE: ffclockの推定値を取得するシステムコール。

これらの知識は、GoのsyscallパッケージがどのようにOSと連携し、低レベルな機能を提供しているかを理解する上で不可欠です。

技術的詳細

このコミットは、Goのsyscallパッケージが特定のOS(DarwinとFreeBSD)のシステムコールインターフェースをどのように反映しているかを示す良い例です。

z-filesの再生成は、通常、以下のプロセスで行われます。

  1. Cヘッダーファイルの解析: go tool cgo -godefsのようなツールが、ターゲットOSのC言語ヘッダーファイル(例: /usr/include/sys/errno.h, /usr/include/sys/fcntl.h, /usr/include/sys/resource.hなど)を読み込みます。
  2. Goコードへの変換: 解析された情報に基づいて、Cの定数、構造体、関数プロトタイプがGoの対応する型や定数に変換されます。例えば、Cの#define F_OK 0x0はGoのconst F_OK = 0x0に変換されます。
  3. Goソースファイルの生成: 変換されたGoコードが、zerrors_*.gozsysnum_*.goといったファイルとして出力されます。

このコミットでは、特に以下の技術的詳細が注目されます。

  • 定数の追加:

    • F_OK: access()システムコールでファイルの存在チェックを行うための重要な定数です。これがGoのsyscallパッケージにない場合、Goプログラムからファイルの存在を効率的にチェックすることが困難になります。
    • LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN: flock()システムコールを用いたファイルロック機能は、複数のプロセス間でファイルを安全に共有するために不可欠です。これらの定数が追加されることで、GoプログラムからOSレベルのファイルロックを細かく制御できるようになります。
    • RLIMIT_*, RLIM_INFINITY: プロセスのリソース使用量を管理するための定数です。これにより、Goプログラムは自身の(または他のプロセスの)リソース制限を照会したり、設定したりすることが可能になります。これは、システムリソースの枯渇を防ぐためや、特定のアプリケーションの動作を制限するために重要です。
    • RUSAGE_CHILDREN, RUSAGE_SELF: プロセスとその子プロセスのリソース使用量を詳細に取得するための定数です。パフォーマンス監視やデバッグにおいて有用です。
  • システムコール番号の更新 (FreeBSD):

    • SYS_ACCESS, SYS_EACCESS, SYS_FACCESSATのコメント修正: これらのシステムコールの引数名がflagsからamodeに修正されています。これは、C言語の標準的な定義に合わせて、引数の意味をより正確に反映させるための変更です。amodeはアクセスモード(読み取り、書き込み、実行、存在チェック)を意味し、flagsよりも具体的な用途を示します。
    • SYS_FFCLOCK_GETCOUNTER, SYS_FFCLOCK_SETESTIMATE, SYS_FFCLOCK_GETESTIMATEの追加: FreeBSD固有のffclockシステムコールがGoのsyscallパッケージに追加されたことを示します。これにより、GoプログラムはFreeBSD上で高精度な時間計測機能を利用できるようになります。これは、特に低レイテンシが要求されるアプリケーションや、正確なタイムスタンプが必要なシステムで重要です。

これらの変更は、GoのsyscallパッケージがOSの進化に追従し、Go開発者がより広範なOS機能にアクセスできるようにするための継続的な努力の一部です。自動生成プロセスは、このようなOS固有の変更を効率的に取り込むための鍵となります。

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

このコミットにおけるコアとなるコードの変更箇所は、以下のzerrors_*.goファイルとzsysnum_*.goファイルへの定数追加およびコメント修正です。

src/pkg/syscall/zerrors_darwin_386.go および src/pkg/syscall/zerrors_darwin_amd64.go:

--- a/src/pkg/syscall/zerrors_darwin_386.go
+++ b/src/pkg/syscall/zerrors_darwin_386.go
@@ -211,6 +211,7 @@ const (
 	F_MARKDEPENDENCY            = 0x3c
 	F_NOCACHE                   = 0x30
 	F_NODIRECT                  = 0x3e
+	F_OK                        = 0x0 // 追加
 	F_PATHPKG_CHECK             = 0x34
 	F_PEOFPOSMODE               = 0x3
 	F_PREALLOCATE               = 0x2a
@@ -559,6 +560,10 @@ const (
 	IP_TRAFFIC_MGT_BACKGROUND   = 0x41
 	IP_TTL                      = 0x4
 	IP_UNBLOCK_SOURCE           = 0x49
+	LOCK_EX                     = 0x2 // 追加
+	LOCK_NB                     = 0x4 // 追加
+	LOCK_SH                     = 0x1 // 追加
+	LOCK_UN                     = 0x8 // 追加
 	MADV_CAN_REUSE              = 0x9
 	MADV_DONTNEED               = 0x4
 	MADV_FREE                   = 0x5
@@ -660,6 +665,14 @@ const (
 	PT_WRITE_D                  = 0x5
 	PT_WRITE_I                  = 0x4
 	PT_WRITE_U                  = 0x6
+	RLIMIT_AS                   = 0x5 // 追加
+	RLIMIT_CORE                 = 0x4 // 追加
+	RLIMIT_CPU                  = 0x0 // 追加
+	RLIMIT_DATA                 = 0x2 // 追加
+	RLIMIT_FSIZE                = 0x1 // 追加
+	RLIMIT_NOFILE               = 0x8 // 追加
+	RLIMIT_STACK                = 0x3 // 追加
+	RLIM_INFINITY               = 0x7fffffffffffffff // 追加
 	RTAX_AUTHOR                 = 0x6
 	RTAX_BRD                    = 0x7
 	RTAX_DST                    = 0x0
@@ -731,6 +744,8 @@ const (
 	RTV_RTTVAR                  = 0x80
 	RTV_SPIPE                   = 0x10
 	RTV_SSTHRESH                = 0x20
+	RUSAGE_CHILDREN             = -0x1 // 追加
+	RUSAGE_SELF                 = 0x0 // 追加
 	SCM_CREDS                   = 0x3
 	SCM_RIGHTS                  = 0x1
 	SCM_TIMESTAMP               = 0x2

src/pkg/syscall/zerrors_freebsd_386.go および src/pkg/syscall/zerrors_freebsd_amd64.go:

--- a/src/pkg/syscall/zerrors_freebsd_386.go
+++ b/src/pkg/syscall/zerrors_freebsd_386.go
@@ -354,6 +354,7 @@ const (
 	F_GETLK                           = 0xb
 	F_GETOWN                          = 0x5
 	F_OGETLK                          = 0x7
+	F_OK                              = 0x0 // 追加
 	F_OSETLK                          = 0x8
 	F_OSETLKW                         = 0x9
 	F_RDAHEAD                         = 0x10
@@ -864,6 +865,10 @@ const (
 	IP_TOS                            = 0x3
 	IP_TTL                            = 0x4
 	IP_UNBLOCK_SOURCE                 = 0x49
+	LOCK_EX                           = 0x2 // 追加
+	LOCK_NB                           = 0x4 // 追加
+	LOCK_SH                           = 0x1 // 追加
+	LOCK_UN                           = 0x8 // 追加
 	MSG_COMPAT                        = 0x8000
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4

src/pkg/syscall/zsysnum_freebsd_386.go および src/pkg/syscall/zsysnum_freebsd_amd64.go:

--- a/src/pkg/syscall/zsysnum_freebsd_386.go
+++ b/src/pkg/syscall/zsysnum_freebsd_386.go
@@ -33,7 +33,7 @@ const (
 	SYS_ACCEPT                   = 30  // { int accept(int s, \
 	SYS_GETPEERNAME              = 31  // { int getpeername(int fdes, \
 	SYS_GETSOCKNAME              = 32  // { int getsockname(int fdes, \
-	SYS_ACCESS                   = 33  // { int access(char *path, int flags); } // コメント修正
+	SYS_ACCESS                   = 33  // { int access(char *path, int amode); } // コメント修正
 	SYS_CHFLAGS                  = 34  // { int chflags(char *path, int flags); }
 	SYS_FCHFLAGS                 = 35  // { int fchflags(int fd, int flags); }
 	SYS_SYNC                     = 36  // { int sync(void); }
@@ -146,6 +146,9 @@ const (
 	SYS_KTIMER_GETTIME           = 238 // { int ktimer_gettime(int timerid, struct \
 	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
 	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, \
+	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); } // 追加
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( \ // 追加
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( \ // 追加
 	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
 	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, \
 	SYS_RFORK                    = 251 // { int rfork(int flags); }
@@ -215,7 +218,7 @@ const (
 	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, \
 	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, \
 	SYS___SETUGID                = 374 // { int __setugid(int flag); }
-	SYS_EACCESS                  = 376 // { int eaccess(char *path, int flags); } // コメント修正
+	SYS_EACCESS                  = 376 // { int eaccess(char *path, int amode); } // コメント修正
 	SYS_NMOUNT                   = 378 // { int nmount(struct iovec *iovp, \
 	SYS___MAC_GET_PROC           = 384 // { int __mac_get_proc(struct mac *mac_p); }
 	SYS___MAC_SET_PROC           = 385 // { int __mac_set_proc(struct mac *mac_p); }
@@ -296,7 +299,7 @@ const (
 	SYS_CPUSET_GETID             = 486 // { int cpuset_getid(cpulevel_t level, \
 	SYS_CPUSET_GETAFFINITY       = 487 // { int cpuset_getaffinity(cpulevel_t level, \
 	SYS_CPUSET_SETAFFINITY       = 488 // { int cpuset_setaffinity(cpulevel_t level, \
-	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int mode, \ // コメント修正
+	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int amode, \ // コメント修正
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \

コアとなるコードの解説

上記のコード変更は、GoのsyscallパッケージがOSの低レベルな機能とどのように連携するかを具体的に示しています。

  1. zerrors_darwin_*.go および zerrors_freebsd_*.go の変更: これらのファイルは、OS固有のエラーコードやフラグなどの定数を定義しています。追加された定数は以下の通りです。

    • F_OK: access()システムコールで使用されるファイル存在チェックのフラグです。Goプログラムがファイルやディレクトリの存在を効率的に確認できるようになります。
    • LOCK_EX, LOCK_NB, LOCK_SH, LOCK_UN: flock()システムコールで使用されるファイルロックのタイプとオプションです。これにより、Goプログラムはファイルに対する排他ロック、共有ロック、非ブロックロック、ロック解除といった操作を直接行えるようになり、複数のプロセス間でのファイルアクセス競合を適切に管理できます。
    • RLIMIT_*, RLIM_INFINITY: プロセスのリソース制限に関する定数です。Goプログラムは、CPU時間、ファイルサイズ、オープンできるファイルディスクリプタの数などのリソース制限を、OSが提供するgetrlimit()setrlimit()システムコールを通じて操作できるようになります。RLIM_INFINITYは、特定のリソースに制限がないことを示します。
    • RUSAGE_CHILDREN, RUSAGE_SELF: getrusage()システムコールで使用される、リソース使用量を取得する対象を指定する定数です。RUSAGE_SELFは現在のプロセスのリソース使用量を、RUSAGE_CHILDRENはその子プロセスのリソース使用量を意味します。これにより、Goプログラムは自身の、または子プロセスのリソース消費状況を詳細に監視できます。
  2. zsysnum_freebsd_*.go の変更: このファイルは、FreeBSDにおけるシステムコール番号と、そのC言語での関数プロトタイプを定義しています。

    • SYS_ACCESS, SYS_EACCESS, SYS_FACCESSATのコメント修正: これらのシステムコールはファイルアクセス権限のチェックに関連します。元のコメントでは引数名がflagsとなっていましたが、より正確なamode(access mode)に修正されました。これは、C言語のaccess(2)マニュアルページに記載されている引数名と一致させ、GoのバインディングがCのAPIをより正確に反映するようにするための変更です。
    • SYS_FFCLOCK_GETCOUNTER, SYS_FFCLOCK_SETESTIMATE, SYS_FFCLOCK_GETESTIMATEの追加: これらはFreeBSD固有のffclock(Fast Forward Clock)システムコールです。これらのシステムコールがGoのsyscallパッケージに追加されたことで、GoプログラムはFreeBSD上で高精度な時間計測機能を利用できるようになります。これは、特に時間精度が要求されるアプリケーションや、システム時刻の同期メカニズムを扱う際に重要です。

これらの変更は、GoのsyscallパッケージがOSの進化に追従し、Go開発者がより広範なOS固有の機能にアクセスできるようにするための重要なステップです。自動生成されたファイルであるため、これらの変更は手動で記述されたものではなく、OSのヘッダーファイルが更新された結果として、生成ツールによって自動的に取り込まれたものと考えられます。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • FreeBSDのmanページ
  • Darwin (macOS) の開発者ドキュメント
  • Go言語のソースコードリポジトリ (特にsrc/pkg/syscallディレクトリ)
  • Stack Overflowや技術ブログなど、GoのsyscallパッケージやOSのシステムコールに関する一般的な情報源。
  • Google検索 (ffclock freebsd, go syscall z-files, access system call amode flags)