Что возвращать из обработчика IOCTL в user-space если данный IOCTL не поддерживается? В нашем драйвере активно использовался ENOIOCTLCMD
. Проблема в том, что он объявлен в linux/errno.h
в заголовке которого написано (вольный перевод):
не использовать в пользовательском коде
В данном случае, под пользовательским кодом стоит понимать всё, что не собирается в дереве ядра. Кто-то может не согласить со мной в этом аспекте, но по соображениям переносимости - лучше этому следовать.
Кроме того:
- этого кода нет в пользовательских
errno.h
/cerrno
; - для этого когда
strerror()
вернёт что-то вроде:Unknown error 515
(номер может и отличаться); - константы для этого кода ошибки нет на других платформах (Windows, MacOSX, FreeBSD).
Что использовать-то? А использовать не совсем очевидный: ENOTTY
.
Изначально, да и согласно комментариям в include/uapi/asm-generic/errno-base.h
:
Not a typewriter
При этом утилита пользовательского пространства errno
из комплекта
moreutils
говорит:
ENOTTY 25 Inappropriate ioctl for device
Дополнительными аргументами:
- интернеты тоже подсказывают такую трактовку;
- в ядре Linux оно используется по такому же назначению.
В чём же отличие? Нашёл отличное объяснение в
block/ioctl.c
:
* Is it an unrecognized ioctl? The correct returns are either
* ENOTTY (final) or ENOIOCTLCMD ("I don't know this one, try a
* fallback"). ENOIOCTLCMD gets turned into ENOTTY by the ioctl
* code before returning.
Не буду переводить, просто поясню: ENOIOCTLCMD
используется во внутренних реализациях, когда есть предположение, что обработку можно выполнить в каком-то стандартном русле, выполнить т.н. fallback. В пользовательское пространство должен вернуться ENOTTY
. Точка.