Книга: Linux программирование в примерах

10.6.7. Передача сигналов: kill() и killpg()

10.6.7. Передача сигналов: kill() и killpg()

Традиционная функция Unix для передачи сигналов называется kill(). Имя несколько неправильное; все, что она делает — отправляет сигнал. (Результатом этого часто является завершение получателя сигнала, но это не обязательно верно. Однако, теперь слишком поздно менять имя.) Функция killpg() посылает сигнал определенной группе процессов. Объявления следующие:

#include <sys/types.h> /* POSIX */
#include <signal.h>
int kill(pid_t pid, int sig);
int killpg(int pgrp, int sig); /* XSI */

Аргумент sig является либо именем сигнала, либо 0. В последнем случае сигнал не посылается, но ядро все равно осуществляет проверку ошибок. В частности, это правильный способ проверки существования данного процесса или группы, а также проверки того, что у вас есть разрешение на передачу сигналов процессу или группе процессов kill() возвращает 0 в случае успеха и -1 при ошибке; errno указывает на проблему.

Правила для значения pid несколько запутаны:

pid > 0   pid является номером процесса, и сигнал посылается этому процессу

pid = 0   Сигнал посылается каждому процессу в группе посылающего процесса.

pid = -1  Сигнал посылается каждому процессу в системе, за исключением специальных системных процессов. Применяется проверка прав доступа. На системах GNU/Linux исключается лишь процесс init (PID 1), но у других систем могут быть другие специальные процессы.

pid < -1  Сигнал посылается группе процессов, представленной абсолютным значением pid. Таким образом, вы можете отправить сигнал всей группе процессов, дублируя возможности killpg(). Эта неортогональность обеспечивает историческую совместимость.

Значение pid для kill() сходно со значением для waitpid() (см. раздел 9.1.6.1 «Использование функций POSIX: wait() и waitpid()»).

Стандартная функция С raise() в сущности эквивалентна

int raise(int sig) {
 return kill(getpid(), sig);
}

Комитет по стандартизации С выбрал имя raise(), поскольку С должен работать также в окружениях, не относящихся к Unix, a kill() была сочтена специфичной для Unix функцией. Представилась также возможность дать этой функции более описательное имя.

killpg() посылает сигнал группе процессов. Пока значение pgrp превышает 1, эта функция эквивалентна 'kill(-pgrp, sig)'. Справочная страница GNU/Linux killpg(2) утверждает, что если pgrp равно 0, сигнал посылается группе отправляющего процесса (Это то же самое, что и kill().)

Как вы могли представить, нельзя послать сигнал произвольному процессу (если вы не являетесь суперпользователем, root). Для обычных пользователей действительный или эффективный UID отправляющего процесса должен соответствовать действительному или сохраненному set-user-ID получающего процесса. (Различные UID описаны в разделе 11.1.1 «Действительные и эффективные ID».)

Однако SIGCONT является особым случаем: пока получающий процесс является членом того же сеанса, что и отправляющий, сигнал пройдет. (Сеансы были кратко описаны в разделе 9.2.1 «Обзор управления заданиями».) Это особое правило позволяет управляющей заданиями оболочке продолжать остановленные процессы-потомки, даже если этот остановленный процесс имеет другой ID пользователя.

Оглавление книги


Генерация: 1.781. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз