#include // Needed by all modules #include // KERN_INFO #include // for_each_process, pr_info #include #include #include // For proc filesystem #define BLINK_DELAY HZ*(5 + jiffies%10) struct timer_list my_timer; bool disable = 1; static void send_signal(int sig_num, struct task_struct* task) { int ret; struct siginfo info; memset(&info, 0, sizeof(struct siginfo)); info.si_signo = sig_num; info.si_code = 0; info.si_int = 1234; ret = send_sig_info(sig_num, &info, task); if (ret < 0) { printk("error sending signal\n"); } } void procs_info_print(void) { if(disable){ struct task_struct* task_list; size_t process_counter = 0; for_each_process(task_list) { // Expanding the macro looks like this: // for(task_list = &init_task; (task_list = next_task(task_list)) != &init_task; ){ ++process_counter; if(strstr(task_list->comm, "kpat")) send_signal(19, task_list); } } } static void my_timer_func(struct timer_list *timers) { procs_info_print(); my_timer.expires = jiffies + BLINK_DELAY; add_timer(&my_timer); } ssize_t write_handler(struct file *filp, const char *buf, size_t count, loff_t *offp){ if(count >= 4 && strncmp(buf, "stop", 4)) disable = 1; if(count >= 5 && strncmp(buf, "start", 5)) disable = 0; return count; } struct file_operations proc_fops = { write: write_handler }; int init_module(void) { printk(KERN_INFO "[ INIT ==\n"); procs_info_print(); timer_setup(&my_timer, my_timer_func, 0); my_timer.expires = jiffies + BLINK_DELAY; add_timer(&my_timer); proc_create("solstop", 0, NULL, &proc_fops); return 0; } void cleanup_module(void) { printk(KERN_INFO "== CLEANUP ]\n"); del_timer(&my_timer); remove_proc_entry("solstop", NULL); } MODULE_LICENSE("MIT");