Linux操作系统内核和设备文件对话(2)

2008-02-23 07:26:47来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
return 0;
#endif
}

  

/* This function is called whenever a process which
* has already opened the device file attempts to
* read from it. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
static ssize_t device_read(
struct file *file,
char *buffer, /* The buffer to fill with the data */
size_t length, /* The length of the buffer */
loff_t *offset) /* offset to the file */
#else
static int device_read(
struct inode *inode,
struct file *file,
char *buffer, /* The buffer to fill with the data */
int length) /* The length of the buffer
* (mustnt write beyond that!) */
#endif
{
/* Number of bytes actually written to the buffer */
int bytes_read = 0;

#ifdef DEBUG
printk("device_read(%p,%p,%d)\n",
file, buffer, length);
#endif

/* If were at the end of the message, return 0
* (which signifies end of file) */
if (*Message_Ptr == 0)
return 0;

/* Actually put the data into the buffer */
while (length && *Message_Ptr) {

/* Because the buffer is in the user data segment,
* not the kernel data segment, assignment wouldnt
* work. Instead, we have to use put_user which
* copies data from the kernel data segment to the
* user data segment. */
put_user(*(Message_Ptr ), buffer );
length --;
bytes_read ;
}

#ifdef DEBUG
printk ("Read %d bytes, %d left\n",
bytes_read, length);
#endif

/* Read functions are supposed to return the number
* of bytes actually inserted into the buffer */
return bytes_read;
}

  

/* This function is called when somebody tries to
* write into our device file. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
static ssize_t device_write(struct file *file,
const char *buffer,
size_t length,
loff_t *offset)
#else
static int device_write(struct inode *inode,
struct file *file,
const char *buffer,
int length)
#endif
{
int i;

#ifdef DEBUG
printk ("device_write(%p,%s,%d)",
file, buffer, length);
#endif

for(i=0; i
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
get_user(Message, buffer i);
#else
Message = get_user(buffer i);
#endif

Message_Ptr = Message;

/* Again, return the number of input characters used */
return i;
}

  

/* This function is called whenever a process tries to
* do an ioctl on our device file. We get two extra
* parameters (additional to the inode and file
* structures, which all device functions get): the number
* 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:

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:如何远程实现为Linux服务器添加新分区

下一篇:Linux应用软件谈之远程桌面控制篇