fseek char linux 设备
Posted
技术标签:
【中文标题】fseek char linux 设备【英文标题】:fseek char linux device 【发布时间】:2011-02-04 14:38:49 【问题描述】:我正在尝试为 linux 编写一个简单的 char 设备,我需要通过 fread/fwrite 读写设备并使用 fopen 和 fseek。我已经编写了一个简单的测试程序来使用我的设备,并且我注意到 fseek 函数中的 fpos 不起作用并且 fseek 出现后不知道 fread 。我无法让设备正常工作,因为 fseek 在 r+ 模式下打开时没有获得正确的文件位置,如果我使用在 w 模式下打开的文件,除了 fread 之外一切正常。
谢谢大家
/* Makefile */
obj-m += char.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
/* char device char.c */
// to complie:
// # make
// # insmod char.ko
// # dmesg
// (to get majornumber)
// # mknod /dev/dp0 c majornumber 0
// # ./test
// # dmesg
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
int char_init (void);
void char_exit (void);
int char_open (struct inode *, struct file *);
int char_release (struct inode *, struct file *);
ssize_t char_read (struct file *, char __user *, size_t, loff_t *);
ssize_t char_write (struct file *, const char __user *, size_t, loff_t *);
loff_t char_llseek (struct file *, loff_t, int);
int char_open (struct inode *inode, struct file *fp)
printk ("f_mode=%d f_pos=%d\n", (int) fp->f_mode, (int)fp->f_pos);
return 0;
int char_release (struct inode *inode, struct file *fp)
return 0;
ssize_t char_read (struct file *fp, char __user *buff, size_t count, loff_t *fpos)
printk ("char_read() fp->f_pos=%d\n", (int) fp->f_pos);
return count;
ssize_t char_write (struct file *fp, const char __user *buff, size_t count, loff_t *fpos)
printk ("char_write() fp->f_pos=%d\n", (int) fp->f_pos);
return count;
loff_t char_llseek (struct file *fp, loff_t fpos, int whe)
printk ("char_llseek() fpos=%d\n ", (int) fpos);
fp->f_pos = fpos;
return fpos;
struct file_operations char_fops =
.owner = THIS_MODULE,
.open = char_open,
.release = char_release,
.read = char_read,
.write = char_write,
.llseek = char_llseek,
.ioctl = NULL,
;
/* the char device */
struct cdev cdev;
int char_init ()
dev_t mm;
int mj, mi, ret;
mi = 0;
ret = alloc_chrdev_region (&mm, mi, 1, "dp0");
mj = MAJOR(mm);
cdev_init (&cdev, &char_fops);
ret = cdev_add (&cdev, mm, 1);
if (ret<0)
printk ("char: unable to add device\n");
return -1;
printk ("char: device added major=%d\n", mj);
return 0;
void char_exit ()
cdev_del(&cdev);
printk ("char: device deleted\n");
module_init(char_init);
module_exit(char_exit);
/* test program test.c */
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[])
int ret;
FILE *fp;
fp = fopen ("/dev/dp0", "r+");
if (fp == NULL)
printf ("open failed\n");
return -1;
int x;
x= fseek (fp, 1, SEEK_SET);
printf("ret fseek=%d\n", x);
fseek (fp, 1, SEEK_SET);
fwrite ("\0", 1, 1, fp);
fseek (fp, 2, SEEK_SET);
fread (&ret, 1, 1, fp);
printf ("DONE\n");
fclose (fp);
return 0;
// this is my dmesg:
f_mode=31 f_pos=0 // this is my fopen
char_llseek() fpos=0 // this is my first fseek but why fpos=0? it should be 1
char_read() fp->f_pos=0 // what's that?
char_llseek() fpos=0 //this is my second fseek but why fpos is 0 again?
char_read() fp->f_pos=0 // I suppose this is my fread fpos=0?
char_llseek() fpos=-4095 // what's that?
char_llseek() fpos=-4095 // What's that too?
char_llseek() fpos=-4095 // What's that too?
【问题讨论】:
【参考方案1】:您正在使用通常具有各种缓冲区的 stdio(fread、fseek 等)。它可能不一定直接转换为系统调用,因此会发生“意外”读取和查找。
【讨论】:
以上是关于fseek char linux 设备的主要内容,如果未能解决你的问题,请参考以下文章