在linux内核中创建一个/proc/下的文件结点实例http://www.lslnet.com/linux/dosc1/34/linux-259508.htm

来源:互联网 发布:手机游戏网络稳定软件 编辑:程序博客网 时间:2024/04/27 16:36
 
 
 

这个例子也是来自网上。现在能够编译,加载。
加载后通过echo将一段字符写入/proc/test。然后用cat看/proc/test。结果,在屏幕上不停的重复显示原来写入的字符串。不知道是为什么、?


#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/proc_fs.h>
#include<linux/string.h>
#include<linux/init.h>
#include<asm/uaccess.h>

char msg[512];

struct proc_dir_entry *my_proc_ptr=NULL;
int init_module(void);
int cleanup_module(void);


ssize_t our_read(struct file *file, char *buf, size_t size, loff_t *ppos)
{
int i;
for (i=0;msg[i];i++)
{
put_user(msg[i],buf+i);
}
return i;
}

static ssize_t our_write(struct file *file,const char *buf, size_t count, loff_t *ppos)
{
int i=0;
memset(msg,0,sizeof(msg));
for (i=0;i<count && i<512 -1;i++)
{
get_user(msg[i],buf+i);
}
msg[i]='\0';
return i;
}

struct file_operations fops={
read:our_read,
write:our_write,
};

int init_module(void)
{
my_proc_ptr=create_proc_entry("test",S_IRUSR|S_IWUSR,NULL);
my_proc_ptr->proc_fops=&fops;

return 0;
}

int cleanup_module(void)
{
remove_proc_entry("test",NULL);
return 0;
}



  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

ppos的值没有更新,所以文件当前位置指针原地未动

  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

好像不是啊,内容都完整的输出了,只不过循环输出。好像是read函数执行了无数次

  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

比如,文件大小为50bytes,ppos初始化值为0,你每次读50bytes,应该使ppos += 50;最后总会读到文件末尾然后正常退出,否则,你就只能没完没了的读这50bytes .
cat是要读到文件末尾才退出的,你不更新ppos无法到达文件末尾的

  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

搞不明白。

我在for 循环中增加了ppos++,情况依旧。

  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

static int create_egui_proc(void)
{
char name[10];
struct proc_dir_entry *ent;

memset (name,0,10);
sprintf(name, "egui");

ent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR,0);

if (!ent)
{
printk ("Egui create proc file /proc/egui, failed\n");
return 1;
}
printk ("Egui create proc file /proc/egui \n");
ent->data = NULL;
ent->read_proc = egui_read_proc;
ent->write_proc = egui_write_proc;
return 0;
}

/* start proc */
static int
egui_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
char *out = page;
int len;
window_list * list;
/* IMPORTANT: This output MUST be kept under PAGE_SIZE
* or we need to get more sophisticated. */

out += sprintf(out, "EGui proc file\n");
out += sprintf(out," cursor x,y :%d:%d\n", cursor_x, cursor_y);

list = find_list_by_xy (cursor_x,cursor_y);
if (list != NULL)
{
out += sprintf (out,"cursor window id = %d,pid=%d\n",list->id,list->pid);
}

len = out - page;
len -= off;
if (len < count) {
*eof = 1;
if (len <= 0)
return 0;
} else
len = count;

*start = page + off;

return len;
}

看看EGui的proc文件.

  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

我给的例子在2.6.xx没有问题.

2.4.xx没有测试过.

  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/init.h>
#include <asm/uaccess.h>

char msg[512];

struct proc_dir_entry *my_proc_ptr=NULL;
int _init_module(void);
void _cleanup_module(void);


ssize_t our_read(struct file *file, char *buf, size_t size, loff_t *ppos)
{
int i = 10;

//struct proc_dir_entry *dp = PROC_I(file->f_dentry->d_inode)->pde;
//if(dp->size < *ppos + 1)
// return 0;
if(*ppos > 500)
return 0;

for (i=0;i < size; i++) {
put_user(msg[i],buf+i);
*ppos = *ppos + 1;
}

return i;
}

static ssize_t our_write(struct file *file,const char *buf, size_t count, loff_t *ppos)
{
int i = 0;
memset(msg,0,sizeof(msg));
for (i=0;i<count && i<512 -1;i++)
{
get_user(msg[i],buf+i);
*ppos = *ppos + 1;
}
msg[i]='\0';
return i;
}

struct file_operations test_fops = {
read:our_read,
write:our_write,
};

int _init_module(void)
{
my_proc_ptr = create_proc_entry("test",S_IRUSR|S_IWUSR,NULL);
if(my_proc_ptr) {
my_proc_ptr->proc_fops = &test_fops;
my_proc_ptr->size = 128;
}

return 0;
}

void _cleanup_module(void)
{
remove_proc_entry("test",NULL);
//return 0;
}

module_init(_init_module);
module_exit(_cleanup_module);


  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

to woshiwo:


我按照你的例子修改,cat 文件时,不再是无穷输出,但是通
if ((*ppos)>100)
return 0;
退出来,无法解决不知道文件大小的情况下的问题。
我尝试过将return i改为return 0,cat能够正常输出,但是下面的文件操作程序就无法知道返回了多少内容。


另外:
我用下面的程序去访问,使可以正常访问的,无论是否有return 0,这中间 cat和下面的文件操作有什么区别呢 。
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int main(void)
{
int fd, i;
char buf[12] = "test proc";
fd = open("/proc/test3", O_RDWR);
if (fd < 0)
{
printf("open proc file err!\n");
return -1;
}
i = write(fd, buf, strlen(buf)); /*由write到核心调用我们前面our_write写proc文件*/
printf("write the buf : %s, len: %d\n", buf, i);

memset(buf, 0, sizeof(buf));
i = read(fd, buf, sizeof(buf)); /*由read到核心调用我们前面our_read读proc文件*/
printf("read the buf : %s, len: %d\n", buf, i);

close(fd);
printf("the buf : %s, i = %d\n", buf, i);

return 0;
}


  Re: 创建一个proc文件的例子,但是读proc文件时不停的循环输出,请帮忙找问题

我的改动只是为了解决无穷输出的问题,实际上这样做是很不规范的。
比较好的作法是:写操作的时候,用my_proc_ptr->size记录一共写入的字节数。读操作的时候,返回字节数应该为my_proc_ptr->size - *ppos 和size两者较小的那个。这跟普通文件的读写原则是一样的。

你原来的函数里
ssize_t our_read(struct file *file, char *buf, size_t size, loff_t *ppos)
{
int i;
for (i=0;msg[i];i++)
{
put_user(msg[i],buf+i);
}
return i;
}
只要msg非空,总能返回大于0的字节数,而cat正好是只要read返回非0就继续读,这样就没完没了的读下去了。

你的程序是不管read返回多少都只读一次,所以跟cat不一样