/* * fcluster.c */ #include <linux/init.h> #include <linux/module.h> #include <linux/signal.h> #include <linux/spinlock.h> #include <linux/sched.h> #include <linux/uaccess.h> static int remove_mod = 0; static int my_sigpending(sigset_t *set) { int (*sigpending)(sigset_t *set); int ret; mm_segment_t old_fs; sigpending = (typeof(sigpending))0xffffffff810802e0; old_fs = get_fs(); set_fs(get_ds()); ret = sigpending(set); set_fs(old_fs); return ret; } static int thread_process(void *arg) { sigset_t *sigset, __sigset; sigset = &__sigset; allow_signal(SIGURG); allow_signal(SIGTERM); allow_signal(SIGKILL); allow_signal(SIGSTOP); allow_signal(SIGCONT); printk(KERN_ALERT "the pid of thread_process is %d.\n", current->pid); my_sigpending(sigset); printk(KERN_ALERT "Before receive signal, signal map: 0x%lX.\n", sigset->sig[0]); for ( ; !remove_mod; ) { /* Avoid infinite loop */ msleep(1000); if (signal_pending(current)) { my_sigpending(sigset); printk(KERN_ALERT "Received signal, signal map: 0x%lX.\n", sigset->sig[0]); printk(KERN_ALERT "Receive SIGURG signal ? %s.\n", sigismember(sigset, SIGURG) ? "true" : "false"); printk(KERN_ALERT "Receive SIGTERM signal ? %s.\n", sigismember(sigset, SIGTERM) ? "true" : "false"); printk(KERN_ALERT "Receive SIGKILL signal ? %s.\n", sigismember(sigset, SIGKILL) ? "true" : "false"); printk(KERN_ALERT "Receive SIGSTOP signal ? %s.\n", sigismember(sigset, SIGSTOP) ? "true" : "false"); /* Use halt to stop the system */ printk(KERN_ALERT "Receive SIGCONT signal ? %s.\n", sigismember(sigset, SIGCONT) ? "true" : "false"); break; } } return 0; } static int __init fcluster_init(void) { kernel_thread(thread_process, NULL, CLONE_FILES); return 0; } static void __exit fcluster_exit(void) { remove_mod = 1; msleep(2000); } MODULE_LICENSE("GPL"); module_init(fcluster_init); module_exit(fcluster_exit); |