[TCP/IP] ソケットシグナル

シグナルとは、ユーザによる割り込み文字の入力やタイマーの期限切れといった特定イベントの発生をプログラムに伝える仕組み

### 実行中のプログラムのシグナルへの対処パターン
1. 無視、感知しない
2. OSにより強制終了
3. シグナル処理関数が実行される。メインスレッドとは別の制御スレッドで実行
4. シグナルをブロック ブロックの対象はマスクで決める

### unixのシグナル
SIGALRM, SIGCHLD, SISINT, SIGIO, SIGPIPE

シグナルのデフォルト動作を変更するにはsigaction()を実行する
int sigaction(int whichSignal, const struct sigaction *newAction, struct sigaction *oldAction)

sigaction構造体
struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
}

シグナルはネストできる
sa_maskはboolean型の集合
int sigemptyset(sigset_t *set)
int sigfillset(sigset_t *set)
int sigaddset(sigset_t *set, int whichSignal)
int sigdelset(sigset_t *set, int whichSignal)

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void DieWithError(char *errorMessage); /* エラー処理関数 */
void InterruptSignalHandler(int signalType); /* 割り込みシグナル処理関数 */

int main(int argc, char *argv[]) {
    struct sigaction handler; /* シグナルハンドラを指定する構造体 */

    /* InterruptSignalHandler()をハンドラ関数として設定 */
    handler.sa_handler = InterruptSignalHandler;
    /* 全シグナルをマスクするマスクを作成 */
    if (sigfillset(&handler.sa_mask) < 0)
        DieWithError("sigfillset() failed");
    /* フラグなし */
    handler.sa_flags = 0;

    /* 割り込みシグナルに対する処理を設定 */
    if(sigaction(SIGINT, &handler, 0) < 0) 
        DieWithError("sigaction() failed");

    for(;;)
        pause(); /* シグナルを受け取るまでプログラムを一時停止 */

    exit(0);
}

void InterruptSignalHandler(int signalType) {
    printf("Interrupt Received. Exiting program. \n");
    exit(1);
}