Замена обработчика сигнала SIGUSR1 работает по-разному в стандартах C11 и GNU11 - PullRequest
2 голосов
/ 05 января 2020

Я бы хотел изменить поведение обработчика сигнала SIGUSR1. Но я получаю разные результаты, используя разные стандарты C. Если я использую стандарт C11, мой обработчик сигнала заменяется на обработчик по умолчанию после получения этого сигнала один раз. Поэтому, если я посылаю сигнал SIGUSR1 процессу дважды, то во второй раз вместо моего вызывается обработчик SIGUSR1 по умолчанию. Но в стандарте GNU11 мой вызывается каждый раз. Как я могу получить это поведение, используя стандарт C11?

Вот мой код:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>

void noop(int signo)
{
    (void) signo;
}

int main(int argc, char **argv)
{
    (void) argc; (void) argv;

    if (signal(SIGUSR1, noop) == SIG_ERR)
    {
        perror("Can't register handler for signal SIGUSR1");
        exit(EXIT_FAILURE);
    }

    while (1);
}

Скомпилируйте эту программу со стандартом C11:

gcc signal.c -o signal_c11.out -std=c11 -O0 -Wall -Wextra -Wpedantic
./signal_c11.out

Или скомпилируйте это программа со стандартом GNU11:

gcc signal.c -o signal_gnu11.out -std=gnu11 -O0 -Wall -Wextra -Wpedantic
./signal_gnu11.out

На другом терминале выполните

kill -s SIGUSR1 <pid-of-above-process>
kill -s SIGUSR1 <pid-of-above-process>

Затем процесс из программы signal_c11.out завершится в соответствии с действием по умолчанию сигнала SIGUSR1. ; но процесс из программы signal_gnu11.out будет продолжаться, как я и ожидаю.

Как получить поведение gnu11 с использованием стандарта c11?

Ответы [ 2 ]

3 голосов
/ 06 января 2020

Поведение для signal() изменяется между семантикой System V и BSD на основе некоторых определений макросов тестирования функций (см. Портативность на этой странице руководства).

Основное различие в этом случае в том, что System V signal() автоматически сбрасывает обработчик при его вызове, а BSD этого не делает.

Используя sigaction(), вы можете установить ожидаемое поведение (не устанавливая SA_RESETHAND flag, возможно устанавливая флаг SA_RESTART).

Как сказано на справочной странице signal():

Поведение signal () варьируется в зависимости от версии UNIX и имеет также исторически различался в разных версиях Linux. Избегайте его использования: используйте вместо этого sigaction (2).

1 голос
/ 06 января 2020

Pass -D_DEFAULT_SOURCE до gcc. Этот флаг неявно определяется, если у вас не включена строгая совместимость со стандартами (т. Е. Нет -std=c* опций).

Это позволит получить все, что связано с C из gnu11, в c11. Тем не менее, он не получит никаких синтаксических вещей, таких как typeof или другие.

...