この表は、POSIX が async-signal-safe であることを保証し、シグナル ハンドラから呼び出すことができるすべての関数を示しています。
この表の「書き込み」コマンドを使用することにより、次の比較的「醜い」ソリューションで問題が解決することが期待されます。
#include <csignal>
#ifdef _WINDOWS_
#define _exit _Exit
#else
#include <unistd.h>
#endif
#define PRINT_SIGNAL(X) case X: \
write (STDERR_FILENO, #X ")\n" , sizeof(#X ")\n")-1); \
break;
void catchSignal (int reason) {
char s[] = "Caught signal: (";
write (STDERR_FILENO, s, sizeof(s) - 1);
switch (reason)
{
// These are the handlers that we catch
PRINT_SIGNAL(SIGUSR1);
PRINT_SIGNAL(SIGHUP);
PRINT_SIGNAL(SIGINT);
PRINT_SIGNAL(SIGQUIT);
PRINT_SIGNAL(SIGABRT);
PRINT_SIGNAL(SIGILL);
PRINT_SIGNAL(SIGFPE);
PRINT_SIGNAL(SIGBUS);
PRINT_SIGNAL(SIGSEGV);
PRINT_SIGNAL(SIGTERM);
}
_Exit (1); // 'exit' is not async-signal-safe
}
編集: Windows でのビルド。
この 1 つのウィンドウをビルドしようとすると、「STDERR_FILENO」が定義されていないように見えます。ただし、ドキュメントから、その値は「2」のようです。
#include <io.h>
#define STDIO_FILENO 2
編集: 'exit' は、シグナル ハンドラからも呼び出されるべきではありません!
fizzerが指摘したように、上記の_Exitの呼び出しは、HUP や TERM などのシグナルに対する大ハンマー アプローチです。理想的には、これらのシグナルがキャッチされたときに、「volatile sig_atomic_t」タイプのフラグを使用して、終了する必要があることをメイン プログラムに通知できます。
以下は、検索で役立つことがわかりました。
- Unix シグナルプログラミング入門
- 従来のシグナルの拡張