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
). Прочтите его справочную страницу, а также другие функции, которые вы используете, чтобы узнать подробности, подобные этим.