Невозможно понять работу read_proc в модуле ядра Linux - PullRequest
3 голосов
/ 15 февраля 2012

Я рассматриваю пример модуля ядра на этой странице

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;
}

Может ли кто-то объяснить, почему выключен флажок, чтобы быть больше 0. Кроме того, кто-то может объяснить, какова важность аргументов off и count.

Насколько я понимаю, мы должны записать данные на странице и установить eof после окончания данных.

Спасибо.

1 Ответ

3 голосов
/ 15 февраля 2012

off - это позиция в файле, откуда данные должны быть прочитаны.Это как из набора нормального файла.Но, в случае proc_read, это кое-что другое.Например, если вы вызываете вызов read для файла proc для считывания 100 байт данных, значение off и count в proc_read будет таким:

в первый раз, off = 0, count 100. Скажите дляНапример, в вашем proc_read вы вернули только 10 байтов.Тогда элемент управления не может вернуться к пользовательскому приложению, ваш proc_read будет снова вызываться ядром с выключенным значением 10 и значением 90. Опять же, если вы вернете 20 в proc_read, вы снова будете вызывать с выключенным значением 30, счетным числом 70.Таким образом, вы будете вызываться до тех пор, пока count не достигнет 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.
                     */
...