問題
ソケットプログラムを試していた際に何の前触れもなくSSL_writeの行で急に終了してしまいました。
終了コードを眺めてみると「141」という自分では定義したことがないコードでした。
$ echo $?
141
原因
wiresharkを眺めているとpeerからのTCP RSTを受けていて、コネクション切断されたあとにSSL_writeをしていると思われることがわかりました。
調べてみるとどうやら、コネクションが切れたソケットに書き込みを行うとSIGPIPEシグナルが発生しているとのことです。
SSL_writeのマニュアルには特に記載されていないが、write(2)のmanpageにはちゃんと記載されていました。
EPIPE
fd がパイプ (pipe) かソケット (socket) に接続されており、 その反対側 (読み込み側) がクローズ (close) されている。 これが発生した場合には、書き込みを行なうプロセスは SIGPIPE シグナル (signal)も受ける。 (したがって、プログラムがこのシグナルを捕獲 (catch)、停止 (block)、無視 (ignore) した場合のみ、write の返り値を参照できる。)
対処法
SIGPIPE時にhandler関数を追加することで、ハンドリングし突然終了しないようにしました。
#include <signal.h>
void handler(int signal) {
fprintf(stderr, "Client reveived %d signal\n", signal);
}
struct sigaction action;
sigset_t sigset;
sigemptyset(&sigset);
action.sa_handler = handler;
action.sa_flags = 0;
action.sa_mask = sigset;
sigaction(SIGPIPE, &action, NULL);
試せていませんが、この他にも以下の記事で紹介されているようにSIGPIPEを無視する方法も存在するようです。