* of the ioctl called and the parameter given to the;
* ioctl function.;
*;
* If the ioctl is write or read/write (meaning output;
* is returned to the calling process), the ioctl call;
* returns the output of this function.;
*/;
int device_ioctl(;
struct inode *inode,;
struct file *file,;
unsigned int ioctl_num,/* The number of the ioctl */;
unsigned long ioctl_param) /* The parameter to it */;
{;
int i
char *temp
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
char ch
#endif;
/* Switch according to the ioctl called */;
switch (ioctl_num) {;
case IOCTL_SET_MSG:;
/* Receive a pointer to a message (in user space);
* and set that to be the devices message. */;
/* Get the parameter given to ioctl by the process */;
temp = (char *) ioctl_param
/* Find the length of the message */;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
get_user(ch, temp)
for (i=0; ch && ibr temp) i,> get_user(ch, temp)
#else;
for (i=0; get_user(temp) && ibr temp) i,>
#endif;
/* Dont reinvent the wheel - call device_write */;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
device_write(file, (char *) ioctl_param, i, 0)
#else;
device_write(inode, file, (char *) ioctl_param, i)
#endif;
break
case IOCTL_GET_MSG:;
/* Give the current message to the calling;
* process - the parameter we got is a pointer,;
* fill it. */;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
i = device_read(file, (char *) ioctl_param, 99, 0)
#else;
i = device_read(inode, file, (char *) ioctl_param,;
99)
#endif;
/* Warning - we assume here the buffer length is;
* 100. If its less than that we might overflow;
* the buffer, causing the process to core dump.;
*;
* The reason we only allow up to 99 characters is;
* that the NULL which terminates the string also;
* needs room. */;
/* Put a zero at the end of the buffer, so it;
* will be properly terminated */;
put_user(, (char *) ioctl_param i)
break
case IOCTL_GET_NTH_BYTE:;
/* This ioctl is both input (ioctl_param) and;
* output (the return value of this function) */;
return Message[ioctl_param]
break
};
return SUCCESS
}
/* Module Declarations *************************** */;
/* This structure will hold the functions to be called;
* when a process does something to the device we;
* created. Since a pointer to this structure is kept in;
* the devices table, it cant be local to;
* init_module. NULL is for unimplemented functions. */;
struct file_operations Fops = {;
NULL, /* seek */;
device_read,;
device_write,;
NULL, /* readdir */;
NULL, /* select */;
device_ioctl, /* ioctl */;
NULL, /* mmap */;
device_open,;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0);
NULL, /* flush */;
#endif;
device_release /* a.k.a. close */;
}
/* Initialize the module - Register the character device */;
int init_module();
{;
int ret_val
/* Register the character device (atleast try) */;
ret_val = module_register_chrdev(MAJOR_NUM,;
DEVICE_NAME,;
&Fops)
/* Negative values signify an error */;
if (ret_val < 0) {;
printk ("%s failed with %dn",;
"Sorry, registering the character device ",;
ret_val)
return ret_val
};
printk ("%s The major device number is %d.n",;
"Registeration is a success",;
MAJOR_NUM)
printk ("If you want to talk to the device driver,n")
printk ("youll have to create a device file. n")
printk ("We suggest you use:n")
printk ("mknod %s c %d 0n", DEVICE_FILE_NAME,;
MAJOR_NUM)
printk ("The device file name is important, becausen")
printk ("the ioctl program assumes thats then")
printk ("file youll use.n")
return 0
};
/* Cleanup - unregister the appropriate file from /proc */;
void cleanup_module();
{;
int ret
/* Unregister the device */;
推荐阅读
- 在Linux系统下清除操作信息的记录
- Linux应用软件谈之远程桌面控制篇
- Linux服务器前台常出现的提示及含意
- Linux操作系统下的软中断问题分析
- 全面剖析Linux操作系统单用户方式
- Linux操作系统不同对象全面升级方法介绍
- Linux系统小型日程表挑战大型群件
- 加挂Linux操作系统中文件系统的小结
- 解读Linux系统下文件权限的设置方法
- 在Linux桌面上随意使用Windows的文档
