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

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

このコミットは、Go言語の実験的なSSHパッケージ (exp/ssh) において、シグナルを表す型 signal をエクスポート可能な Signal 型にリネームし、外部から利用可能にする変更です。これにより、SSHセッションを通じてリモートプロセスにシグナルを送信する機能が、パッケージの外部からよりGoの慣習に沿った形で利用できるようになります。

コミット

commit fad57c0c030b5f5b6204b781b33d4343f95d6c40
Author: Gustav Paul <gustav.paul@gmail.com>
Date:   Thu Dec 1 14:06:15 2011 -0500

    exp/ssh: export type signal. Renamed to Signal

    R=dave, agl, rsc, golang-dev, n13m3y3r
    CC=golang-dev
    https://golang.org/cl/5450059

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

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

元コミット内容

exp/ssh: signal 型をエクスポートし、Signal にリネーム。

変更の背景

Go言語では、パッケージ外部からアクセス可能な(エクスポートされた)識別子(型、関数、変数など)は、その名前の最初の文字が大文字である必要があります。このコミット以前は、SSHセッションで利用されるシグナルを表す型が signal という小文字で始まる名前であったため、exp/ssh パッケージの外部からは直接利用できませんでした。

この変更の背景には、exp/ssh パッケージが提供するSSHセッション管理機能において、リモートプロセスへのシグナル送信機能(Session.Signal メソッド)を外部からよりGoの慣習に沿った形で利用可能にする意図があります。具体的には、Session.Signal メソッドの引数として渡されるシグナル型をエクスポートすることで、ユーザーがパッケージ内で定義された SIGABRT, SIGINT などの定数を直接利用できるようになります。これにより、APIの使いやすさと一貫性が向上します。

前提知識の解説

Go言語のエクスポートルール

Go言語では、識別子(変数、関数、型、メソッドなど)の可視性(スコープ)は、その名前の最初の文字が大文字か小文字かによって決まります。

  • 大文字で始まる識別子: パッケージの外部からアクセス可能です(エクスポートされます)。
  • 小文字で始まる識別子: その識別子が定義されているパッケージ内でのみアクセス可能です(エクスポートされません)。

このルールは、GoのAPI設計において非常に重要であり、外部に公開するべきものと内部実装の詳細を区別するために用いられます。

exp/ssh パッケージ

exp/ssh は、Go言語の標準ライブラリの一部として、SSH (Secure Shell) プロトコルを実装するための実験的なパッケージでした。SSHは、ネットワークを介して安全にコンピュータを操作するためのプロトコルであり、リモートコマンドの実行、ファイル転送、ポートフォワーディングなどの機能を提供します。exp ディレクトリにあるパッケージは、まだ安定版ではなく、APIが変更される可能性があることを示しています。このパッケージは後に golang.org/x/crypto/ssh として独立し、より成熟したSSHクライアントおよびサーバーの実装を提供しています。

POSIXシグナルとRFC 4254 Section 6.10

POSIXシグナルは、Unix系オペレーティングシステムにおいて、プロセスに対して非同期にイベントを通知するメカニズムです。例えば、SIGINT は通常、ユーザーがCtrl+Cを押したときにプロセスに送信され、プロセスの終了を要求します。SIGTERM は正常な終了を要求し、SIGKILL は強制終了を要求します。

RFC 4254 Section 6.10 は、SSHプロトコルにおける「シグナル」リクエストの仕様を定義しています。このセクションでは、SSHクライアントがリモートのSSHサーバーに対して、特定のPOSIXシグナルをリモートプロセスに送信するよう要求する方法が記述されています。このコミットで定義されている SIGABRT, SIGALRM などの定数は、このRFCで規定されているシグナル名に対応しています。SSHプロトコルでは、これらのシグナル名を文字列として送信することで、リモートプロセスにシグナルを伝達します。

技術的詳細

このコミットの主要な技術的変更は、Go言語のエクスポートルールに準拠するために、signal という名前の型を Signal に変更したことです。

変更前:

type signal string

変更後:

type Signal string

この変更により、Signal 型は exp/ssh パッケージの外部から参照可能になります。これは、Session 型の Signal メソッドのシグネチャにも影響を与えます。

変更前:

func (s *Session) Signal(sig signal) error

変更後:

func (s *Session) Signal(sig Signal) error

これにより、exp/ssh パッケージを利用する外部のコードは、exp/ssh.Signal 型を直接使用してシグナルを表現できるようになります。また、パッケージ内で定義されているシグナル定数(例: exp/ssh.SIGINT)も、Signal 型としてエクスポートされるため、外部から直接アクセスして利用することが可能になります。

例えば、変更前は exp/ssh パッケージの内部でのみ signal 型の定数を利用できましたが、変更後は以下のように外部から exp/ssh.SIGINT を直接参照して Session.Signal メソッドに渡すことができるようになります。

// 変更後の利用例
import "exp/ssh"

// ...
session := &ssh.Session{} // 仮のSessionインスタンス
err := session.Signal(ssh.SIGINT)
if err != nil {
    // エラーハンドリング
}
// ...

