TGViewer
LinuxCamp | DevOps LinuxCamp | DevOps @linuxcamp_tg · 13.6K subscribers
Post #147 5.68K
Перехватывай сигналы, как профи: sigaction()

Сегодня поговорим про вызов, который активно рекомендуется к использованию в качестве альтернативы примитивному signal(). Несмотря на то, что sigaction() сложнее в использовании, взамен он предоставляет большую гибкость:


#include <signal.h>

// Возвращает 0 при успешном завершении, –1 при ошибке
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);


Аргумент sig означает сигнал, который мы хотим перехватить. Значением может быть любой экземпляр, кроме SIGKILL или SIGSTOP.

Аргумент act — указатель на структуру, определяющую условия перехвата. Если нам необходимо получить актуальное значения, без изменений, можно указать NULL.

Аргумент oldact — это указатель на структуру такого же типа. Используется для возврата информации о предыдущих правилах перехвата. Если нам это неинтересно, можно также задать значение NULL.

Структура, на которую указывают аргументы act и oldact, выглядит следующим образом:


struct sigaction
{
/* Адрес обработчика */
void (*sa_handler)(int);

/* Адрес расширенного обработчика */
void (*sa_sigaction)(int, siginfo_t *, void *);

/* Сигналы, блокируемые во время вызова обработчика */
sigset_t sa_mask;

/* Флаги, контролирующие активацию обработчика */
int sa_flags;

/* Устарел и не должен использоваться */
void (*sa_restorer)(void);
};


Поле sa_handler соотносится с аргументом handler, передаваемым функции signal(). В данном поле указывается либо адрес обработчика либо одна из констант — SIG_IGN (сигнал будет проигнорирован) или SIG_DFL (процесс ответит дефолтным поведением на сигнал).

Поле sa_mask определяет список сигналов, блокируемых во время активации обработчика. После старта его выполнения, все сигналы из набора автоматически добавляются в сигнальную маску. После того, как произойдет возврат из обработчика, они автоматически удалятся.

Сделано это для того, чтобы никакой из сигналов не прервал выполнение обработчика.

Поле sa_flags — битовая маска, устанавливающая разные параметры, контролирующие обработку сигнала. Биты могут быть объединены в этом поле битовой операцией ИЛИ (|). Более детально ознакомиться с флагами можете в мануале.

Простой пример использования вызова sigaction():


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

void handle_signal(int sig) {
printf("Caught signal %d\n", sig);
}

int main() {
struct sigaction sa;
sa.sa_handler = handle_signal;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);

if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}

while (1);
}


И да, как видите, я проинициализировал почти все поля структуры. Если вы работаете на C, не забывайте, что это не C++ и тут нет конструкторов, деструкторов, дефолтной инициализации. Если явно не указать значения переменным, они могут спокойно заполниться мусором, что приведет к UB (undefined behavior).

Где sigaction() прям 100% полезен?

Мы с вами еще не говорили подробно о сигналах реального времени, но при работе с ними вам прям станет ясна необходимость sigaction(). Дело в том, что через настройку перехватчика мы cможем принимать дополнительные аргументы - пользовательские данные. Использовать для этого нам нужно флаг SA_SIGINFO:


sa.sa_flags = SA_SIGINFO;


Если флаг указан, обработчик должен присваиваться полю sa_sigaction и принимать расширенный интерфейс для пользовательских данных:


void handler(int sig, siginfo_t *info, void *context);
sa.sa_sigaction = handler;


LinuxCamp
  • 🔥 19
  • 👍 12
  • ❤‍🔥 6
More from @linuxcamp_tg
  1. Sep 28, 2026Проекту GNU вчера исполнилось 43 года 1983 год: Ричард Столлман объявил планы разработать…
  2. Sep 25, 2026Linux будет работать на ноутах с Snapdragon X2. Qualcomm добавляет полноценную поддержку L…
  3. Sep 24, 2026Так все по делу)) Советует же самый быстрый фикс LinuxCamp | #memes
  4. Sep 23, 2026Планы на 3 октября — прийти на RWB Infra x Security Meetup Мы направим прожекторы на инфра…
  5. Sep 22, 2026Ещё одна рекордная неделя для AI-разработки в Linux. На прошлой неделе в ядро попало 1 634…
  6. Sep 17, 2026Открыл плейлист, а как выйти - непонятно 😁 LinuxCamp | #memes
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →