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

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

このコミットは、Go言語のsyscallパッケージにおけるBSD系OS(FreeBSD, NetBSD, OpenBSD)向けのKillシステムコール定義の変更に関するものです。具体的には、Kill関数のsignum引数の型がintからSignal型に変更されています。これは、os/signalパッケージの新しい設計との同期を図るための変更です。

コミット

commit adc1e0bcef9e7e4a7bf4fa6d5b83681d578b9e0f
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Feb 14 11:20:39 2012 +0900

    syscall: update BSD variants to sync with new os/signal
    
    R=golang-dev, adg
    CC=golang-dev
    https://golang.org/cl/5661051

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

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

元コミット内容

syscall: update BSD variants to sync with new os/signal

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/5661051

変更の背景

このコミットの背景には、Go言語の標準ライブラリにおけるシグナルハンドリングの改善と標準化があります。特に、os/signalパッケージが導入または改訂され、シグナルをより型安全かつGoらしい方法で扱うための新しいSignal型が定義されたことが挙げられます。

従来のシステムコールでは、シグナル番号は単なる整数型(int)として扱われていました。しかし、これにより、誤ったシグナル番号が渡された場合にコンパイル時エラーではなく実行時エラーとなる可能性がありました。また、シグナルに関するセマンティクスがint型だけでは表現しきれないという問題もありました。

新しいos/signalパッケージの導入により、シグナルはSignalという専用の型で表現されるようになりました。これにより、シグナルに関する操作がより明確になり、型チェックによる早期エラー検出が可能になります。この変更は、Go言語の設計思想である「型安全性」と「明確性」を追求する一環として行われました。

このコミットは、syscallパッケージがos/signalパッケージの新しいSignal型と整合性を持つようにするための同期作業であり、Go言語全体のシグナル処理の一貫性を保つことを目的としています。

前提知識の解説

1. システムコール (System Call)

システムコールは、オペレーティングシステム (OS) のカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。ファイル操作、プロセス管理、メモリ管理、ネットワーク通信など、OSの基本的な機能のほとんどはシステムコールを通じて提供されます。

Go言語のsyscallパッケージは、これらのOS固有のシステムコールをGoプログラムから直接呼び出すための機能を提供します。これにより、低レベルのOS機能にアクセスしたり、OS固有の動作を制御したりすることが可能になります。

2. シグナル (Signal)

シグナルは、Unix系OSにおいてプロセス間通信やイベント通知のために使用されるソフトウェア割り込みの一種です。例えば、Ctrl+Cを押すとSIGINTシグナルがプロセスに送られ、プロセスは通常終了します。他にも、子プロセスの終了を通知するSIGCHLD、セグメンテーション違反を通知するSIGSEGVなど、様々なシグナルが存在します。

シグナルは、プロセスに対して特定のイベントが発生したことを通知し、それに応じてプロセスが特定の動作(シグナルハンドラの実行、プロセスの終了など)を行うように促します。

3. Killシステムコール

Killシステムコールは、指定されたプロセスID (PID) に対して特定のシグナルを送信するために使用されます。関数の基本的な形式は以下のようになります。

int kill(pid_t pid, int sig);
  • pid: シグナルを送信する対象のプロセスID。
  • sig: 送信するシグナル番号。

このシステムコールは、プロセスを終了させるだけでなく、特定のシグナルを送信してプロセスの動作を制御するためにも使用されます。

4. Go言語のos/signalパッケージ

os/signalパッケージは、GoプログラムがOSからのシグナルを処理するための機能を提供します。このパッケージを使用することで、特定のシグナルを受信した際にカスタムの処理を実行したり、シグナルを無視したりすることができます。

このコミットが行われた時期(2012年頃)に、os/signalパッケージはシグナルをよりGoらしい方法で扱うためのSignal型を導入しました。このSignal型は、OS固有のシグナル番号を抽象化し、Goプログラム内でシグナルをより安全かつ明確に扱うことを可能にします。

5. //sys および //sysnb コメント

Go言語のsyscallパッケージのソースコードには、//sys//sysnbといった特殊なコメントが頻繁に見られます。これらは、Goのツールチェーンがシステムコールを自動生成するために使用するディレクティブです。

  • //sys: 通常のシステムコールを生成することを示します。
  • //sysnb: "no blocking" の略で、ノンブロッキングなシステムコールを生成することを示します。これは、Goのランタイムがシステムコール中に他のゴルーチンをスケジュールできるようにするために重要です。

