参数
====
1. 如果你决定使用缓冲区,数据应该被插入它。
2. 字符指针的指针。如果你不想使用由内核分配的缓冲区时这将有用。
3. 文件的当前位置。
4. 第一个参数中的缓冲区的大小。
5. Zero (为将来使用?)。
用法和返回值
============
如果你像我那样使用自己的缓冲区,将它放在第二个参数的位置并返回在那个缓冲区中使用的字节数。
返回值为0 意味着这次没有更多信息(文件尾)。负数返回值是错误条件。
更多信息
========
我不是通过读文档而发现用这个函数去做什么的,而是通过读使用它的代码。我只想看看什么使用了
proc_dir_entry的get_info成员(如果你有兴趣的话,我使用了一个查找和搜索的组合),我发现它被
<内核源文件目录>/fs/proc/array.c使用。
如果有什么关于内核的事情不清楚,这是一个通常的办法。在 Linux 中我们有自由的获取源代码的巨大优势--使用它。
*/
int procfile_read(char *buffer,
char **buffer_location,
off_t offset,
int buffer_length,
int zero)
{
int len; /* The number of bytes actually used
*/
/* 这是静态的,因此当我们离开这个函数时它还会待在内存中 */
static char my_buffer[80];
static int count = 1;
/* 我们将所有的信息放在一个里面,所以如果用户问是否有更多的信息,答案总是“没有”。
*
* 这是很重要的,因为来自库的标准读函数将持续发布读系统调用直到内核答复没有更多信息
* 或它的缓冲区被填满。
*/
if (offset > 0)
return 0;
/* 填充缓冲区并得到长度 */
len = sprintf(my_buffer,
"For the %d%s time, go away!\n", count,
(count % 100 > 10 && count % 100
< 14) ? "th" :
(count % 10 == 1) ? "st" :
(count % 10 == 2) ? "nd" :
(count % 10 == 3) ? "rd" : "th"
);
count++;
/* 告诉调用函数缓冲区在哪儿*/
*buffer_location = my_buffer;
/* 返回长度 */
return len;
}
struct proc_dir_entry Our_Proc_File =
{
0, /* 节点数 - 忽略,它将被 proc_register[_dynamic] 填充*/
4, /* 文件名长度 */
"test", /* 文件名*/
S_IFREG | S_IRUGO, /* 文件模式 - 这是一个可以被拥有者,用户组和其他所有的用户读取的
* 普通文件 */
1, /* 连接数 (文件被引用的目录数) */
0, 0, /* 文件的UID和GID - 我们将它赋予 root */
80, /* 用ls报告的文件大小。 */
NULL, /* 使用节点的函数(连接,删除,等等)--我们不支持 */
procfile_read, /* 对这个文件的读函数,当某人试图葱它读入什么时被调用。
*/
NULL /* 我们能够在这儿有一个填充文件节点的函数,允许我们修改权限和拥有权,等等。
*/
};
/* 初始化模块--登记 proc 文件 */
int init_module()
{
/* proc_register[_dynamic] 成功则成功,否则失败。 */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
/* 在 2.2版中,如果在这个结构中它为0则 proc_register 自动的分配一个动态的节点数
* 因此不再需要proc_register_dynamic
*/
return proc_register(&proc_root, &Our_Proc_File);
#else
return proc_register_dynamic(&proc_root,
&Our_Proc_File);
#endif
/* proc_root 是 proc文件系统的根目录。这是我们想让我们的文件所处的位置
*/
}
/* 清除 - 从 /proc中注销我们的文件 */
void cleanup_module()
{
proc_unregister(&proc_root, Our_Proc_File.low_ino);
}
|