Функция send_signal
Функция send signal заносит новый элемент в очередь висящих сигналов.
Она принимает в качестве параметров номер сигнала sig, адрес info структуры siginfo t (или специальный код), адрес t дескриптора процесса- получателя и адрес signals очереди висящих сигналов.
Функция выполняет следующие действия:
1. Если параметр info равен 2, значит, послан сигнал sigkill или sigstop, и ОН был сгенерирован ядром С ПОМОЩЬЮ функции force_sig_specific. В таком случае описываемая функция переходит к шагу 9. Действия, являющиеся реакцией на эти сигналы, немедленно выполняются ядром, так что функция может не заносить сигнал в очередь висящих сигналов.
2. Если количество висящих сигналов у владельца процесса (t->user-> sigpending) не превышает лимит ресурсов текущего процесса ((t->signai-> rlim[RLIMIT_SIGPENDING] . rlim_cur), фуНКЦИЯ выделяет Структуру sigqueue для нового экземпляра сигнала:
q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
3. Если количество висящих сигналов у владельца процесса слишком велико, или попытка выделения памяти на предыдущем шаге закончилась неудачно, функция переходит к шагу 9.
4. Увеличивает количество висящих сигналов владельца (t->user-> sigpending) и счетчик ссылок структуры данных (отдельной у каждого пользователя), на которую указывает поле t->user.
5. Заносит структуру sigqueue В очередь ВИСЯЩИХ сигналов signals: list_add_tail(&q->list, &signals->list);
6. Заполняет таблицу siginfo t В структуре Sigqueue:
if ((unsigned long)info == 0) { q->info.si_signo = sig; q->info.si_errno = 0; q->info.si_code = SI_USER;
q->info._sifields._kill._pid = current->pid; q->info._sifields._kill._uid = current->uid;
} else if ((unsigned long)info == 1) { q->info.si_signo = sig; q->info.si_errno = 0; q->info.si_code = SI_KERNEL; q->info._sifields._kill._pid = 0; q->info._sifields._kill._uid = 0;
} else
copy_siginfo(&q->info, info);
Функция copy siginfo о копирует таблицу siginfo t, переданную при вызове.
7. Устанавливает бит, соответствующий сигналу, в битовой маске очереди: sigaddset(&signals->signal, sig);
8. Возвращает 0 (сигнал успешно добавлен в очередь висящих сигналов).
9. Если функция на этом шаге, значит, сигнал не будет занесен в очередь висящих сигналов, потому что висящих сигналов уже очень много, или для структуры sigqueue нет свободной памяти, или сигнал немедленно обрабатывается ядром. Если это сигнал реального времени, и он послан функцией ядра (то есть его обязательно нужно было поставить в очередь), функция возвращает код ошибки -eagain:
if (sig>=32 && info && (unsigned long) info != 1 && info->si_code != SI_USER) return -EAGAIN;
10. Устанавливает бит, соответствующий сигналу, в битовой маске очереди:
sigaddset(&signals->signal, sig);
11. Возвращает 0. Даже если сигнал не был добавлен в очередь, соответствующий бит в маске висящих сигналов был установлен.
Важно позволить процессу-получателю принять сигнал, даже если не нашлось места для нового элемента очереди сигналов. Предположим, например, что процесс занимает слишком много памяти. Ядро должно обеспечить успешное выполнение системного вызова kill о, даже если нет свободной памяти. В противном случае у системного администратора не будет возможности снять мешающий процесс и восстановить функционирование системы.
Предыдущая страница | 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 | Следующая страница