Как установить errno в драйвер устройства Linux?

Я разрабатываю драйвер персонального устройства Linux. Я хочу установить errno при возникновении ошибки в системном вызове ioctl().

long my_own_ioctl(struct file *file, unsigned int req, unsigned long arg)
{
    long ret = 0;
    BOOL isErr = FALSE;

    // some operation
    // ...

    if (isErr) {
        // set errno
        // ...                 <--- What should I do?
        ret = -1;
    }

    return ret;
}

Что я должен сделать для этого? Спасибо вам заранее!


Пожалуйста, позвольте мне более подробно объяснить свое выражение.

Мое устройство расположено в /dev/myCharDev. Приложение моего пользовательского пространства выглядит так:

#define _COMMAND                    (1)
#define _ERROR_COMMAND_PARAMETER    (-1)

int main()
{
    int fd = open("/dev/myCharDec", O_RDONLY);
    int errnoCopy;

    if (fd) {
        if (ioctl(fd, _COMMAND, _ERROR_COMMAND_PARAMETER) < 0) {      // should cause error in ioctl()
            errnoCopy = errno;
            printf("Oops, error occurred: %s\n", strerr(errnoCopy));  // I want this "errno" printed correctly
        }

        close(fd);
    }

    return 0;
}

Как я уже упоминал в комментариях выше, как мне установить " errno " в моих собственных кодах драйверов устройства и сделать его доступным для чтения при использовании пользовательского пространства?

Ответ 1

Хороший вопрос!

Хорошо, вы могли бы думать о errno как глобальной переменной (быть honnest, это extern int). errno имеет множество предопределенных макросов для кодов ошибок в библиотеке errno.h. Вы можете посмотреть здесь. Очень вероятно, что некоторые из этих кодов ошибок описывают то, что вы хотите показать. Возьмите правильный, установите его, как если бы это была переменная, которую вы определили, и (важно!) Немедленно выйдите!

Вы можете спросить себя, если установка errno - правильный подход к вашей проблеме. Вы всегда можете определить (* int) и разработать свои собственные коды ошибок и механизм обработки ошибок. Цель Errno - показать и объяснить системные ошибки. Учтите свою часть кода "системы" (как я вижу, вы разрабатываете свой собственный системный вызов, так что это может быть так)? Поэтому продолжайте и используйте errno, чтобы объяснить свою "системную ошибку".

Изменить (на вопрос обновления): Ok больше информации. Как я уже сказал, errno является extern int и устанавливается ядром. Значение, на которое установлено errno, является просто возвращаемым значением системного вызова. Затем ядро Linux интерпретирует это отрицательное значение через библиотеку errno.h. Таким образом, примерное сообщение об ошибке устанавливается просто путем возврата (EBUSY - это всего лишь пример - вы можете использовать все предопределенные типы ошибок) сообщение об ошибке, которое вы хотите получить от своего системного вызова. Пример:

return -EBUSY

Надеюсь, поможет

Ответ 2

Верните отрицательный номер ошибки из ioctl. Библиотека c интерпретирует это и дает код возврата -1 и устанавливает errno в положительную ошибку. Например, ваш исходный пример установит errno равным 1.

В стороне ваш прототип функции ioctl в ядре выглядит неправильно. Какую версию ядра вы используете?

Ответ 3

if (isErr)
    {
        printk(KERN_ALERT "Error %d: your description\n", errno);
        ret = errno;
    }

где, errno - возвращаемое значение некоторой функции.

Драйвер устройства всегда должен возвращать статус для полученного запроса. Отстаивается, что вы всегда используете перечислимые коды возврата, а также нормальные коды возврата. Возврат 0 = проход 1 или -1 = сбой является неопределенным и может вводить в заблуждение.

Раздел 3.1. Эффективная обработка ошибок, отчетность и восстановление: для получения дополнительной информации