これらのコメントは、Goのビルドプロセスにおいて、C言語のシステムコール定義からGoの関数シグネチャを自動的に生成するために利用されます。

技術的詳細

このコミットの技術的な詳細を掘り下げると、Go言語のクロスプラットフォーム対応と、型安全性の追求という2つの側面が見えてきます。

Go言語は、様々なOS上で動作するように設計されており、それぞれのOSが提供するシステムコールを抽象化して利用できるようにsyscallパッケージを提供しています。しかし、OSによってシステムコールのシグネチャやセマンティクスが微妙に異なる場合があります。このため、syscallパッケージ内では、各OS向けのファイル(例: syscall_freebsd.go, syscall_netbsd.go, syscall_openbsd.go)にOS固有の実装が記述されています。

このコミットでは、BSD系のOS(FreeBSD, NetBSD, OpenBSD)におけるKillシステムコールのGo言語ラッパーの定義が変更されています。具体的には、Kill関数の2番目の引数であるsignumの型がintからSignalに変更されました。

--- a/src/pkg/syscall/syscall_freebsd.go
+++ b/src/pkg/syscall/syscall_freebsd.go
@@ -146,7 +146,7 @@ func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
 //sysnb	Gettimeofday(tv *Timeval) (err error)
 //sysnb	Getuid() (uid int)
 //sys	Issetugid() (tainted bool)
-//sys	Kill(pid int, signum int) (err error)
+//sys	Kill(pid int, signum Signal) (err error)
 //sys	Kqueue() (fd int, err error)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)

この変更は、os/signalパッケージで定義された新しいSignal型との整合性を保つために行われました。Signal型は、Go言語の内部でシグナルを表現するためのカスタム型であり、これによりシグナルに関する操作がより型安全になります。例えば、os.Interruptos.Killといった定数がSignal型として提供され、これらをKill関数に直接渡すことができるようになります。

この変更のメリットは以下の通りです。

  1. 型安全性: int型では任意の整数値をシグナル番号として渡せてしまいますが、Signal型を使用することで、Goコンパイラが不正なシグナル番号の利用を検出できるようになります。これにより、実行時エラーのリスクが低減します。
  2. コードの可読性: Signal型を使用することで、コードを読む人がその引数がシグナル番号であることをより明確に理解できます。
  3. 一貫性: os/signalパッケージとsyscallパッケージの間でシグナル表現の一貫性が保たれ、Go言語全体でのシグナル処理の設計がより統一されます。

この変更は、Go言語が初期の段階から、低レベルのシステムプログラミングにおいても高いレベルの安全性と使いやすさを追求していたことを示しています。

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

変更は以下の3つのファイルにわたっています。

  • src/pkg/syscall/syscall_freebsd.go
  • src/pkg/syscall/syscall_netbsd.go
  • src/pkg/syscall/syscall_openbsd.go

それぞれのファイルで、Killシステムコールの定義行が変更されています。

--- a/src/pkg/syscall/syscall_freebsd.go
+++ b/src/pkg/syscall/syscall_freebsd.go
@@ -146,7 +146,7 @@ func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
 //sysnb	Gettimeofday(tv *Timeval) (err error)
 //sysnb	Getuid() (uid int)
 //sys	Issetugid() (tainted bool)
-//sys	Kill(pid int, signum int) (err error)
+//sys	Kill(pid int, signum Signal) (err error)
 //sys	Kqueue() (fd int, err error)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)

他の2つのファイル(syscall_netbsd.gosyscall_openbsd.go)も同様の変更が加えられています。

コアとなるコードの解説

変更された行は、GoのsyscallパッケージがOSのシステムコールをGoの関数として公開するための特殊なコメント構文を使用しています。

元の行: //sys Kill(pid int, signum int) (err error)

変更後の行: //sys Kill(pid int, signum Signal) (err error)

この//sysコメントは、Goのビルドツールがこの行を解析し、対応するGoの関数シグネチャを自動的に生成するために使用されます。

  • //sys: これは、この行がシステムコール定義であることを示すディレクティブです。
  • Kill: 生成されるGo関数の名前です。
  • (pid int, signum int): 生成されるGo関数の引数リストです。
    • pid int: プロセスIDを表すint型の引数。
    • signum int (変更前): シグナル番号を表すint型の引数。
    • signum Signal (変更後): シグナル番号を表すSignal型の引数。
  • (err error): 生成されるGo関数の戻り値リストです。システムコールがエラーを返す可能性があるため、通常はerror型が含まれます。

