Вы здесь

Сигналы, группы, сеансы

Отправка сигнала

kill(pid,signum);

Если pid

  • > 0 - конкретному процессу
  • == 0 - всем членам группы
  • == -1 - всем процессам кроме init (в Linux'е еще кроме себя)
  • < -1 - группе с номером -pid

Если signum == 0 - сигнал не посылается, но делается проверка прав на посылку сигнала и формируются код ответа и errno.

alarm(time);

Отправка сигнала SIGALARM себе через time секунд. Возвращает 0 если ранее alarm не был установлен или число секунд остававшихся до срабатывания предыдущего alarma. Таймер управляющий alarm'ами один. Соответственно установка нового alarm'а отменяет старый. Параметр time==0 позволяет получить оставшееся до alarm'а время без установки нового.

Старый способ обработки сигнала

signal(SIGINT,sighandler);

sighandler - адрес функции обработчика void sighandler(int) или один из двух макросов: SIG_DFL (обработчик по умолчанию) или SIG_IGN (игнорирование сигнала).

signal(...) возвращает предыдущее значение обработчика или SIG_ERR в случае ошибки.

В Линуксе и SysV при вызове sighandler обработчик сбрасывается в SIG_DFL и возможна доставка нового сигнала во время работы sighandler. Такое поведение заставляет первой строкой в sighandler восстанавливать себя в качестве обработчика сигнала, и, даже в этом случае, не гарантирует от вызова обработчика по умолчанию. В BSD системах сброс не происходит, доставка новых сигнала блокируется до выхода из sighandler.

Пример кода:

#include <signal.h>
void sighandler(int signum) {
   signal(signum,sighandler);
   ...
}

main() {
      signal(SIGINT,sighandler);
      signal(SIUSR1,SIG_IGN);
      signal(SIUSR2,SIG_DFL);
}

Новый способ

Структуры данных

struct sigaction {
   void (*sa_handler)(int);                                 // Обработчик сигнала старого стиля
   void (*sa_sigaction)(int, siginfo_t *, void *); // Обработчик сигнала нового стиля
                                                                         // Обработчик выбирается на основе флага SA_SIGINFO
                                                                         // в поле sa_flags
   sigset_t sa_mask; // Маска блокируемых сигналов 
   int sa_flags; // Набор флагов
        //  SA_RESETHAND - сброс обработчика на SIG_DFL после выхода из назначенного обработчика.
        //  SA_RESTART - восстановление прерванных системных вызовов после выхода из обработчика.
        //  SA_SIGINFO - вызов sa_sigaction вместо sa_handler

  void (*sa_restorer)(void); // Устаревшее поле
}

siginfo_t {
  int      si_signo;  // Signal number
  int      si_errno;  // An errno value
  int      si_code;   // Signal code
  pid_t    si_pid;    // Sending process ID
  uid_t    si_uid;    // Real user ID of sending process
  int      si_status; // Exit value or signal
  clock_t  si_utime;  // User time consumed
  clock_t  si_stime;  // System time consumed
  sigval_t si_value;  // Signal value
  int      si_int;    // POSIX.1b signal
  void *   si_ptr;    // POSIX.1b signal
  void *   si_addr;   // Memory location which caused fault
  int      si_band;   // Band event 
  int      si_fd;     // File descriptor
}

Код

#include <signal.h>
void myhandler(int sig) {
   ...
}
void myaction(int signum, siginfo_t * siginfo, void *code)  {
...
}

main() {
struct sigaction act,oldact;
    act.sa_sigaction=myaction;
    act.sa_flags=SA_SIGINFO;
    sigaction(signum, &act, &oldact);
}

Блокирование сигналов

Все функции блокирования сигналов работают с маской сигналов типа sigset_t. Скорее всего это битовая маска длины int (т.е. не более 32х сигналов в 32х разрядной архитектуре)

Манипулирование маской

#include <signal.h>

int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); Изменить маску сигналов

Параметр how определяет операцию над текущей маской. Значения SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK.

int sigpending(sigset_t *set); // Получить список недоставленных из-за блокировки сигналов.
int sigsuspend(const sigset_t *mask);  //Установить новую маску и "уснуть" до получения допустимого сигнала.

Список сигналов Posix.1-1990

Источник - man 7 signal

   Signal     Value     Action   Comment
   -------------------------------------------------------------------------
   SIGHUP        1       Term    Hangup detected on controlling terminal
                                 or death of controlling process
   SIGINT        2       Term    Interrupt from keyboard
   SIGQUIT       3       Core    Quit from keyboard
   SIGILL        4       Core    Illegal Instruction
   SIGABRT       6       Core    Abort signal from abort(3)
   SIGFPE        8       Core    Floating point exception
   SIGKILL       9       Term    Kill signal
   SIGSEGV      11       Core    Invalid memory reference
   SIGPIPE      13       Term    Broken pipe: write to pipe with no readers
   SIGALRM      14       Term    Timer signal from alarm(2)
   SIGTERM      15       Term    Termination signal
   SIGUSR1   30,10,16    Term    User-defined signal 1
   SIGUSR2   31,12,17    Term    User-defined signal 2
   SIGCHLD   20,17,18    Ign     Child stopped or terminated
   SIGCONT   19,18,25    Cont    Continue if stopped
   SIGSTOP   17,19,23    Stop    Stop process
   SIGTSTP   18,20,24    Stop    Stop typed at tty
   SIGTTIN   21,21,26    Stop    tty input for background process
   SIGTTOU   22,22,27    Stop    tty output for background process