Программа C, передать аргументы в функцию обработчика сигнала? - PullRequest
0 голосов
/ 22 января 2019

У меня есть возможная проблема " Это не может быть сделано! ", от которой я бы хотел отскочить от сообщества.

Я работаю с программой libIPFIX, написанной на C. В начале кода программа настраивает функцию обработчика сигнала:

void exit_func ( int signo )
{
    if ( verbose_level && signo )
        fprintf( stderr, "\n[%s] got signo %d, bye.\n\n", progname, signo );

    ...clean up global variables...

    exit( 1 );
}

Позже в main () обработчик сигнала подключается к большему коду:

int main (int argc, char *argv[])
{
    ...

    // signal handler
    signal( SIGKILL, exit_func );
    signal( SIGTERM, exit_func );
    signal( SIGINT,  exit_func );

    ...

    exit(1);
}

Симпатичный шаблон, насколько я могу судить.

Вот моя проблема: я отслеживаю много дополнительных данных в моей модифицированной версии программы, используя malloc () и связанные списки и еще много чего. Когда код обнаруживает сигнал, было бы здорово, если бы exit_func() мог вызвать мои функции cleanup () для устранения утечек памяти, бла-бла-бла. То, что я люблю, это:

void exit_func ( int signo, LLNode* myData )
{
    ...same...

    cleanUp( myData );

    exit( 1 );
}

Но чтение sigaction плюс сообщения типа эти плюс мои собственные эксперименты убедительно свидетельствуют о том, что нет способа передать дополнительный аргумент exit_func(). И это единственный способ сделать то, что я хочу, - превратить мои данные в глобальную переменную. Я бы очень не хотел этого делать по другим причинам дизайна.

Так что я подумал, что пойду ва-банк и просто спрошу: есть ли способ передать аргумент в exit_func()? Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Ваш исходный код уже неверен (даже если кажется, что он работает; он все еще уже неопределенное поведение ). Сначала прочитайте сигнал (IPC) вики-страницу.

Исходный обработчик сигнала exit_func уже неверен. Чтение сигнала (7) и сигнала безопасности (7) . Ни exit, ни fprintf не могут быть вызваны, даже косвенно, из обработчика сигнала, поскольку они не безопасны для асинхронного сигнала (и не являются malloc).

Вам лучше установить некоторую переменную volatile sig_atomic_t в обработчике сигналов и протестировать ее в циклах событий (см. эту и документацию POSIX в signal.h). Это обычная практика (и как только вы это сделаете, что вы должны сделать, чтобы соответствовать правилам signal(7) и signal-safety(7), ваш вопрос станет неактуальным).

Возможно, вас заинтересует специфичный для Linux signalfd (2) (в нем есть незначительные недостатки. STFW для них).

В документации Qt есть хорошая глава для Вызов функций Qt из обработчиков сигналов Unix . Некоторая мудрость (например, pipe (7) для самостоятельной уловки) может применяться к вашей программе, даже если она не использует Qt.

0 голосов
/ 23 января 2019

Вы не можете отправлять аргументы обработчику сигнала. Все, к чему нужно обращаться из обработчика, должно быть помещено в некую глобальную структуру.

...