この変更により、Goのsyscall.Kill関数を呼び出す際に、signum引数としてint型ではなくos/signalパッケージで定義されたSignal型を渡すことが必須となります。これにより、Goコンパイラが型チェックを行い、不正なシグナル番号の利用を早期に検出できるようになります。

例えば、変更前は以下のようなコードがコンパイルできてしまいましたが、シグナル番号として意味のない値が渡される可能性がありました。

// 変更前 (概念的なコード)
syscall.Kill(1234, 999) // 999は有効なシグナル番号ではないかもしれない

変更後は、Signal型を使用することで、より安全な呼び出しが強制されます。

// 変更後 (概念的なコード)
import "os"
import "syscall"

syscall.Kill(1234, os.Interrupt) // os.Interrupt は Signal 型
// syscall.Kill(1234, 999) // これはコンパイルエラーになる

この変更は、Go言語の標準ライブラリが、低レベルのOSインターフェースを扱いながらも、Go言語の型システムを活用して堅牢性と安全性を高める努力の一端を示しています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Unix系OSのシグナルに関する一般的な情報源 (例: man 7 signal, man 2 kill)
  • Go言語のソースコードリポジトリ (特にsrc/pkg/syscallディレクトリ)
  • Go言語のコミット履歴とChange List (CL) の議論
  • Go言語の設計に関するブログ記事や議論(当時の情報)

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

このコミットは、Go言語のsyscallパッケージにおけるBSD系OS(FreeBSD, NetBSD, OpenBSD)向けのKillシステムコール定義の変更に関するものです。具体的には、Kill関数のsignum引数の型がintからSignal型に変更されています。これは、os/signalパッケージの新しい設計との同期を図るための変更です。

コミット

commit adc1e0bcef9e7e4a7bf4fa6d5b83681d578b9e0f
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Feb 14 11:20:39 2012 +0900

    syscall: update BSD variants to sync with new os/signal
    
    R=golang-dev, adg
    CC=golang-dev
    https://golang.org/cl/5661051

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

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

元コミット内容

syscall: update BSD variants to sync with new os/signal

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/5661051

変更の背景

このコミットの背景には、Go言語の標準ライブラリにおけるシグナルハンドリングの改善と標準化があります。特に、Go 1のリリース時期(2012年頃)にos/signalパッケージが改訂され、シグナルをより型安全かつGoらしい方法で扱うための新しいSignal型が導入されたことが挙げられます。

従来のシステムコールでは、シグナル番号は単なる整数型(int)として扱われていました。しかし、これにより、誤ったシグナル番号が渡された場合にコンパイル時エラーではなく実行時エラーとなる可能性がありました。また、シグナルに関するセマンティクスがint型だけでは表現しきれないという問題もありました。

Web検索の結果によると、2012年頃のos/signalパッケージの変更では、signal.Notify関数がシグナル受信の主要なメカニズムとして導入され、chan os.Signal型のチャネルを通じてシグナルが通知されるようになりました。このos.Signal型自体はインターフェースであり、syscall.SIGINTsyscall.SIGTERMのような具体的なシグナル値がこのインターフェースを満たす形でチャネルに送られます。

この変更により、シグナルはSignalという専用の型(またはインターフェース)で表現されるようになりました。これにより、シグナルに関する操作がより明確になり、型チェックによる早期エラー検出が可能になります。この変更は、Go言語の設計思想である「型安全性」と「明確性」を追求する一環として行われました。

このコミットは、syscallパッケージがos/signalパッケージの新しいSignal型と整合性を持つようにするための同期作業であり、Go言語全体のシグナル処理の一貫性を保つことを目的としています。これにより、GoのプログラムがOSシグナルを扱う際に、より統一された、Goらしいアプローチが提供されることになります。

前提知識の解説

1. システムコール (System Call)

システムコールは、オペレーティングシステム (OS) のカーネルが提供するサービスを、ユーザー空間のプログラムが利用するためのインターフェースです。ファイル操作、プロセス管理、メモリ管理、ネットワーク通信など、OSの基本的な機能のほとんどはシステムコールを通じて提供されます。

