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

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

このコミットは、Go言語の標準ライブラリnetパッケージにおけるTCPListenerおよびUnixListenerFile()メソッドに、重要なドキュメントを追加するものです。具体的には、File()メソッドが返す*os.Fileが元の接続とは異なるファイルディスクリプタを持つこと、そしてその複製に対して行われた変更が元の接続に意図した効果をもたらさない可能性があるという注意書きが追加されました。

コミット

Author: Mikio Hara mikioh.mikioh@gmail.com Date: Wed Apr 24 08:32:11 2013 +0900

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

https://github.com/golang/go/commit/73417e4098f59b3b03e7b3287427be6e47d9f56e

元コミット内容

net: add missing File method document

R=golang-dev, bradfitz, r
CC=golang-dev
https://golang.org/cl/8698049

変更の背景

Go言語のnetパッケージでは、TCPListenerUnixListenerのようなリスナーオブジェクトが、基盤となるネットワーク接続を抽象化しています。これらのリスナーは、File()メソッドを提供しており、これによりユーザーはリスナーが使用している基盤のファイルディスクリプタ(またはそれに相当するもの)を*os.Fileとして取得できます。これは、例えばselectepollのようなシステムコールと組み合わせて、より低レベルなI/O操作を行いたい場合に有用です。

しかし、File()メソッドの実装は、単に基盤のファイルディスクリプタを複製(dupシステムコールなどを用いて)して新しい*os.Fileオブジェクトとして返すものでした。この挙動は、ユーザーがFile()メソッドから得られた*os.Fileに対して行った操作(例えば、SetDeadlineSetReadBufferなど)が、元のリスナーオブジェクトには影響しない可能性があるという重要な意味を持っていました。

このコミット以前は、この重要な挙動に関する明示的なドキュメントが存在しませんでした。そのため、開発者がFile()メソッドの戻り値に対して操作を行い、それが元のリスナーに反映されると誤解する可能性がありました。このような誤解は、予期せぬバグやパフォーマンスの問題を引き起こす可能性があります。このコミットは、この「欠けていたドキュメント」を追加することで、開発者の誤解を防ぎ、APIの正しい使用法を明確にすることを目的としています。

前提知識の解説

ファイルディスクリプタ (File Descriptor, FD)

ファイルディスクリプタは、Unix系オペレーティングシステムにおいて、開かれたファイルやソケット、パイプなどのI/Oリソースを識別するためにカーネルがプロセスに割り当てる非負の整数です。プログラムはファイルディスクリプタを通じて、これらのリソースに対して読み書きなどの操作を行います。

os.File

Go言語のosパッケージにあるFile型は、オペレーティングシステムのファイルディスクリプタを抽象化したものです。これにより、Goプログラムはファイルやネットワーク接続などのI/Oリソースを統一的に扱うことができます。*os.Fileは、ファイルディスクリプタへの参照を内部に持ち、それを通じてI/O操作を実行します。

dupシステムコール (またはそれに相当する操作)

dup (duplicate file descriptor) は、既存のファイルディスクリプタの複製を作成するシステムコールです。複製されたファイルディスクリプタは、元のファイルディスクリプタと同じオープンファイル記述エントリ(ファイルオフセット、ファイルステータスフラグなど)を参照します。しかし、ファイルディスクリプタ自体は新しい番号が割り当てられ、独立したものです。これにより、例えば親プロセスと子プロセスが同じファイルにアクセスする際に、それぞれが独立したファイルディスクリプタを持つことができます。GoのnetパッケージのFile()メソッドは、内部的にこのdupに相当する操作を行っています。

ブロッキングモードと非ブロッキングモード

ファイルディスクリプタは、ブロッキングモードまたは非ブロッキングモードで動作させることができます。

  • ブロッキングモード: I/O操作(読み込みや書き込み)が完了するまで、呼び出し元のプロセスを停止(ブロック)させます。
  • 非ブロッキングモード: I/O操作がすぐに完了しない場合でも、プロセスをブロックせずにエラー(例えばEAGAINEWOULDBLOCK)を返します。これにより、プログラムは他のタスクを実行しながらI/Oの準備ができるのを待つことができます。

