首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fseek char linux设备

fseek char linux设备
EN

Stack Overflow用户
提问于 2011-02-04 22:38:50
回答 1查看 1.3K关注 0票数 1

我正在尝试为linux编写一个简单的char设备,我需要通过fread/fwrite来读写该设备,并使用fopen和fseek。我已经写了一个简单的测试程序来使用我的设备,并且我已经注意到fseek函数中的fpos不起作用,并且在fseek出现后不知道fread。我无法让设备工作,因为fseek在r+模式下打开时没有得到正确的文件位置,如果我使用在w模式下打开的文件,那么除了fread之外,所有的东西都可以工作。

谢谢大家

代码语言:javascript
复制
/* 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?
EN

回答 1

Stack Overflow用户

发布于 2011-02-05 00:02:09

您正在使用stdio (fread、fseek等)其通常具有各种类型的缓冲器。它不一定直接转换为syscall,因此出现了“意外”的读取和查找。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4899215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档