C言語,sigaction()関数でシグナル受信時の動作を設定

スポンサーリンク

鍛錬 790

C言語,sigaction()関数でシグナル受信時の動作を設定

シグナル受信時の動作を設定する方法の一つとして、sigaction()関数を使用する方法があります。
 
以下は、sigaction()関数についてです。

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
 

引数

以下は、上記の引数についてです。

引数 意味
int signum 設定の対象となる、SIGKILL, SIGSTOP 以外のシグナル
const struct sigaction *act signum 受信時の新しい動作を設定 (NULL以外の場合)
struct sigaction *oldact 今までの動作が格納される (NULL以外の場合)

構造体

以下は、sigaction 構造体についてです。

struct sigaction {
	void (*sa_handler)(int);
	void (*sa_sigaction)(int, siginfo_t *, void *);
	sigset_t sa_mask;
	int sa_flags;
	void (*sa_restorer)(void);
};
 

 
sa_handler:
signum に対する動作を指定する。

  • SIG_DFL の場合はデフォルトの動作を行う。
  • SIG_IGN の場合はシグナルを無視する。
  • シグナルハンドラ関数を使用する場合は、関数のポインタを設定する。

sa_mask:
シグナルハンドラの実行中にブロックするシグナルのマスク。

sa_flags:
シグナルハンドラの動作を変更するためのフラグ。

sa_restorer:
廃止予定であり、使用すべきではない。

戻り値

以下は、戻り値についてです。

戻り値
int 成功した場合 0
int エラーの場合 -1
 
スポンサーリンク

プログラム

以下は、シグナル受信時の動作を設定するプログラム、test_sigaction.c です。

シグナルハンドラでのデバッグについて、printf()は非同期シグナルセーフ関数ではないため、write()関数を使用してデバッグ文を出力しています。

今回は、次のシグナルを受信した際の動作を設定しています。

シグナル シグナルに対するプログラムの動作
SIGINT シグナルハンドラ関数で処理を行う
SIGQUIT シグナルを無視する(SIG_IGN)
SIGTSTP デフォルトの動作を行う(SIG_DFL)
// include
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

// prototype
void CheckSignal(int signum);

// main
int main(void)
{
	int cnt;
	int ret;
	struct sigaction act;
	
	memset(&act, '\0', sizeof(act));
	act.sa_flags = 0;
	
	// SIGINT
	act.sa_handler = CheckSignal;	// シグナルハンドラ関数を使用
//	act.sa_handler = SIG_IGN;		// 無視
//	act.sa_handler = SIG_DFL;		// デフォルト動作
	ret = sigaction(SIGINT, &act, NULL);
	if (ret == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}
	// SIGQUIT
//	act.sa_handler = CheckSignal;
	act.sa_handler = SIG_IGN;
//	act.sa_handler = SIG_DFL;
	ret = sigaction(SIGQUIT, &act, NULL);
	if (ret == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}
	// SIGTSTP
//	act.sa_handler = CheckSignal;
//	act.sa_handler = SIG_IGN;
	act.sa_handler = SIG_DFL;
	ret = sigaction(SIGTSTP, &act, NULL);
	if (ret == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}
	
	cnt = 0;
	while (cnt < 10) {
		sleep(6);
		cnt++;
	}
	
	return 0;
}

// ======================================================
// @brief  捕捉したシグナル番号を表示するシグナルハンドラ
// @param  signum [in],シグナル番号
// @return 無し
// @note   無し
// ======================================================
void CheckSignal(int signum)
{
	write(1, "\n", 1);
	switch (signum) {
		case SIGINT:
			write(1, "SIGINT\n", 7);
			break;
		case SIGQUIT:
			write(1, "SIGQUIT\n", 8);
			break;
		case SIGTSTP:
			write(1, "SIGTSTP\n", 8);
			break;
		default:
			break;
	}
}

実行結果

以下は、プログラム test_sigaction.c を実行しています。

シグナルを発生させるために、次の操作をキーボードで入力しています。

発生させるシグナル キーボード操作
SIGINT Ctrl + c
SIGQUIT Ctrl + \
SIG_DFL Ctrl + z
***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra test_sigaction.c -o test_sigaction
***@ubuntu:~/***/test/c$ ./test_sigaction
^C
SIGINT
^C
SIGINT
^C
SIGINT
^\
^\
^\
^Z
[7]+  停止                  ./test_sigaction

 
上記に示した通り、シグナル受信時の動作を設定することができました。

スポンサーリンク

シェアする

フォローする