File()メソッドが「ブロッキングモードに設定された」*os.Fileを返すという記述は、返されたファイルがデフォルトでブロッキングI/Oを行うことを意味します。

Go言語のnetパッケージ

netパッケージは、Go言語でネットワークプログラミングを行うための主要なパッケージです。TCP/IP、UDP、Unixドメインソケットなどのネットワークプロトコルをサポートし、高レベルなインターフェース(Dial, Listen, Acceptなど)を提供します。TCPListenerUnixListenerは、それぞれTCPソケットとUnixドメインソケットのリスニングエンドポイントを表現する型です。

Plan 9とPOSIX

Go言語は、複数のオペレーティングシステムをサポートしています。このコミットで変更されているファイル名にplan9posixが含まれているのは、Goのnetパッケージがこれらの異なるOS環境向けに、それぞれのシステムコールやAPIに合わせた実装を持っているためです。

  • POSIX: Portable Operating System Interfaceの略で、Unix系OSの標準インターフェースを定義しています。Linux、macOS、BSDなどがこれに準拠しています。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Go言語の開発者の一部はPlan 9の経験があり、Goの設計思想にも影響を与えています。

技術的詳細

このコミットで追加されたドキュメントの核心は、File()メソッドが返す*os.Fileが、元のネットワーク接続とは異なるファイルディスクリプタを持つという点です。これは、File()メソッドが内部的にdup(またはそれに相当する複製操作)を実行しているためです。

具体的に、追加されたドキュメントは以下の点を強調しています。

  1. ファイルディスクリプタの独立性:

    The returned os.File's file descriptor is different from the connection's. (返されたos.Fileのファイルディスクリプタは、接続のファイルディスクリプタとは異なります。)

    これは、File()が元のソケットのファイルディスクリプタを直接返すのではなく、その複製を返すことを明確にしています。複製されたファイルディスクリプタは、元のファイルディスクリプタと同じオープンファイル記述エントリを共有しますが、ファイルディスクリプタ自体は独立したものです。

  2. プロパティ変更の影響:

    Attempting to change properties of the original using this duplicate may or may not have the desired effect. (この複製を使用して元のプロパティを変更しようとしても、意図した効果が得られる場合と得られない場合があります。)

    この警告は非常に重要です。*os.Fileオブジェクトには、ソケットのバッファサイズを変更するSetReadBuffer()SetWriteBuffer()、タイムアウトを設定するSetDeadline()などのメソッドがあります。もしユーザーがFile()から得られた*os.Fileに対してこれらのメソッドを呼び出した場合、その変更は複製されたファイルディスクリプタにのみ適用され、元のネットワーク接続(リスナー)には反映されない可能性があります。

    なぜ「意図した効果が得られる場合と得られない場合がある」のかというと、ファイルディスクリプタのプロパティには、オープンファイル記述エントリに紐づくもの(例: ファイルオフセット、ファイルステータスフラグ)と、ファイルディスクリプタ自体に紐づくもの(例: fcntlで設定される一部のフラグ、ソケットオプション)があるためです。dupによって複製されたファイルディスクリプタは、オープンファイル記述エントリを共有するため、前者のプロパティ変更は両方に影響する可能性があります。しかし、後者のプロパティ変更は、複製されたファイルディスクリプタにのみ影響し、元のファイルディスクリプタには影響しない可能性が高いです。ネットワークソケットのバッファサイズやタイムアウト設定は、通常、ソケットオプションとしてファイルディスクリプタに紐づくため、複製に対して変更しても元のソケットには影響しないことがほとんどです。

このドキュメントの追加により、開発者はFile()メソッドの戻り値の性質を正しく理解し、誤った仮定に基づいてコードを書くことを避けることができます。これは、APIの透明性を高め、潜在的なバグを未然に防ぐ上で非常に価値のある変更です。

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

このコミットでは、以下の4つのファイルにドキュメントが追加されています。

src/pkg/net/tcpsock_plan9.go

