Drivers de dispositivo Linux, 3ª edição afirma:
se o método llseek estiver faltando nas operações do dispositivo, a implementação padrão no kernel executa buscas modificando filp->f_pos
No entanto, tenho um dispositivo de caractere para o qual o driver não implementa lseek. Aqui estão as definições de op de arquivo para esse tipo de dispositivo: https://github.com/Xilinx/dma_ip_drivers/blob/master/XDMA/linux-kernel/xdma/cdev_ctrl.c
Mas tentar lseek neste dispositivo retorna ESPIPE:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
int main(int argc, char** argv) {
uint32_t val=0x12345678;
int fid=open("/dev/xdma0_user", O_RDWR);
off_t lseek_ret=lseek(fid, 0x8ul, SEEK_SET);
if (lseek_ret <0)
fprintf(stderr, "Seek result: %d, errno: %s (%d)\n", lseek_ret, strerror(errno), errno );
unsigned int c=write(fid, &val, sizeof(val));
printf("written %u bytes\n", c);
close(fid);
return (0);
}
Saída:
Seek result: -1, errno: Illegal seek (29)
written 4 bytes
Não consigo entender como isso acontece. Não pode vir do driver: ESPIPE nem é mencionado em lugar nenhum, então deve vir do kernel, o que contradiz a citação acima.
O comportamento padrão foi alterado? Ele pode ser configurado de alguma forma? Como pode ser visto o que o kernel realmente faz (idealmente código fonte)?
A versão do kernel é 5.10 (Debian 11).