2011-02-04 10 views
1

私はLinux用の簡単なcharデバイスを書こうとしていますが、fread/fwriteでデバイスを読み書きし、fopenとfseekを使う必要があります。私は私のデバイスを使用するための簡単なテストプログラムを書いたし、fseek関数のfposは動作せず、fseekが現れた後freadを知らないことに気づいた。私はデバイスを動作させることができません。なぜなら、fseekはr +モードで開いたときに正しいファイル位置を得られないからです。fseek char linux device

感謝の人々

/* 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? 

答えて

2

あなたは、一般的な種類のバッファを持っているのstdio(freadは、fseek関数など)を使用しています。それは必ずしも直接syscallsに翻訳するとは限らないので、 "予期せぬ"読み込みとシークがあります。

関連する問題