c - 无法理解 Linux 内核模块中 read_proc 的工作

标签 c linux linux-kernel kernel kernel-module

我正在查看内核模块示例 page

程序中使用的read_proc如下:

int fortune_read( char *page, char **start, off_t off,

               int count, int *eof, void *data )

{

    int len;

     if (off > 0) {
         *eof = 1;
          return 0;
     }

     /* Wrap-around */
    if (next_fortune >= cookie_index) next_fortune = 0;

    len = sprintf(page, "%s\n", &cookie_pot[next_fortune]);

    next_fortune += len;

    return len;
}

谁能解释为什么 off 被检查为大于 0。此外,谁能解释 off 和 count 参数的重要性。

到目前为止我的理解是我们必须在页面中写入数据并且必须在数据结束时设置eof。

谢谢。

最佳答案

off 是文件中必须从中读取数据的位置。这就像普通文件的偏移量。但是,在 proc_read 的情况下,它有些不同。例如,如果您调用 proc 文件的读取调用以读取 100 字节的数据,proc_read 中的关闭和计数将如下所示:

第一次,off = 0,计数 100。比如说在你的 proc_read 中你只返回了 10 个字节。然后控制权无法返回给用户应用程序,您的 proc_read 将被内核再次调用,off 为 10,计数为 90。如果您在 proc_read 中返回 20,您将再次调用 off 30,计数为 70。像这样,您将被调用直到计数达到 0。然后数据被写入给定的用户缓冲区,您的应用程序 read() 调用返回。

但是如果你没有百字节的数据,只想返回几个字节,你必须将eof设置为1。然后read()函数立即返回。

首先,以下评论比我解释得更好。

      /*
       * How to be a proc read function
       * ------------------------------
                     * Prototype:
                     *    int f(char *buffer, char **start, off_t offset,
                     *          int count, int *peof, void *dat)
                     *
                     * Assume that the buffer is "count" bytes in size.
                     *
                     * If you know you have supplied all the data you
                     * have, set *peof.
                     *
                     * You have three ways to return data:
                     * 0) Leave *start = NULL.  (This is the default.)
                     *    Put the data of the requested offset at that
                     *    offset within the buffer.  Return the number (n)
                     *    of bytes there are from the beginning of the
                     *    buffer up to the last byte of data.  If the
                     *    number of supplied bytes (= n - offset) is 
                     *    greater than zero and you didn't signal eof
                     *    and the reader is prepared to take more data
                     *    you will be called again with the requested
                     *    offset advanced by the number of bytes 
                     *    absorbed.  This interface is useful for files
                     *    no larger than the buffer.
                     * 1) Set *start = an unsigned long value less than
                     *    the buffer address but greater than zero.
                     *    Put the data of the requested offset at the
                     *    beginning of the buffer.  Return the number of
                     *    bytes of data placed there.  If this number is
                     *    greater than zero and you didn't signal eof
                     *    and the reader is prepared to take more data
                     *    you will be called again with the requested
                     *    offset advanced by *start.  This interface is
                     *    useful when you have a large file consisting
                     *    of a series of blocks which you want to count
                     *    and return as wholes.
                     *    (Hack by Paul.Russell@rustcorp.com.au)
                     * 2) Set *start = an address within the buffer.
                     *    Put the data of the requested offset at *start.
                     *    Return the number of bytes of data placed there.
                     *    If this number is greater than zero and you
                     *    didn't signal eof and the reader is prepared to
                     *    take more data you will be called again with the
                     *    requested offset advanced by the number of bytes
                     *    absorbed.
                     */

关于c - 无法理解 Linux 内核模块中 read_proc 的工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9286303/

相关文章:

c - 使用 `ld -r` 并在符号丢失时出现编译错误

linux - 如何在 Linux 内核模块中获取一组可用的 CPU?

python - psutil 总是返回 pid 存在

linux-kernel - 如何为真正的 Android 手机编译 Linux 内核?

c - Linux 内核中的工作队列实现

c - 字符串指针在函数之间不起作用

C 使用 fread 读取未知数量的数据

c - Hello World 驱动程序无法正确编译

java - 对 JRE 和 JDK 以及最新的 Java 版本感到困惑

c - 如果 exec() 失败怎么办?