Всегда ли stdio устанавливает errno?


Когда поток stdio обнаруживает ошибку (но не EOF), индикатор ошибки потока будет установлен таким образом, что ferror() возвратит ненулевое значение. Я всегда предполагал, что больше информации доступно в errno. Но откуда я это знаю?

Документация для некоторых функций[например, man fopen под Linux] говорит, что errno также будет установлен. Однако man fgets вообще не упоминает errno. Информационные страницы glibc обнадеживают:

В дополнение к установке индикатора ошибок, связанного с то stream, функции, которые работают с потоками, также устанавливают 'errno' в так же, как и соответствующие низкоуровневые функции, которые работают с файлом дескрипторы.

Но я понятия не имею, насколько сильна эта гарантия. Требуется ли это по стандарту с? Что происходит в Visual C / C++?
2 10

2 ответа:

Сам стандарт C не требует большого использования errno WRT для функций stdio; он определяет ferror() , но говорит о нем только то, что

7.13.10.3 функция феррора функция феррора проверяет индикатор ошибки для потока, на который указывает поток. Функция феррора возвращает ненулевое значение тогда и только тогда, когда индикатор ошибки установлен для потока.

Из проекта С99: http://www.vmunix.com/~gabor/c/draft.html . любые фактические коды ошибок используются, например: большая часть, реализация определена.

Однако библиотека GNU C в linux также соответствует спецификациям POSIX:

Http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm

, которые в этом контексте гораздо более четко определены. Например, если вы посмотрите на страницу для fopen:

Http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html

Вы увидите много подробной информации, включая конкретные коды errno, в разделе ошибки .

Опять же, библиотека GNU C, используемая практически во всех нормальных системах linux, совместима с POSIX, так что вы можете рассчитывать на эту информацию ;). Эти (онлайновые) справочные страницы POSIX также, как правило, более детализированы, чем стандартные справочные страницы системы linux (читайте оба).

WRT для файловых операций на других (не POSIX) платформах, они будут иметь свои собственные реализации. К сожалению, такие вещи не являются прозрачно переносимыми в стандартных потоках C. C++ есть больше однако стандартизированная обработка ошибок.

Согласно стандарту C11, глава 7.21 ("stdio.h"), только fgetpos, fsetpos и ftell пишите в errno в случае ошибки.