親プロセスと分岐した子プロセスがあり、これらは で作成された Unix ドメイン IPC ソケットを共有していますsocketpair(AF_UNIX, SOCK_STREAM, 0, sockets)
。両方のプロセスがソケット ペアの一方の端を閉じ、もう一方の端をsock
変数に保存します。その後、彼らはこれを行います:
int sock; // Unix-domain socket
void child_main()
{
printf("I am child\n");
sleep(1);
close(sock);
}
void parent_main()
{
printf("I am parent\n");
write(sock, "hello", 5);
char buf[100];
int ret = read(sock, buf, 100); // this read will return ECONNRESET
if (ret == -1) {
perror("read");
exit(-1);
}
}
親プロセスはソケットにデータを書き込みますが、子プロセスはそれを読み取りません。代わりに、子はソケットを閉じます。今私の懸念はread
、親プロセスでECONNRESET(ピアによる接続リセット)で失敗することですが、ストリームの終わりを示す「0」が返されることを期待しています。ソケットのもう一方の端は、を呼び出すことによって正常に閉じられたためclose
です。
今、私はその動作 (保留中のデータを読み取らずにソケットを閉じると ECONNRESET が生成される) を理解していますが、これはどこに文書化されていますか? man read
ECONNRESET については何も述べていませんが、次のように言及しています。
fd に接続されたオブジェクトによっては、その他のエラーが発生する場合があります。
UNIXドメインソケットのmanページには、次のように書かれています:
ECONNRESET: リモート ソケットが予期せず閉じられました。
しかし、Unix ドメイン ソケットはローカルの IPC であるため、このエラーが発生する可能性がある状況については、より具体的に説明できると思います。
私の「より深い考え」は次のようなものです:仕様が、たとえばclose
、ソケットから読み取るデータがない場合にのみストリームの終わりマークを生成すると言う場合、他のプロセスがちょうど書き込みしようとしていないかどうかをどのように知るのですか?いくつか?それは競合状態を作成しませんか?カーネルは、接続が正常に閉じられるかどうかをどのように認識しますか?