Go言語のsyscallパッケージは、これらのOS固有のシステムコールをGoプログラムから直接呼び出すための機能を提供します。これにより、低レベルのOS機能にアクセスしたり、OS固有の動作を制御したりすることが可能になります。

2. シグナル (Signal)

シグナルは、Unix系OSにおいてプロセス間通信やイベント通知のために使用されるソフトウェア割り込みの一種です。例えば、Ctrl+Cを押すとSIGINTシグナルがプロセスに送られ、プロセスは通常終了します。他にも、子プロセスの終了を通知するSIGCHLD、セグメンテーション違反を通知するSIGSEGVなど、様々なシグナルが存在します。

シグナルは、プロセスに対して特定のイベントが発生したことを通知し、それに応じてプロセスが特定の動作(シグナルハンドラの実行、プロセスの終了など)を行うように促します。

3. Killシステムコール

Killシステムコールは、指定されたプロセスID (PID) に対して特定のシグナルを送信するために使用されます。関数の基本的な形式は以下のようになります。

int kill(pid_t pid, int sig);
  • pid: シグナルを送信する対象のプロセスID。
  • sig: 送信するシグナル番号。

このシステムコールは、プロセスを終了させるだけでなく、特定のシグナルを送信してプロセスの動作を制御するためにも使用されます。

4. Go言語のos/signalパッケージとSignal

os/signalパッケージは、GoプログラムがOSからのシグナルを処理するための機能を提供します。このパッケージを使用することで、特定のシグナルを受信した際にカスタムの処理を実行したり、シグナルを無視したりすることができます。

このコミットが行われた時期(2012年頃)に、os/signalパッケージはシグナルをよりGoらしい方法で扱うためのSignal型を導入しました。このSignal型は、OS固有のシグナル番号を抽象化し、Goプログラム内でシグナルをより安全かつ明確に扱うことを可能にします。具体的には、os.Signalはインターフェースとして定義され、syscallパッケージ内の具体的なシグナル定数(例: syscall.SIGINT)がこのインターフェースを実装します。これにより、Goの型システムを活用してシグナルを扱う際の堅牢性が向上しました。

5. //sys および //sysnb コメント

Go言語のsyscallパッケージのソースコードには、//sys//sysnbといった特殊なコメントが頻繁に見られます。これらは、Goのツールチェーンがシステムコールを自動生成するために使用するディレクティブです。

  • //sys: 通常のシステムコールを生成することを示します。
  • //sysnb: "no blocking" の略で、ノンブロッキングなシステムコールを生成することを示します。これは、Goのランタイムがシステムコール中に他のゴルーチンをスケジュールできるようにするために重要です。

これらのコメントは、Goのビルドプロセスにおいて、C言語のシステムコール定義からGoの関数シグネチャを自動的に生成するために利用されます。

技術的詳細

このコミットの技術的な詳細を掘り下げると、Go言語のクロスプラットフォーム対応と、型安全性の追求という2つの側面が見えてきます。

Go言語は、様々なOS上で動作するように設計されており、それぞれのOSが提供するシステムコールを抽象化して利用できるようにsyscallパッケージを提供しています。しかし、OSによってシステムコールのシグネチャやセマンティクスが微妙に異なる場合があります。このため、syscallパッケージ内では、各OS向けのファイル(例: syscall_freebsd.go, syscall_netbsd.go, syscall_openbsd.go)にOS固有の実装が記述されています。

このコミットでは、BSD系のOS(FreeBSD, NetBSD, OpenBSD)におけるKillシステムコールのGo言語ラッパーの定義が変更されています。具体的には、Kill関数の2番目の引数であるsignumの型がintからSignalに変更されました。

--- a/src/pkg/syscall/syscall_freebsd.go
+++ b/src/pkg/syscall/syscall_freebsd.go
@@ -146,7 +146,7 @@ func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
 //sysnb	Gettimeofday(tv *Timeval) (err error)
 //sysnb	Getuid() (uid int)
 //sys	Issetugid() (tainted bool)
-//sys	Kill(pid int, signum int) (err error)
+//sys	Kill(pid int, signum Signal) (err error)
 //sys	Kqueue() (fd int, err error)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)

この変更は、os/signalパッケージで定義された新しいSignal型との整合性を保つために行われました。Signal型は、Go言語の内部でシグナルを表現するためのカスタム型であり、これによりシグナルに関する操作がより型安全になります。例えば、os.Interruptos.Killといった定数がSignal型として提供され、これらをKill関数に直接渡すことができるようになります。

