在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;
}
ppos的值没有更新,所以文件当前位置指针原地未动
好像不是啊,内容都完整的输出了,只不过循环输出。好像是read函数执行了无数次
比如,文件大小为50bytes,ppos初始化值为0,你每次读50bytes,应该使ppos += 50;最后总会读到文件末尾然后正常退出,否则,你就只能没完没了的读这50bytes .
cat是要读到文件末尾才退出的,你不更新ppos无法到达文件末尾的
搞不明白。
我在for 循环中增加了ppos++,情况依旧。
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文件.
我给的例子在2.6.xx没有问题.
2.4.xx没有测试过.
#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);
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;
}
我的改动只是为了解决无穷输出的问题,实际上这样做是很不规范的。
比较好的作法是:写操作的时候,用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就继续读,这样就没完没了的读下去了。
- 在linux内核中创建一个/proc/下的文件结点实例http://www.lslnet.com/linux/dosc1/34/linux-259508.htm
- nginx在Centos下的安装,转:http://www.linuxidc.com/Linux/2016-09/134907.htm
- Linux下轻松实现PDF文件的合并 转自:http://www.linuxidc.com/Linux/2007-10/8585.htm
- linux 在proc文件系统下创建文件
- http://www.linuxidc.com/Linux/2011-08/40169.htm
- http://www.linuxidc.com/Linux/2010-05/26206.htm
- http://www.linuxidc.com/Linux/2012-01/52138.htm
- http://www.linuxidc.com/Linux/2014-06/102856.htm
- http://www.linuxidc.com/Linux/2014-09/106310.htm
- http://www.linuxidc.com/Linux/2013-07/86999.htm
- http://www.linuxidc.com/Linux/2015-05/117920.htm
- http://www.linuxidc.com/Linux/2012-10/72284.htm
- linux proc下创建文件
- 通过XShell链接虚拟机的CentOS http://www.linuxidc.com/Linux/2013-02/79574.htm
- cmake安装等,(红帽linux下)http://www.linuxidc.com/Linux/2012-10/72216.htm
- Linux下快速搭建ntp时间同步服务器(转载:http://www.linuxidc.com/Linux/2014-07/104371.htm)
- linux 创建proc 文件
- linux mkdir http://www.linuxidc.com/Linux/2011-04/35180.htm
- extern 用法汇集
- python装饰器
- 我们结婚吧!让我陪你一辈子
- android Layout (复杂一点的)(嵌套)
- vs2005下的编码转码
- 在linux内核中创建一个/proc/下的文件结点实例http://www.lslnet.com/linux/dosc1/34/linux-259508.htm
- 关于读书:读XX书是否为时过早,是否有意义
- Jquery easyui datagrid 模板,动态切换表头
- tornado registry的问题--无法找到序数
- 确保已安装项目类型(.csproj)的应用程序
- c#filestream与streamwriter用法
- pthread多线程编程整理
- kindle touch使用,多亏有了calibre
- 使用Samba访问windows的共享目录