--- a/src/pkg/net/tcpsock_plan9.go
+++ b/src/pkg/net/tcpsock_plan9.go
@@ -159,6 +159,10 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
 // File returns a copy of the underlying os.File, set to blocking
 // mode.  It is the caller's responsibility to close f when finished.
 // Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
 func (l *TCPListener) File() (f *os.File, err error) { return l.dup() }
 
 // ListenTCP announces on the TCP address laddr and returns a TCP

src/pkg/net/tcpsock_posix.go

--- a/src/pkg/net/tcpsock_posix.go
+++ b/src/pkg/net/tcpsock_posix.go
@@ -267,6 +267,10 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
 // File returns a copy of the underlying os.File, set to blocking
 // mode.  It is the caller's responsibility to close f when finished.
 // Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
 func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
 
 // ListenTCP announces on the TCP address laddr and returns a TCP

src/pkg/net/unixsock_plan9.go

--- a/src/pkg/net/unixsock_plan9.go
+++ b/src/pkg/net/unixsock_plan9.go
@@ -126,6 +126,10 @@ func (l *UnixListener) SetDeadline(t time.Time) error {
 // File returns a copy of the underlying os.File, set to blocking
 // mode.  It is the caller's responsibility to close f when finished.
 // Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
 func (l *UnixListener) File() (*os.File, error) {
 	return nil, syscall.EPLAN9
 }

src/pkg/net/unixsock_posix.go

--- a/src/pkg/net/unixsock_posix.go
+++ b/src/pkg/net/unixsock_posix.go
@@ -339,6 +339,10 @@ func (l *UnixListener) SetDeadline(t time.Time) (err error) {\n // File returns a copy of the underlying os.File, set to blocking\n // mode.  It is the caller's responsibility to close f when finished.\n // Closing l does not affect f, and closing f does not affect l.\n+//\n+// The returned os.File's file descriptor is different from the\n+// connection's.  Attempting to change properties of the original\n+// using this duplicate may or may not have the desired effect.\n func (l *UnixListener) File() (f *os.File, err error) { return l.fd.dup() }\n 
 // ListenUnixgram listens for incoming Unix datagram packets addressed\n```

## コアとなるコードの解説

上記の各ファイルにおいて、`File()`メソッドの既存のドキュメントブロックに以下の4行が追加されています。

```go
//
// The returned os.File's file descriptor is different from the
// connection's.  Attempting to change properties of the original
// using this duplicate may or may not have the desired effect.

この追加は、File()メソッドの動作に関する重要な注意点を明確にしています。

  • The returned os.File's file descriptor is different from the connection's.: これは、File()メソッドが内部的にdup()(またはそれに相当するファイルディスクリプタの複製操作)を呼び出していることを示唆しています。つまり、返される*os.Fileオブジェクトは、元のネットワーク接続が使用しているファイルディスクリプタとは異なる、新しいファイルディスクリプタを保持しています。両者は同じ基盤となるカーネルオブジェクト(オープンファイル記述エントリ)を参照していますが、ファイルディスクリプタ自体は別物です。

  • Attempting to change properties of the original using this duplicate may or may not have the desired effect.: この警告は、複製されたファイルディスクリプタに対して行われた操作が、元のネットワーク接続に意図した通りに影響しない可能性があることを示しています。例えば、返された*os.Fileに対してSetReadBuffer()SetDeadline()のようなメソッドを呼び出しても、それは複製されたファイルディスクリプタにのみ適用され、元のリスナーやそこから受け入れられた接続の動作には影響しない可能性が高いです。これは、ソケットオプションのような一部のプロパティがファイルディスクリプタ自体に紐づいているためです。

このドキュメントの追加は、APIの利用者がFile()メソッドの戻り値の性質を誤解し、それによって発生しうるバグや予期せぬ挙動を防ぐためのものです。特に、低レベルなソケット操作を行う開発者にとっては、この情報は非常に重要です。

関連リンク

参考にした情報源リンク

  • Go言語のnetパッケージドキュメント: https://pkg.go.dev/net
  • Go言語のosパッケージドキュメント: https://pkg.go.dev/os
  • dupシステムコールに関する情報 (例: man 2 dup)
  • ファイルディスクリプタとソケットオプションに関する一般的なOSのドキュメント
  • Go言語のソースコード (特にnetパッケージの内部実装)# [インデックス 16224] ファイルの概要

このコミットは、Go言語の標準ライブラリnetパッケージにおけるTCPListenerおよびUnixListenerFile()メソッドに、重要なドキュメントを追加するものです。具体的には、File()メソッドが返す*os.Fileが元の接続とは異なるファイルディスクリプタを持つこと、そしてその複製に対して行われた変更が元の接続に意図した効果をもたらさない可能性があるという注意書きが追加されました。

コミット

Author: Mikio Hara mikioh.mikioh@gmail.com Date: Wed Apr 24 08:32:11 2013 +0900

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

https://github.com/golang/go/commit/73417e4098f59b3b03e7b3287427be6e47d9f56e

元コミット内容

net: add missing File method document

R=golang-dev, bradfitz, r
CC=golang-dev
https://golang.org/cl/8698049

変更の背景

Go言語のnetパッケージでは、TCPListenerUnixListenerのようなリスナーオブジェクトが、基盤となるネットワーク接続を抽象化しています。これらのリスナーは、File()メソッドを提供しており、これによりユーザーはリスナーが使用している基盤のファイルディスクリプタ(またはそれに相当するもの)を*os.Fileとして取得できます。これは、例えばselectepollのようなシステムコールと組み合わせて、より低レベルなI/O操作を行いたい場合に有用です。

しかし、File()メソッドの実装は、単に基盤のファイルディスクリプタを複製(dupシステムコールなどを用いて)して新しい*os.Fileオブジェクトとして返すものでした。この挙動は、ユーザーがFile()メソッドから得られた*os.Fileに対して行った操作(例えば、SetDeadlineSetReadBufferなど)が、元のリスナーオブジェクトには影響しない可能性があるという重要な意味を持っていました。

このコミット以前は、この重要な挙動に関する明示的なドキュメントが存在しませんでした。そのため、開発者がFile()メソッドの戻り値に対して操作を行い、それが元のリスナーに反映されると誤解する可能性がありました。このような誤解は、予期せぬバグやパフォーマンスの問題を引き起こす可能性があります。このコミットは、この「欠けていたドキュメント」を追加することで、開発者の誤解を防ぎ、APIの正しい使用法を明確にすることを目的としています。

前提知識の解説

ファイルディスクリプタ (File Descriptor, FD)

ファイルディスクリプタは、Unix系オペレーティングシステムにおいて、開かれたファイルやソケット、パイプなどのI/Oリソースを識別するためにカーネルがプロセスに割り当てる非負の整数です。プログラムはファイルディスクリプタを通じて、これらのリソースに対して読み書きなどの操作を行います。

os.File

Go言語のosパッケージにあるFile型は、オペレーティングシステムのファイルディスクリプタを抽象化したものです。これにより、Goプログラムはファイルやネットワーク接続などのI/Oリソースを統一的に扱うことができます。*os.Fileは、ファイルディスクリプタへの参照を内部に持ち、それを通じてI/O操作を実行します。

dupシステムコール (またはそれに相当する操作)

dup (duplicate file descriptor) は、既存のファイルディスクリプタの複製を作成するシステムコールです。複製されたファイルディスクリプタは、元のファイルディスクリプタと同じオープンファイル記述エントリ(ファイルオフセット、ファイルステータスフラグなど)を参照します。しかし、ファイルディスクリプタ自体は新しい番号が割り当てられ、独立したものです。これにより、例えば親プロセスと子プロセスが同じファイルにアクセスする際に、それぞれが独立したファイルディスクリプタを持つことができます。GoのnetパッケージのFile()メソッドは、内部的にこのdupに相当する操作を行っています。

ブロッキングモードと非ブロッキングモード

ファイルディスクリプタは、ブロッキングモードまたは非ブロッキングモードで動作させることができます。

  • ブロッキングモード: I/O操作(読み込みや書き込み)が完了するまで、呼び出し元のプロセスを停止(ブロック)させます。
  • 非ブロッキングモード: I/O操作がすぐに完了しない場合でも、プロセスをブロックせずにエラー(例えばEAGAINEWOULDBLOCK)を返します。これにより、プログラムは他のタスクを実行しながらI/Oの準備ができるのを待つことができます。

File()メソッドが「ブロッキングモードに設定された」*os.Fileを返すという記述は、返されたファイルがデフォルトでブロッキングI/Oを行うことを意味します。

Go言語のnetパッケージ

netパッケージは、Go言語でネットワークプログラミングを行うための主要なパッケージです。TCP/IP、UDP、Unixドメインソケットなどのネットワークプロトコルをサポートし、高レベルなインターフェース(Dial, Listen, Acceptなど)を提供します。TCPListenerUnixListenerは、それぞれTCPソケットとUnixドメインソケットのリスニングエンドポイントを表現する型です。

Plan 9とPOSIX

Go言語は、複数のオペレーティングシステムをサポートしています。このコミットで変更されているファイル名にplan9posixが含まれているのは、Goのnetパッケージがこれらの異なるOS環境向けに、それぞれのシステムコールやAPIに合わせた実装を持っているためです。

  • POSIX: Portable Operating System Interfaceの略で、Unix系OSの標準インターフェースを定義しています。Linux、macOS、BSDなどがこれに準拠しています。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Go言語の開発者の一部はPlan 9の経験があり、Goの設計思想にも影響を与えています。

技術的詳細

このコミットで追加されたドキュメントの核心は、File()メソッドが返す*os.Fileが、元のネットワーク接続とは異なるファイルディスクリプタを持つという点です。これは、File()メソッドが内部的にdup(またはそれに相当する複製操作)を実行しているためです。

具体的に、追加されたドキュメントは以下の点を強調しています。

  1. ファイルディスクリプタの独立性:

    The returned os.File's file descriptor is different from the connection's. (返されたos.Fileのファイルディスクリプタは、接続のファイルディスクリプタとは異なります。)

    これは、File()が元のソケットのファイルディスクリプタを直接返すのではなく、その複製を返すことを明確にしています。複製されたファイルディスクリプタは、元のファイルディスクリプタと同じオープンファイル記述エントリを共有しますが、ファイルディスクリプタ自体は独立したものです。

  2. プロパティ変更の影響:

    Attempting to change properties of the original using this duplicate may or may not have the desired effect. (この複製を使用して元のプロパティを変更しようとしても、意図した効果が得られる場合と得られない場合があります。)

    この警告は非常に重要です。*os.Fileオブジェクトには、ソケットのバッファサイズを変更するSetReadBuffer()SetWriteBuffer()、タイムアウトを設定するSetDeadline()などのメソッドがあります。もしユーザーがFile()から得られた*os.Fileに対してこれらのメソッドを呼び出した場合、その変更は複製されたファイルディスクリプタにのみ適用され、元のネットワーク接続(リスナー)には反映されない可能性があります。

    なぜ「意図した効果が得られる場合と得られない場合がある」のかというと、ファイルディスクリプタのプロパティには、オープンファイル記述エントリに紐づくもの(例: ファイルオフセット、ファイルステータスフラグ)と、ファイルディスクリプタ自体に紐づくもの(例: fcntlで設定される一部のフラグ、ソケットオプション)があるためです。dupによって複製されたファイルディスクリプタは、オープンファイル記述エントリを共有するため、前者のプロパティ変更は両方に影響する可能性があります。しかし、後者のプロパティ変更は、複製されたファイルディスクリプタにのみ影響し、元のファイルディスクリプタには影響しない可能性が高いです。ネットワークソケットのバッファサイズやタイムアウト設定は、通常、ソケットオプションとしてファイルディスクリプタに紐づくため、複製に対して変更しても元のソケットには影響しないことがほとんどです。

このドキュメントの追加により、開発者はFile()メソッドの戻り値の性質を正しく理解し、誤った仮定に基づいてコードを書くことを避けることができます。これは、APIの透明性を高め、潜在的なバグを未然に防ぐ上で非常に価値のある変更です。

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

このコミットでは、以下の4つのファイルにドキュメントが追加されています。

src/pkg/net/tcpsock_plan9.go

--- a/src/pkg/net/tcpsock_plan9.go
+++ b/src/pkg/net/tcpsock_plan9.go
@@ -159,6 +159,10 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
 // File returns a copy of the underlying os.File, set to blocking
 // mode.  It is the caller's responsibility to close f when finished.
 // Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
 func (l *TCPListener) File() (f *os.File, err error) { return l.dup() }
 
 // ListenTCP announces on the TCP address laddr and returns a TCP

src/pkg/net/tcpsock_posix.go

--- a/src/pkg/net/tcpsock_posix.go
+++ b/src/pkg/net/tcpsock_posix.go
@@ -267,6 +267,10 @@ func (l *TCPListener) SetDeadline(t time.Time) error {
 // File returns a copy of the underlying os.File, set to blocking
 // mode.  It is the caller's responsibility to close f when finished.
 // Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
 func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
 
 // ListenTCP announces on the TCP address laddr and returns a TCP

src/pkg/net/unixsock_plan9.go

--- a/src/pkg/net/unixsock_plan9.go
+++ b/src/pkg/net/unixsock_plan9.go
@@ -126,6 +126,10 @@ func (l *UnixListener) SetDeadline(t time.Time) error {
 // File returns a copy of the underlying os.File, set to blocking
 // mode.  It is the caller's responsibility to close f when finished.
 // Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
 func (l *UnixListener) File() (*os.File, error) {
 	return nil, syscall.EPLAN9
 }

src/pkg/net/unixsock_posix.go

--- a/src/pkg/net/unixsock_posix.go
+++ b/src/pkg/net/unixsock_posix.go
@@ -339,6 +339,10 @@ func (l *UnixListener) SetDeadline(t time.Time) (err error) {\n // File returns a copy of the underlying os.File, set to blocking\n // mode.  It is the caller's responsibility to close f when finished.\n // Closing l does not affect f, and closing f does not affect l.\n+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.\n func (l *UnixListener) File() (f *os.File, err error) { return l.fd.dup() }\n 
 // ListenUnixgram listens for incoming Unix datagram packets addressed\n```

## コアとなるコードの解説

上記の各ファイルにおいて、`File()`メソッドの既存のドキュメントブロックに以下の4行が追加されています。

```go
//
// The returned os.File's file descriptor is different from the
// connection's.  Attempting to change properties of the original
// using this duplicate may or may not have the desired effect.

この追加は、File()メソッドの動作に関する重要な注意点を明確にしています。

  • The returned os.File's file descriptor is different from the connection's.: これは、File()メソッドが内部的にdup()(またはそれに相当するファイルディスクリプタの複製操作)を呼び出していることを示唆しています。つまり、返される*os.Fileオブジェクトは、元のネットワーク接続が使用しているファイルディスクリプタとは異なる、新しいファイルディスクリプタを保持しています。両者は同じ基盤となるカーネルオブジェクト(オープンファイル記述エントリ)を参照していますが、ファイルディスクリプタ自体は別物です。

  • Attempting to change properties of the original using this duplicate may or may not have the desired effect.: この警告は、複製されたファイルディスクリプタに対して行われた操作が、元のネットワーク接続に意図した通りに影響しない可能性があることを示しています。例えば、返された*os.Fileに対してSetReadBuffer()SetDeadline()のようなメソッドを呼び出しても、それは複製されたファイルディスクリプタにのみ適用され、元のリスナーやそこから受け入れられた接続の動作には影響しない可能性が高いです。これは、ソケットオプションのような一部のプロパティがファイルディスクリプタ自体に紐づいているためです。

このドキュメントの追加は、APIの利用者がFile()メソッドの戻り値の性質を誤解し、それによって発生しうるバグや予期せぬ挙動を防ぐためのものです。特に、低レベルなソケット操作を行う開発者にとっては、この情報は非常に重要です。

関連リンク

参考にした情報源リンク

  • Go言語のnetパッケージドキュメント: https://pkg.go.dev/net
  • Go言語のosパッケージドキュメント: https://pkg.go.dev/os
  • dupシステムコールに関する情報 (例: man 2 dup)
  • ファイルディスクリプタとソケットオプションに関する一般的なOSのドキュメント
  • Go言語のソースコード (特にnetパッケージの内部実装)