Повторный запуск системного вызова для обработанного сигнала
Если сигнал обрабатывается, функция handie signai о анализирует код ошибки и, возможно, флаг sa restart в таблице sigaction, чтобы принять решение об автоматическом повторении неоконченного системного вызова:
if (regs->orig_eax >=0) { switch (regs->eax) {
case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->eax = -EINTR; break; case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) { regs->eax = -EINTR; break;}
/ fallthrough / case -ERESTARTNOINTR:
regs->eax = regs->orig_eax; regs->eip -= 2;}}
Если ВЫЗОВ должен быть повторен, функция handle_signal действует в точности, как функция do signai о; в противном случае она возвращает процессу режима пользователя код ошибки -eintr.
Системные вызовы, связанные с обработкой сигналов
Как было сказано во введении к этой главе, программам, работающим в режиме пользователя, разрешено посылать и принимать сигналы. Отсюда следует необходимость определения некоторого набора системных вызовов, обеспечивающих выполнение подобных операций. К сожалению, в силу исторических причин существует несколько системных вызовов, служащих фактически той же цели. В результате некоторые из них остаются невостребованными. Например, СИСТеМНЫе ВЫЗОВЫ sys_sigaction И sys_rt_ sigaction о практически идентичны, и поэтому интерфейсная функция sigaction о, включенная в библиотеку С, в конечном счете, вызывает sys_rt_sigaction, а не sys sigaction(). В следующих разделах мы опишем некоторые из наиболее важных системных вызовов.
Системный вызов killQ
Системный вызов kin (pid,sig) широко применяется для отправки сигналов обычным процессам или многопоточным приложениям. Его служебной процедурой является функция sys kiiio. Целочисленный параметр pid имеет разный смысл, в зависимости от своего числового значения:
- pid >0 — сигнал sig посылается группе потоков, содержащей процесс, у которого идентификатор PID равен pid;
- pid = 0 — сигнал sig посылается всем группам потоков в той же группе процессов, что и вызывающий процесс;
- pid = -1 — сигнал посылается всем процессам, кроме (PID 0), init (PID 1)
И current;
- pid tgid; info._sifields._kill._uid = current->uid; return kill_something_info(sig, Sinfo, pid);
Функция kiii_something_info(), в свою очередь, вызывает либо функцию kiii_proc_info() (чтобы послать сигнал одной группе потоков при помощи функции group send sig infо ), Либо фуНКЦИЮ kill pg info (чтобы перебрать все процессы в целевой группе процессов и вызвать функцию
send_sig_info ДЛЯ КЭЖДОГО ИЗ НИХ), Либо фуНКЦИЮ group_send_sig_info(),
причем последняя вызывается для каждого процесса в системе (если параметр pid равен -1).
Системный вызов kill о способен послать любой сигнал, даже так называемые сигналы реального времени, номера которых лежат в диапазоне от 32 до 64. Однако, как мы видели в разд. "Генерирование сигнала” ранее в этой главе, системный вызов kill о не гарантирует добавление нового элемента в очередь висящих сигналов процесса-получателя, так что повторные экземпляры висящих сигналов могут быть потеряны. Сигналы реального времени следует посылать, например, с помощью системного вызова rt sigqueueinfo о
В таких Unix-подобных системах, как System V и BSD, имеется дополнительный системный вызов kiiipgo, который может явным образом послать сигнал группе процессов. В Linux эта возможность реализована в виде библиотечной функции, делающей системный вызов kill о. Еще одной возможностью является функция raise , которая посылает сигнал текущему процессу (то есть процессу, который ее выполняет). В Linux она реализована в виде библиотечной функции.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница