Такие программы, как cat
, будут читать текущий входной файл до тех пор, пока не столкнется с условием конца файла или ошибкой чтения. По соглашению, возвращаемое read()
значение 0 указывает на состояние конца файла, когда запрашивается ненулевой объем данных. Возвращаемое значение -1
указывает на ошибку чтения с номером ошибки в переменной errno
.
На уровне ядра обработчик файловых операций read
должен возвращать 0, чтобы указать на конец файла (но может также делать это, когда запрошенная сумма равна 0), и должен возвращать отрицательное значение errno
, чтобы указать на ошибку чтения.
Текущий обработчик файловой операции read
OP, my_read
, копирует содержимое строкового литерала, "Hello from the kernel world!\n"
, в буфер пользовательской памяти, ограниченный запрошенным объемом чтения или длиной строки, в зависимости от того, что наименьшее. Он никогда не возвращает условие конца файла. Единственный раз, когда он возвращает 0, это когда запрошенная сумма равна 0, но это не является допустимым условием конца файла.
Одна вещь, которую может сделать my_read
, — это использовать переданную информацию о позиции в файле, чтобы определить, с чего начать чтение, и ограничить объем копирования. Он должен соответствующим образом обновить позицию. Затем он может вернуть 0, чтобы указать конец файла, когда больше нет данных для копирования. Вот возможная реализация:
static ssize_t my_read(struct file *my_file, char __user *buf, size_t len, loff_t *off) {
char *message = "Hello from the kernel world!\n";
size_t datalen = strlen(message);
if (*off >= datalen) {
return 0; /* end of file */
}
if(len > datalen - *off) {
len = datalen - *off;
}
printk(KERN_INFO "Char driver: Read\n");
if(copy_to_user(buf, message, len)) {
return -EFAULT;
}
*off += len;
return len;
}
Одно изменение в поведении заключается в том, что последовательные количества чтения длиной 10 (например) будут начинаться с того места, где остановилось предыдущее read
, например:
- прочитать 10, вернуть 10 (
'H'
, 'e'
, 'l'
, 'l'
, 'o'
, ' '
, 'f'
, 'r'
, 'o'
, 'm'
)
- прочитать 10, вернуть 10 (
' '
, 't'
, 'h'
, 'e'
, ' '
, 'k'
, 'e'
, 'r'
. 'n'
, 'e'
)
- прочитать 10, вернуть 9 (
'l'
, ' '
, 'w'
, 'o'
, 'r'
, 'l'
, 'd'
, '!'
, '\n'
)
- прочитать 10, вернуть 0 (конец файла)
person
Ian Abbott
schedule
30.11.2020
cat
будет продолжать считывать ввод до тех пор, пока функцияread()
не вернет 0 (указывает на конец файла) или-1
(указывает на ошибку). - person Ian Abbott   schedule 30.11.2020printk
должно заканчиваться новой строкой, если вы не собираетесь следовать за ним с помощьюKERN_CONT
. - person Ian Abbott   schedule 30.11.2020