別のプロセスにファイルを処理してもらうとき、ファイル名を伝えて開いてもらう方法があります。ところが、渡したいものが「いま開いている、このファイル」である場合には、別の方法もあります。UNIXドメインソケットのSCM_RIGHTSは、開いたファイルを使うための参照を、同じコンピューター上の別プロセスへ渡す仕組みです。
受け取った側には、そのプロセス用のファイル記述子ができます。ただし、ファイルを独立に開き直した状態にはなりません。たとえば通常の読み取りでは、一方が読んだ分だけ、もう一方の読み始める位置も進みます。この違いを知っておくと、処理を引き継ぐ設計と、各処理が独立に読みたい設計を区別できます。
簡単にまとめると?
- SCM_RIGHTSで渡すのは、開いたファイルへの参照です。受信側のFD番号は、送信側と同じになるとは限りません。
- 同じopen file descriptionを参照するため、通常の読み取り位置などを共有します。同じパスを別途openする場合とは異なります。
- 送信側が自分のFDを閉じても、受信側のFDまで閉じられるわけではありません。受け渡し後の読み方と、誰が閉じるかを決めて使います。
FDの番号は、そのプロセスの中で意味を持つ
ファイル記述子、略してFDは、開いたファイルなどを操作するときに渡す整数です。たとえばFD 4という番号は、プロセスが持つ記述子の表の一つの項目を指します。他のプロセスに数字の「4」を普通のデータとして送っただけでは、相手が同じファイルを読めるようにはなりません。
Linuxの説明で、ここからもう一段たどった先にあるのがopen file descriptionです。これは開いている状態を表すカーネル内の記録で、現在のファイル位置や、読み書きの動作に関わるフラグを持ちます。FDはこの記録への参照です。同じファイルを別々にopenすると、それぞれ別の記録が作られます。
SCM_RIGHTSを使うと、受信側の記述子の表にも、同じ記録を参照する項目ができます。Linuxのunix(7)は、これを別プロセスの記述子の表へdupするのと同じ意味だと説明しています。新しい番号ができても、その先にある「開いた状態」は共有されます。ファイルの内容をまるごと送る操作でもありません。
ABの次に、別プロセスがCDを読む
この共有を確かめるため、内容がABCDEFGHの一時ファイルを用意し、二つのプロセスで順番に2バイトずつ読む実験を行いました。実行環境はmacOS 26.6.2、Python 3.12.14です。以下はこの環境での観察であり、Linux上で測定した結果ではありません。
まず受信プロセスを起動し、通信に使うソケットだけを引き継がせます。対象ファイルはその後で送信側が開くため、受信側が最初から対象のFDを持っていた、という実験にはしていません。受信側では番号の違いを見やすくするため、あらかじめ別のFDを8個開いておきました。

送信側はFD 4でABを読んでから、SCM_RIGHTSで参照を渡しました。受信側にできたFDは12で、そこから読めたのはCDです。続いて送信側の現在位置を調べると、先頭から4バイトの位置になっていました。送信側が次に読むとEFが返ります。受信側の読み取りが、送信側にも見える位置を進めています。
その途中で同じパスを別途openしたFDから読むと、返ったのはABでした。このFDには独立した読み取り位置があるためです。さらに送信側の元のFDを閉じた後、受信側は自分のFDから残りのGHを読めました。三つの独立した試行で、この順序を確認しています。
これは受け渡しの意味を見る小さな実験です。速度を測ったものではなく、二つのプロセスを同時に走らせて読み取り順を競わせてもいません。実際に並行して読めば、どちらがどの部分を受け持つかは、アプリケーション側の手順にも左右されます。
通常のデータとは別の欄で渡す
送受信にはsendmsgとrecvmsgを使い、付随データ、英語ではancillary dataと呼ばれる欄へFDを載せます。Pythonでは、その欄の種類をSOL_SOCKETとSCM_RIGHTSで指定します。受信側は通常のデータだけでなく、この付随データから自分に割り当てられたFDを取り出します。
ここで、通常データ用のバッファだけを大きくしても十分ではありません。付随データには別の受信領域が必要です。PythonのCMSG_SPACEは、その領域に必要な余白も含めたサイズを計算します。ただし、サイズを指定しただけで受信するFDの個数まで厳密に制限できるとは限らないため、受信後にも種類と個数を確かめます。
Linuxでは付随データが収まりきらなかった場合にMSG_CTRUNCが示されます。予定どおり受け取れたものとして処理を進めず、切り詰めの有無やエラーを確認し、不要なFDを閉じる手順が必要です。また、Linuxのストリーム型UNIXドメインソケットでFDを渡す場合、少なくとも1バイトの通常データも必要です。今回の実験では目印として1バイトを添えました。
引き継ぎたい状態を先に決める
たとえば、受付役のプロセスが開いたファイルを作業役へ渡し、そこから続きを読ませたいなら、読み取り位置を共有する性質が役立ちます。一方で、複数の作業役がそれぞれ先頭から全体を読みたい場合、SCM_RIGHTSで受け取ったFDから単純にreadするだけでは、その意図になりません。同じファイルを使うことと、独立した位置で読むことは別の条件です。
また、送信側がFDを閉じるのは、自分が持つ参照を手放す操作です。すでに渡した受信側の参照を取り消す操作にはなりません。渡す相手と対象を確かめたうえで、受信側がいつ閉じるか、送信側は受け渡し成功をどう確認するかまで、処理の約束に含めます。
SCM_RIGHTSの要点は、ファイル名から開き直す手間だけではありません。すでに開かれた状態を、別のプロセスでも使えるようにするところにあります。番号、開いた状態、ファイル本体を分けて考えると、何が新しくできて、何が共有されたままなのかが見えてきます。
出典
- Linux man-pages:unix(7) — 6.19、2026年2月8日。SCM_RIGHTSと付随データ、Linuxでの受信条件。
- Linux man-pages:open(2)、dup(2) — 6.19、2026年2月8日。FDとopen file descriptionの関係。
- Python 3.12:socket — 閲覧時の文書版は3.12.15。sendmsg、recvmsg、CMSG_SPACE。利用可否と細部はOSに依存する。
- Quantum Sea独自実験 — 2026年10月25日、macOS 26.6.2 / Python 3.12.14、通常ファイル8バイト、独立プロセス間のSCM_RIGHTS受け渡しを3試行。
