Почему glib c сохраняет возвращаемое значение системного вызова в errno - PullRequest
0 голосов
/ 13 января 2020

Я прочитал, что при сбое системного вызова ядро ​​возвращает соответствующий номер ошибки, объясняющий сбой. Почему эта ошибка не возвращается напрямую в пользовательские приложения?

Почему glib c хранит ее в глобальной переменной errno? В чем преимущество этого?

1 Ответ

4 голосов
/ 13 января 2020

Перевод комментариев в ответ.

Использование errno является предметом обсуждения, но сводится к "историческим причинам". Ранние версии Unix делали это - более поздние версии (и стандартные C и POSIX) сохраняли его, чтобы избежать взлома рабочего кода. Механизм errno имеет много fl aws, особенно в современном многопоточном коде. Библиотека POSIX pthread не использует errno; функции сообщают номер ошибки напрямую. Вы можете найти записи о errno в книгах, таких как PJ Plauger The Standard C Library (1992). Он довольно старый и описывает C90, но большая часть его остается актуальной сегодня.

Обоснование POSIX для Номера ошибок содержит довольно много информации о topi c. Обратите внимание, в частности, на подраздел «Альтернативные решения для каждого потока errno».

Обратите внимание, что старый код C может записать extern int errno; в исходном файле. Поскольку многопоточность стала обычным явлением, это неверно. Единственный правильный способ получить объявление errno в современном коде - это #include <errno.h>. Это потому, что имя может быть макросом для «модифицируемого lvalue». В одной системе (macOS Catalina 10.15.2) вы можете найти:

extern int * __error(void);  // Do not copy this
#define errno (*__error())   // Do not copy this

Это сильно отличается от extern int errno;. Обратите внимание, что другие системы имеют различные способы объявления этого - вы не можете скопировать то, что я показал в ваш код, и ожидать, что оно будет работать. Включить заголовок; это просто и надежно (и это единственный способ сделать работу надежно).

...