この変更のメリットは以下の通りです。

  1. 型安全性: int型では任意の整数値をシグナル番号として渡せてしまいますが、Signal型を使用することで、Goコンパイラが不正なシグナル番号の利用を検出できるようになります。これにより、実行時エラーのリスクが低減します。
  2. コードの可読性: Signal型を使用することで、コードを読む人がその引数がシグナル番号であることをより明確に理解できます。
  3. 一貫性: os/signalパッケージとsyscallパッケージの間でシグナル表現の一貫性が保たれ、Go言語全体でのシグナル処理の設計がより統一されます。

この変更は、Go言語が初期の段階から、低レベルのシステムプログラミングにおいても高いレベルの安全性と使いやすさを追求していたことを示しています。

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

変更は以下の3つのファイルにわたっています。

  • src/pkg/syscall/syscall_freebsd.go
  • src/pkg/syscall/syscall_netbsd.go
  • src/pkg/syscall/syscall_openbsd.go

それぞれのファイルで、Killシステムコールの定義行が変更されています。

--- a/src/pkg/syscall/syscall_freebsd.go
+++ b/src/pkg/syscall/syscall_freebsd.go
@@ -146,7 +146,7 @@ func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
 //sysnb	Gettimeofday(tv *Timeval) (err error)
 //sysnb	Getuid() (uid int)
 //sys	Issetugid() (tainted bool)
-//sys	Kill(pid int, signum int) (err error)
+//sys	Kill(pid int, signum Signal) (err error)
 //sys	Kqueue() (fd int, err error)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)

他の2つのファイル(syscall_netbsd.gosyscall_openbsd.go)も同様の変更が加えられています。

コアとなるコードの解説

変更された行は、GoのsyscallパッケージがOSのシステムコールをGoの関数として公開するための特殊なコメント構文を使用しています。

元の行: //sys Kill(pid int, signum int) (err error)

変更後の行: //sys Kill(pid int, signum Signal) (err error)

この//sysコメントは、Goのビルドツールがこの行を解析し、対応するGoの関数シグネチャを自動的に生成するために使用されます。

  • //sys: これは、この行がシステムコール定義であることを示すディレクティブです。
  • Kill: 生成されるGo関数の名前です。
  • (pid int, signum int): 生成されるGo関数の引数リストです。
    • pid int: プロセスIDを表すint型の引数。
    • signum int (変更前): シグナル番号を表すint型の引数。
    • signum Signal (変更後): シグナル番号を表すSignal型の引数。
  • (err error): 生成されるGo関数の戻り値リストです。システムコールがエラーを返す可能性があるため、通常はerror型が含まれます。

この変更により、Goのsyscall.Kill関数を呼び出す際に、signum引数としてint型ではなくos/signalパッケージで定義されたSignal型を渡すことが必須となります。これにより、Goコンパイラが型チェックを行い、不正なシグナル番号の利用を早期に検出できるようになります。

例えば、変更前は以下のようなコードがコンパイルできてしまいましたが、シグナル番号として意味のない値が渡される可能性がありました。

// 変更前 (概念的なコード)
syscall.Kill(1234, 999) // 999は有効なシグナル番号ではないかもしれない

変更後は、Signal型を使用することで、より安全な呼び出しが強制されます。

// 変更後 (概念的なコード)
import "os"
import "syscall"

syscall.Kill(1234, os.Interrupt) // os.Interrupt は Signal 型
// syscall.Kill(1234, 999) // これはコンパイルエラーになる

この変更は、Go言語の標準ライブラリが、低レベルのOSインターフェースを扱いながらも、Go言語の型システムを活用して堅牢性と安全性を高める努力の一端を示しています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Unix系OSのシグナルに関する一般的な情報源 (例: man 7 signal, man 2 kill)
  • Go言語のソースコードリポジトリ (特にsrc/pkg/syscallディレクトリ)
  • Go言語のコミット履歴とChange List (CL) の議論
  • Go言語の設計に関するブログ記事や議論(当時の情報)
  • Web検索結果: "Go os/signal package changes 2012 Signal type" (特に、os/signalパッケージの変更がGo 1のリリースと同時期に行われ、signal.Notify関数とos.Signalインターフェースが導入された点)