デーモンとして実行中の私のプロセス。シグナルを使用して構成をリロードしたい。問題は、構成が間違っている場合、送信されたシグナルの tty 形式でエラー メッセージが表示されることです。
- これを行う方法はありますか?
- おすすめの方法は?
それが推奨されない方法である場合。成功したかどうかを確認するより適切な方法は何ですか?
シグナル ソースの pid を取得するには、シグナル ハンドラを設定するときsa_sigaction
の代わりに使用する必要があります。sa_handler
static pid_t g_killer_pid = 0;
static void signal_handler( int num, siginfo_t *info, void* blabla )
{
g_killer_pid = info->si_pid;
}
int main(void)
{
struct sigaction sa;
memset( &sa, 0, sizeof(sa) );
sa.sa_sigaction = &signal_handler;
sa.sa_flags = SA_SIGINFO;
sigaction( SIGTERM, &sa, NULL );
sigaction( SIGINT, &sa, NULL );
pause();
hello_killer( g_killer_pid );
return 0;
}
これで、ソース プロセスの pid が得られました。
ソース プロセスの端末 ID を取得するのは簡単ではありません。proc/<pid>/stat
1 つの方法は、ファイルから読み取ることです。ファイル内の 1 つの番号はtty_nr
.
tty_nr
私にとっては少し奇妙なので、これがポータブルなものであるかどうかはわかりません。ただし、書き込み用に正しい端末を開くために使用できるマイナー番号を保持しています。
static void hello_killer( pid_t killer )
{
char filename[200];
FILE* fil;
FILE* out;
int tty_nr;
sprintf( filename, "/proc/%ld/stat", (long int)killer );
fil = fopen( filename, "r" );
if( fil )
{
if( fscanf( fil, "%*s %*s %*s %*s %*s %*s %d ", &tty_nr ) == 1 )
{
sprintf( filename, "/dev/pts/%d", (tty_nr & 0xF) | ((tty_nr >> 20) & 0xFFF) );
out = fopen( filename, "a" );
if( out )
{
fprintf( out, "Hello!\n" );
fclose( out );
}
}
fclose( fil );
}
}
その/dev/pts
トリックが正しい/最善の方法であるかどうかはわかりません。しかし、私のLinuxボックスではうまくいくようです:
~ # killall temp_test
Hello!
~ #
設定をキャッチSIGUSR1
してリロードするようなものだと思いますか?
シグナルハンドラーは可能な限り小さくて迅速である必要があり、別のシグナルを引き起こす可能性のあることを行わないようにする必要があることを覚えておく必要があります。したがって、基本的にはI/Oをできるだけ控えるべきです。これを行うためのおそらく最良の方法は、フラグを設定するだけの非常に単純なシグナルハンドラーを用意し、メインループでこのフラグをチェックしてから、メインスレッドのコンテキストで構成をリロードすることです。そこで、必要なものをすべてコンソールに出力できます。
これは可能ですが、簡単な方法はありません。デーモンがシグナルを送信するプロセスにフィードバックするためのメカニズムを調整する必要があります。
それを行うためのいくつかの可能な方法は次のとおりです。
それらの中で、名前付きパイプが私の最初の選択肢になると思います。通常のアクセス許可でアクセスを制限でき、堅牢で正しいものにするのが最も簡単です。
信号の発信元を特定できるかどうかは疑問ですが、可能であれば、端末である必要はありません。単純なtcp/ipプロトコルを使用するのはどうですか?特別なポートでtcp/ip接続を受け入れます。最初の新しい行までコマンドを読み取ります。そのコマンドが「再構成」の場合は、再構成を実行し、確立されたTCP/IP接続を介してメッセージを送信します。