Lseek SEEK_END не работает?

Я работаю над программой на C с джойстиками, и я хотел бы получить последнее событие, которое является последней строкой файла js0. Я пытаюсь переместить курсор перед последним элементом, но он не работает. Есть идеи почему?

int fd = open ("/dev/input/js0", O_RDONLY);
struct js_event e;
lseek(fd, -(sizeof(e)), SEEK_END);    
read (fd, &e, sizeof(e));
switch(e.type){
    case JS_EVENT_BUTTON: printf("btn\n");
    break;
    case JS_EVENT_AXIS: printf("axes\n");
    break;
    default: printf("smth else\n");
}

Я уверен, что файл, который я читаю, по крайней мере (sizeof(e)) длинный. Lseek возвращает мне -1, поэтому я получил ошибку, и было 29 - Незаконный поиск: почему это должен быть незаконный поиск? Я получаю те же результаты, даже если я использую 0 в качестве смещения

  lseek(fd, 0, SEEK_END)

Я использую последнюю версию Ubuntu, спасибо за вашу помощь

1 ответ

Решение

почему это должно быть незаконным поиском?

Файл, из которого вы пытаетесь прочитать, является символьным специальным файлом (это то, что указывает 'c' в первой позиции его строки режима), с помощью которого драйвер джойстика ядра может взаимодействовать с программами пользовательского пространства, такими как ваша. Такие файлы похожи на трубы - не доступны для поиска. Любая попытка найти другую позицию в таком файле не удастся, а некоторые lseek() Реализации могут потерпеть неудачу, даже если аргументы соответствуют нулевому изменению чистой позиции. Вы можете найти больше информации о файлах устройств здесь: Что такое специальные символы и специальные файлы блоков в системе Unix?

В комментариях вы спрашиваете

Любое предложение о том, как я могу получить последнюю строку?

, но это вряд ли то, что вы на самом деле хотите. В файле, таком как этот, который представляет канал связи, достижение конца файла (чтобы иметь возможность распознать последнюю строку) указывает, что канал был закрыт, и все данные были прочитаны из него. Через этот файловый дескриптор больше никогда не будет доступно никаких данных. Это не произойдет в вашем случае при обычных обстоятельствах. И я сомневаюсь, что это то, что вы надеетесь наблюдать.

Я думаю, что вы хотите узнать о самом последнем событии, доступном с устройства джойстика, и это концептуально просто: вы читаете события с устройства, пока чтение не заблокирует или не сделает. В документации по ядру Linux для используемого вами устройства есть несколько советов о том, как избежать блокировки на неопределенный срок:

  • использование select() определить, доступны ли данные с устройства, прежде чем пытаться читать с него.

  • Откройте устройство в неблокирующем режиме (т.е. с опцией O_NONBLOCK) и будьте готовы к read()s потерпеть неудачу (возвращение -1) с errno установлен в EAGAIN,

Обратите внимание, что вы должны проверять возвращаемое значение из read() в любом случае, и что существует по крайней мере один другой режим отказа, который не обязательно является подлинной ошибкой (EINTR). Прочтите его справочную страницу, а также другие функции, которые вы используете, чтобы узнать подробности, подобные этим.

Другие вопросы по тегам