Энциклопедия разработчика модулей ядра Linux | страница 30
>asmlinkage int our_sys_open(const char *filename, int flags, int mode) {
> int i = 0;
> char ch;
> /* Check if this is the user we're spying on */
> if (uid == getuid_call()) {
> /* getuid_call is the getuid system call,
> * which gives the uid of the user who
> * ran the process which called the system
> * call we got */
> /* Report the file, if relevant */
> printk("Opened file by %d: ", uid);
> do {
>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
> get_user(ch, filename+i);
>#else
> ch = get_user(filename+i);
>#endif
> i++;
> printk("%c", ch);
> } while (ch != 0);
> printk("\n");
> }
> /* Call the original sys_open - otherwise, we lose
> * the ability to open files */
> return original_call(filename, flags, mode);
>}
>/* Initialize the module - replace the system call */
>int init_module() {
> /* Warning - too late for it now, but maybe for next time... */
> printk("I'm dangerous. I hope you did a ");
> printk("sync before you insmod'ed me.\n");
> printk("My counterpart, cleanup_module(), is even");
> printk("more dangerous. If\n");
> printk("you value your file system, it will ");
> printk("be \"sync; rmmod\" \n");
> printk("when you remove this module.\n");
> /* Keep a pointer to the original function in
> * original_call, and then replace the system call
> * in the system call table with our_sys_open */
> original_call = sys_call_table[__NR_open];
> sys_call_table[__NR_open] = our_sys_open;
> /* To get the address of the function for system
> * call foo, go to sys_call_table[__NR_foo]. */
> printk("Spying on UID:%d\n", uid);
> /* Get the system call for getuid */
> getuid_call = sys_call_table[__NR_getuid];
> return 0;
>}
>/* Cleanup - unregister the appropriate file from /proc */
>void cleanup_module() {
> /* Return the system call back to normal */
> if (sys_call_table[__NR_open] != our_sys_open) {
> printk("Somebody else also played with the ");
> printk("open system call\n");
> printk("The system may be left in ");
> printk("an unstable state.\n");
> }
> sys_call_table[__NR_open] = original_call;
>}
Отложенные процессы
Что Вы делаете, когда кто-то просит Вас о чем-то, что Вы не можете сделать сразу же? Если вы человек, и вы обеспокоены, единственное, что Вы можете сказать: «Не сейчас, я занят.». Но если вы модуль, Вы имеете другую возможность. Вы можете поместить процесс в спячку, чтобы он бездействовал, пока Вы не сможете обслужить его. В конце концов, процессы помещаются в спячку и пробуждаются ядром постоянно.
Этот модуль является примером этого подхода. Файл (названный /proc/sleep) может быть открыт только одним процессом сразу. Если файл уже открыт, модуль называет module_interruptible_sleep_on