この変更は、APIの使いやすさだけでなく、Goの慣習に沿った設計を促進します。小文字で始まる型は通常、内部的な実装の詳細として扱われるため、外部に公開する意図がある場合は大文字で始めるのが適切です。

コメントの変更は、主に改行位置の調整であり、コードのセマンティクスには影響を与えませんが、コードの可読性を向上させるための一般的なクリーンアップ作業の一部と考えられます。

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

変更は src/pkg/exp/ssh/session.go ファイルに集中しています。

  1. 型定義のリネーム:

    --- a/src/pkg/exp/ssh/session.go
    +++ b/src/pkg/exp/ssh/session.go
    @@ -15,39 +15,39 @@ import (
     	"io/ioutil"
     )
    
    -type signal string
    +type Signal string
    

    signal 型が Signal 型にリネームされています。

  2. シグナル定数の型変更:

    --- a/src/pkg/exp/ssh/session.go
    +++ b/src/pkg/exp/ssh/session.go
    @@ -15,39 +15,39 @@ import (
     	"io/ioutil"
     )
    
    -type signal string
    +type Signal string
    
     // POSIX signals as listed in RFC 4254 Section 6.10.
     const (
    -	SIGABRT signal = "ABRT"
    -	SIGALRM signal = "ALRM"
    -	SIGFPE  signal = "FPE"
    -	SIGHUP  signal = "HUP"
    -	SIGILL  signal = "ILL"
    -	SIGINT  signal = "INT"
    -	SIGKILL signal = "KILL"
    -	SIGPIPE signal = "PIPE"
    -	SIGQUIT signal = "QUIT"
    -	SIGSEGV signal = "SEGV"
    -	SIGTERM signal = "TERM"
    -	SIGUSR1 signal = "USR1"
    -	SIGUSR2 signal = "USR2"
    +	SIGABRT Signal = "ABRT"
    +	SIGALRM Signal = "ALRM"
    +	SIGFPE  Signal = "FPE"
    +	SIGHUP  Signal = "HUP"
    +	SIGILL  Signal = "ILL"
    +	SIGINT  Signal = "INT"
    +	SIGKILL Signal = "KILL"
    +	SIGPIPE Signal = "PIPE"
    +	SIGQUIT Signal = "QUIT"
    +	SIGSEGV Signal = "SEGV"
    +	SIGTERM Signal = "TERM"
    +	SIGUSR1 Signal = "USR1"
    +	SIGUSR2 Signal = "USR2"
     )
    

    すべての SIG* 定数の型が signal から Signal に変更されています。

  3. Session.Signal メソッドの引数型変更:

    --- a/src/pkg/exp/ssh/session.go
    +++ b/src/pkg/exp/ssh/session.go
    @@ -130,7 +130,7 @@ type signalMsg struct {
    
     // Signal sends the given signal to the remote process.
     // sig is one of the SIG* constants.
    -func (s *Session) Signal(sig signal) error {
    +func (s *Session) Signal(sig Signal) error {
     	req := signalMsg{
     		PeersId:   s.peersId,
     		Request:   "signal",
    

    Session.Signal メソッドの sig 引数の型が signal から Signal に変更されています。

  4. コメントの整形: 複数のコメント行で改行位置が調整されています。これは機能的な変更ではなく、コードの整形です。

コアとなるコードの解説

このコミットの核心は、Go言語の可視性ルールに従い、signal 型を Signal 型にリネームすることで、この型をパッケージ外部にエクスポート可能にした点にあります。

  • type Signal string: この行は、Signal という新しい型を定義しています。この型は基底型が string であり、SSHプロトコルでシグナル名を表す文字列(例: "ABRT", "INT")を保持するために使用されます。名前の最初の文字が大文字であるため、この型は exp/ssh パッケージの外部から参照できるようになります。

  • const ( ... ): ここでは、POSIXシグナルに対応する定数が定義されています。これらの定数は、Signal 型の値として定義されており、それぞれ対応するシグナル名を文字列として保持しています。例えば、SIGINT Signal = "INT" は、SIGINT という定数が Signal 型であり、その値が文字列 "INT" であることを示します。これらの定数も Signal 型と同様にエクスポートされるため、外部から exp/ssh.SIGINT のように直接アクセスして利用できます。

  • func (s *Session) Signal(sig Signal) error: このメソッドは、SSHセッションを通じてリモートプロセスにシグナルを送信する機能を提供します。引数 sig の型が Signal に変更されたことで、外部のコードはエクスポートされた Signal 型の定数(例: exp/ssh.SIGTERM)を直接このメソッドに渡すことができるようになります。これにより、SSHセッションを介したシグナル送信のAPIが、Goの慣習に沿った、より使いやすいものになりました。

この変更により、exp/ssh パッケージのユーザーは、SSHセッションで利用可能なシグナルを型安全な方法で指定できるようになり、APIの利用がより直感的になります。

関連リンク

参考にした情報源リンク