このsignal()
関数は、プロセスが設定した可能性のある他のシグナル呼び出しを上書きしますか?つまり、SIGINT
ハンドラーがプロセスによってセットアップされ、DLLがsignal(SIGINT,xxx)
独自の終了コードを処理するために呼び出す場合、元のSIGINT
ハンドラーは無効になりますか?
2 に答える
signal()
呼び出し:
- 指定したハンドラーを新しいシグナルハンドラーとしてインストールし、
- 古いハンドラーが何であったかを教えてくれます。
古いハンドラーの代わりに新しいハンドラーが呼び出されます。それらを連鎖させたい場合は、次のようなことを行う必要があります。
typedef void (*Handler)(int signum);
static Handler old_int_handler = SIG_IGN;
static void int_handler(int signum) /* New signal handler */
{
/* ...do your signal handling... */
if (old_int_handler != SIG_IGN && old_int_handler != SIG_DFL)
(*old_int_handler)(signum);
}
static void set_int_handler(void) /* Install new handler */
{
Handler old = signal(SIGINT, SIG_IGN);
if (old != SIG_IGN)
{
old_int_handler = old;
signal(SIGINT, int_handler);
}
}
static void rst_int_handler(void) /* Restore original handler */
{
Handler old = signal(SIGINT, SIG_IGN);
if (old == int_handler)
{
signal(SIGINT, old_int_handler);
old_int_handler = SIG_IGN;
}
}
void another_function()
{
/* ... */
set_int_handler();
/* ... */
rst_int_handler();
/* ... */
}
割り込みが無視されていた場合、これにより割り込みは無視されたままになります。割り込みがユーザー定義の割り込みハンドラーによって処理されていた場合、これはシグナル処理コードと元のシグナル処理コードを呼び出します。
DLL(共有ライブラリ)でシグナルを処理しないことに関するChristian.Kからのアドバイスも関連性があり、有効であることに注意してください。上記の説明は、そのアドバイスを無視することにしたことを前提としています。
これはあなたの質問に対する「文字通りの」答えではありませんが、推奨事項です。DLLでこれを行うべきではありません。
これは、DLLを使用するアプリケーションにとって予期せぬことであり、多くの場合煩わしいものです。DLLは(通常)「パッシブ」であり、アプリケーションが呼び出す関数のみを提供する必要があります。
したがって、DLLからパブリック関数を提供して、アプリケーションが呼び出す必要があるようにしますMyDllCleanup()
。次に、アプリケーションにその関数を呼び出す方法を決定させます(シグナルハンドラーまたはその他を介して)。ところで、同じことが初期化にも当てはまります。UNIXに依存するDllMain
(またはUNIXでは_init
/_fini
をlibdl
使用する)のではなく、アプリケーションが呼び出す明示的な関数を提供します。