Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
Именно для этого сигнала мы ввели новый обработчик, функцию stop_daemon. Извлечем адрес этой функции из исполняемого файла sfc и сравним его с результатом, полученным при работе модуля:
# objdump -x ./sfc | grep stop_daemon
080484D8 g F .text 00000010 stop_daemon
Адрес функции stop_daemon – нового обработчика сигнала SIGUSR1 – равен 0x080484D8. Точно такое же значение выдал и модуль.
Согласитесь, что просто смотреть на процесс неинтересно. Давайте им управлять. Пошлем процессу sfc из модуля сигнал SIGUSR1, при получении которого процесс завершит свое выполнение.
Для того чтобы из ядра послать процессу сигнал, необходимо установить в структуре struct sigpending pending бит, соотвествующий порядковому номеру посылаемого сигнала, в единицу, а также присвоить единичное значение полю sigpending, которое служит индикатором того, что процесс получил сигнал и его надо обработать.
Перепишем функцию инициализации модуля – вместо отображения информации о процессе sfc модуль будет посылать ему сигнал SIGUSR1.
Функция инициализации модуля будет выглядеть следующим образом:
static int __init task_on(void)
{
struct task_struct *p;
Ищем процесс sfc:
p = find_task_by_name("sfc");
if(p) printk(KERN_INFO "PID - %d ", p->pid);
else {
printk(KERN_INFO "No such task ");
return 0;
}
В структуре struct sigpending pending устанавливаем бит, соответствующий сигналу SIGUSR1:
sigaddset(&p->pending.signal, SIGUSR1);
p->sigpending = 1; // индикатор прихода сигнала
return 0;
}
Функция sigaddset устанавливается в 1 бит с указанным номером. Номер бита передается как параметр функции. Эта функция (платформенно-зависимый вариант) определена в файле <asm-i386/signal.h>:
static __inline__ void sigaddset(sigset_t *set, int _sig)
{
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
}
Загрузив модуль, мы тем самым отправим процессу sfc сигнал SIGUSR1 и остановим его выполнение.
Кстати, совсем не обязательно переопределять обработчик сигнала в самом процессе – это можно сделать в модуле, вписав адрес нового обработчика непосредственно в поле sa_handler.
Посмотрим, как это делается. Перепишем функцию start_daemon процесса, убрав из нее переопределение обработчика сигнала SIGUSR1:
void start_daemon()
{
sigset_t mask;
sigfillset(&mask);
/* Блокируем все сигналы */