errno коды ошибок linux

Сравнительная таблица кодов и расшифровок errno для различных юниксов?

Дамы и господа, потерял я недавно одну очень удобную штуку 🙁

А именно — таблицу, в которой были сведены воедино распространенные коды системных ошибок с расшифровками (из errno.h) для самых ходовых *nix-совместимых осей — Linux, BSD, AIX, Solaris, HP-UX как минимум.

Попытки загуглить ее ни к чему не привели, что заставляет задуматься о собственной вменяемости, профпригодности и т.п.

Ценность такой таблицы в том, что стандарт POSIX задает только символьные имена-аббревиатуры ошибок (ENOMEM, типа), а не коды, которые различаются от оси к осе. А масса разборчивого в друзьях ПО выдает в логах не расшифровку и даже не символьный код, а тупо числовой код…

Разбирая на изолированной станции гиговую пачку логов инцидента с сильно гетерогенной связки ПО на разных осях, без такой таблицы перед глазами приходится совершать много лишних движений. Типа, увидел 79 — а пока читаешь лог, сиди вспоминай, что на AIX это Connection Refused, когда на соляре и линухе Connection Refused это 146, а на хпуксе — 239.

Естественно, всегда можно найти в сети errno.h от каждой из нужных осей, распарсить, свести воедино, проверить на примерах и отредактировать, но это работа не на один час, а данная чудо-табличка уже была с авторскими комментариями, отформатированная и т.д., и даже влезала на А4, кажется.

По популярности «та самая» таблица должна быть как Rosetta Stone for Unix, посему и прошу Вашей помощи.

Вдруг у кого чудо-табличка завалялась?

Ну, а если не найдется — все равно оставляйте пожелания, займусь тогда составлением сам.

Источник

Обработка ошибок в C

errno коды ошибок linux

Введение

Переменная errno и коды ошибок

errno – переменная, хранящая целочисленный код последней ошибки. В каждом потоке существует своя локальная версия errno, чем и обусловливается её безопасность в многопоточной среде. Обычно errno реализуется в виде макроса, разворачивающегося в вызов функции, возвращающей указатель на целочисленный буфер. При запуске программы значение errno равно нулю.

Все коды ошибок имеют положительные значения, и могут использоваться в директивах препроцессора #if. В целях удобства и переносимости заголовочный файл определяет макросы, соответствующие кодам ошибок.

Стандарт ISO C определяет следующие коды:

Нехитрый скрипт печатает в консоль коды ошибок, их символические имена и описания:

Функции работы с errno

Получив код ошибки, хочется сразу получить по нему её описание. К счастью, ISO C предлагает целый набор полезных функций.

void perror(const char *s);

strerror() не безопасная функция. Во-первых, возвращаемая ею строка не является константной. При этом она может храниться в статической или в динамической памяти в зависимости от реализации. В первом случае её изменение приведёт к ошибке времени выполнения. Во-вторых, если вы решите сохранить указатель на строку, и после вызовите функцию с новым кодом, все прежние указатели будут указывать уже на новую строку, ибо она использует один буфер для всех строк. В-третьих, её поведение в многопоточной среде не определено в стандарте. Впрочем, в QNX она объявлена как thread safe.

Поэтому в новом стандарте ISO C11 были предложены две очень полезные функции.

size_t strerrorlen_s(errno_t errnum);

errno_t strerror_s(char *buf, rsize_t buflen, errno_t errnum);

Функции входят в Annex K (Bounds-checking interfaces), вызвавший много споров. Он не обязателен к выполнению и целиком не реализован ни в одной из свободных библиотек. Open Watcom C/C++ (Windows), Slibc (GNU libc) и Safe C Library (POSIX), в последней, к сожалению, именно эти две функции не реализованы. Тем не менее, их можно найти в коммерческих средах разработки и системах реального времени, Embarcadero RAD Studio, INtime RTOS, QNX.

Стандарт POSIX.1-2008 определяет следующие функции:

char *strerror_l(int errnum, locale_t locale);

int strerror_r(int errnum, char *buf, size_t buflen);

Увы, никакого аналога strerrorlen_s() в POSIX не определили, поэтому длину строки можно выяснить лишь экспериментальным путём. Обычно 300 символов хватает за глаза. GNU C Library в реализации strerror() использует буфер длиной в 1024 символа. Но мало ли, а вдруг?

Макрос assert()

Функции atexit(), exit() и abort()

int atexit(void (*func)(void));

Регистрирует функции, вызываемые при нормальном завершении работы программы в порядке, обратном их регистрации. Можно зарегистрировать до 32 функций.

_Noreturn void exit(int exit_code);

_Noreturn void abort(void);

Функции setjmp() и longjmp()

Вот мы и подошли к самому интересному – функциям нелокальных переходов. setjmp() и longjmp() работают по принципу goto, но в отличие от него позволяют перепрыгивать из одного места в другое в пределах всей программы, а не одной функции.

int setjmp(jmp_buf env);

void longjmp(jmp_buf env, int value);

Используя setjmp() и longjmp () можно реализовать механизм исключений. Во многих языках высокого уровня (например, в Perl) исключения реализованы через них.

Внимание! Функции setjmp() и longjmp () в первую очередь применяются в системном программировании, и их использование в клиентском коде не рекомендуется. Их применение ухудшает читаемость программы и может привести к непредсказуемым ошибкам. Например, что произойдёт, если вы прыгните не вверх по стеку – в вызывающую функцию, а в параллельную, уже завершившую выполнение?

Источник

131 Linux Error Codes for C Programming Language using errno

Programmers should handle all kinds of errors to protect the program from failure.

In C programming language, there is no direct support for error handling. You have to detect the failure and handle the error. In C programming language, return values represents success or failure. Inside a C program, when a function fails, you should handle the errors accordingly, or at least record the errors in a log file.

When you are running some program on Linux environment, you might notice that it gives some error number. For example, “Error no is : 17”, which doesn’t really say much. You really need to know what error number 17 means.

This article shows all available error numbers along with it descriptions. This article might be a handy reference for you, when you encounter an error number and you would like to know what it means.

The following C code snippet tries to open a file through open system call. There are two flags in the open call. O_CREAT flag is to create a file, if the file does not exist. O_EXCL flag is used with O_CREAT, if the file is already exist open call will fail with the proper error number.

At first execution, open got executed successfully, and it created the file since the file was not available. In next execution, it throws an error number 17, which is “File already exist”.

The following table shows list of error numbers and its descriptions in Linux operation system

ERROR CODE TABLE
Error numberError CodeError Description
1EPERMOperation not permitted
2ENOENTNo such file or directory
3ESRCHNo such process
4EINTRInterrupted system call
5EIOI/O error
6ENXIONo such device or address
7E2BIGArgument list too long
8ENOEXECExec format error
9EBADFBad file number
10ECHILDNo child processes
11EAGAINTry again
12ENOMEMOut of memory
13EACCESPermission denied
14EFAULTBad address
15ENOTBLKBlock device required
16EBUSYDevice or resource busy
17EEXISTFile exists
18EXDEVCross-device link
19ENODEVNo such device
20ENOTDIRNot a directory
21EISDIRIs a directory
22EINVALInvalid argument
23ENFILEFile table overflow
24EMFILEToo many open files
25ENOTTYNot a typewriter
26ETXTBSYText file busy
27EFBIGFile too large
28ENOSPCNo space left on device
29ESPIPEIllegal seek
30EROFSRead-only file system
31EMLINKToo many links
32EPIPEBroken pipe
33EDOMMath argument out of domain of func
34ERANGEMath result not representable
35EDEADLKResource deadlock would occur
36ENAMETOOLONGFile name too long
37ENOLCKNo record locks available
38ENOSYSFunction not implemented
39ENOTEMPTYDirectory not empty
40ELOOPToo many symbolic links encountered
42ENOMSGNo message of desired type
43EIDRMIdentifier removed
44ECHRNGChannel number out of range
45EL2NSYNCLevel 2 not synchronized
46EL3HLTLevel 3 halted
47EL3RSTLevel 3 reset
48ELNRNGLink number out of range
49EUNATCHProtocol driver not attached
50ENOCSINo CSI structure available
51EL2HLTLevel 2 halted
52EBADEInvalid exchange
53EBADRInvalid request descriptor
54EXFULLExchange full
55ENOANONo anode
56EBADRQCInvalid request code
57EBADSLTInvalid slot
59EBFONTBad font file format
60ENOSTRDevice not a stream
61ENODATANo data available
62ETIMETimer expired
63ENOSROut of streams resources
64ENONETMachine is not on the network
65ENOPKGPackage not installed
66EREMOTEObject is remote
67ENOLINKLink has been severed
68EADVAdvertise error
69ESRMNTSrmount error
70ECOMMCommunication error on send
71EPROTOProtocol error
72EMULTIHOPMultihop attempted
73EDOTDOTRFS specific error
74EBADMSGNot a data message
75EOVERFLOWValue too large for defined data type
76ENOTUNIQName not unique on network
77EBADFDFile descriptor in bad state
78EREMCHGRemote address changed
79ELIBACCCan not access a needed shared library
80ELIBBADAccessing a corrupted shared library
81ELIBSCN.lib section in a.out corrupted
82ELIBMAXAttempting to link in too many shared libraries
83ELIBEXECCannot exec a shared library directly
84EILSEQIllegal byte sequence
85ERESTARTInterrupted system call should be restarted
86ESTRPIPEStreams pipe error
87EUSERSToo many users
88ENOTSOCKSocket operation on non-socket
89EDESTADDRREQDestination address required
90EMSGSIZEMessage too long
91EPROTOTYPEProtocol wrong type for socket
92ENOPROTOOPTProtocol not available
93EPROTONOSUPPORTProtocol not supported
94ESOCKTNOSUPPORTSocket type not supported
95EOPNOTSUPPOperation not supported on transport endpoint
96EPFNOSUPPORTProtocol family not supported
97EAFNOSUPPORTAddress family not supported by protocol
98EADDRINUSEAddress already in use
99EADDRNOTAVAILCannot assign requested address
100ENETDOWNNetwork is down
101ENETUNREACHNetwork is unreachable
102ENETRESETNetwork dropped connection because of reset
103ECONNABORTEDSoftware caused connection abort
104ECONNRESETConnection reset by peer
105ENOBUFSNo buffer space available
106EISCONNTransport endpoint is already connected
107ENOTCONNTransport endpoint is not connected
108ESHUTDOWNCannot send after transport endpoint shutdown
109ETOOMANYREFSToo many references: cannot splice
110ETIMEDOUTConnection timed out
111ECONNREFUSEDConnection refused
112EHOSTDOWNHost is down
113EHOSTUNREACHNo route to host
114EALREADYOperation already in progress
115EINPROGRESSOperation now in progress
116ESTALEStale NFS file handle
117EUCLEANStructure needs cleaning
118ENOTNAMNot a XENIX named type file
119ENAVAILNo XENIX semaphores available
120EISNAMIs a named type file
121EREMOTEIORemote I/O error
122EDQUOTQuota exceeded
123ENOMEDIUMNo medium found
124EMEDIUMTYPEWrong medium type
125ECANCELEDOperation Canceled
126ENOKEYRequired key not available
127EKEYEXPIREDKey has expired
128EKEYREVOKEDKey has been revoked
129EKEYREJECTEDKey was rejected by service
130EOWNERDEADOwner died
131ENOTRECOVERABLEState not recoverable

When you see an error number thrown by a C program on a Linux environment, you might find the above table handy to identify what those error number means. Make sure to bookmark this article for future reference.

Источник

Linux.yaroslavl.ru

Много функций в GNU C библиотеке обнаруживают и выводят ошибки условий, и иногда ваши программы должны проверить эти ошибки условий. Например, когда Вы открываете входной файл, Вы должны проверить, что файл был фактически открыт правильно, и печатать сообщение об ошибках или выполнять другое соответствующее действие, если обращение к библиотечной функции потерпело неудачу.

Эта глава описывает, как работают средства сообщений об ошибках. Чтобы использовать эти средства, ваша программа должна включить заголовочный файл «errno.h».

Большинство библиотечных функций возвращает специальное значение, чтобы указать, что они потерпели неудачу. Специальное значение типично ­ 1, нулевой указатель, или константа типа EOF, которая определена для той цели. Но это значение возврата сообщает Вам только то, что ошибка произошла. Чтобы выяснять что это было, Вы должны рассмотреть код ошибки, сохраненный в переменной errno. Эта переменная объявлена в заголовочном файле «errno.h».

Переменная errno содержит номер ошибки системы. Вы можете изменять значение errno.

С тех пор как errno объявлена изменяемой, она может быть асинхронно изменена драйвером сигнала; см. раздел 21.4 [Определение драйверов]. Однако, правильно написанный драйвер сигнала сохраняет и восстанавливает значение errno, так что Вы вообще не должны волноваться относительно этой возможности, разве что при нааписании драйверов сигнала.

Многие библиотечные функции могут устанавливать errno отличным от нуля в результате вызова других библиотечных функций, которые возможно и установили ошибку. Т. е. если функция возвращает ошибку, то любая библиотечная функция могла изменять errno.

Примечание относительно переносимоси: ANSI C определяет errno скорее как «модифицируемое именуемое выражение», чем как переменную, разрешая ему выполняться как макрокоманде. Например, его расширение может включать обращение к функции, подобно * _errno (). Фактически, это встроено систему GNU непосредственно. GNU библиотека, на не-GNU системах, делает то, что правильно для этой специфической системы.

Имеются несколько библиотечных функций, подобно sqrt и atan, которые в случае ошибки возвращают ожидаемое значение, устанавивая также errno. Для этих функций, если Вы хотите выяснить, произошла ли ошибка, рекомендуется обнулить errno перед вызовом функции, и затем проверить значение позже.

Все коды ошибки имеют символические имена; т. е. это макрокоманды, определенные в «errno.h». Имена начинаются с «E» и символа верхнего регистра или цифры; Вы должны рассмотривать имена такой формы, как зарезервированные имена. См. раздел 1.3.3 [Зарезервированные имена].

Значение errno не обязательно должно соответствовать одной из этих макрокоманд, так как некоторые библиотечные функции могут возвращать другие их собственные коды ошибки для других ситуаций. Единственные значения, которые будут важны для специфической библиотечной функции ­ это списки кодов ошибок для этой функции.

На не-GNU системах, почти любой системный вызов может возвратить EFAULT, если как параметр задан недопустимый указатель. Так как это могло случиться только в результате ошибки в вашей программе, и так как этого не будет в системе GNU, мы сэкономили место не упоминая EFAULT в описаниях индивидуальных функций.

Макрокоманды кода ошибки определены в заголовочном файле «errno.h». Каждая из них преобразуется в константное целое значение. Некоторые из этих ошибок не могут произойти в системе GNU, но они могут происходить при использовании библиотеки GNU в других системах. int EPERM (макрос)

Не разрешенная операция; только владелец файла (или другого обьекта) или процессы со специальными привилегиями могут выполнять эту операцию.

Нет процесса соответствующего заданному.

Прерванное обращение к функции; асинхронный сигнал предотвратил завершение обращения. Когда это случается, Вы должны попробовать снова вызвать функцию.

Ошибка ввода-вывода, обычно используется для ошибок физического чтения или записи.

Нет такого устройства или адреса. Система попробовала использовать устройство, указанное файлом, который Вы определили, и не смогло найти это устройство. Это может означать, что файл устройства был установлен неправильно, или физическое устройство отсутствует или не правильно присоединено к компьютеру.

Список параметров слишком длинный; используется, когда параметры, переданные одной из функций (см. раздел 23.5 [Выполнение файла] ) занимают слишком много пространства памяти. Это условие никогда не возникает в системе GNU.

int ENOEXEC (макрос)

Недопустимый формат исполняемого файла. Это условие обнарживается запускаемыми функциями; см. раздел 23.5 [Выполнение файла].

Не имеется никаких порожденнных процессов. Эта ошибка случается при операциях, которые, как предполагается, управляют порожденнными процессами, когда не имеется ни каких процессов, для управления.

int EDEADLK (макрос)

Тупик; распределение ресурсов системы оценено как ситуация тупика. Система не гарантирует, что она будет обращать внимание на все такие ситуации. Эта ошибка означает, что Вам повезло; система могла зависнуть. См. раздел 8.11 [Блокировки файла].

Нет доступной памяти. Система не может распределять виртуальную память, потому она полна.

Отклоненное право; права файла не позволяют предпринятую операцию.

Плохой адрес; был обнаружен недопустимый указатель.

int ENOTBLK (макрос)

Не специальный файл, был дан в ситуации, которая требует блок файов. Например, при попытке установить обычный файл как файловую систему в UNIX дает эту ошибку.

Ресурсы заняты; ресурс системы, который не может быть разделен уже используется. Например, если Вы пробуете удалить файл, который является корнем установленной в настоящее время файловой системы, Вы получаете эту ошибку.

Файл существует; существующий файл был определен в контексте, где имеет смысл определять только новый файл.

Была обнаружена попытка, сделать неподходящую компоновку файловой системы. Это случается не только, когда Вы используете связи (см. раздел 9.3 [Сложные связи]) но также, когда Вы переименовываете файл (см. раздел 9.6 [Переименование файлов]).

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

int ENOTDIR (макрос)

Был определен файл, а не каталог, когда требуется каталог.

Указан каталог; попытка открыть каталог для записи дает эту ошибку.

Недопустимый параметр. Используется, чтобы указать различные виды проблем с указанием неправильного параметра для библиотечной функции.

Текущий процесс имеет слишком много открытых файлов и не может открыть больше. Двойные описатели приводят к этому ограничению.

Имеется слишком много различных открытых экземпляров файла во всей системе. Обратите внимание, что любое число связанных каналов считается только одним открытым экземпляром файла; см. раздел 8.5.1 [Связанные каналы]. Эта ошибка никогда не происходит в системе GNU.

int ETXTBSY (макрос)

Попытка выполнить файл, который является в настоящее время открытым для записи, или записи в файл который в настоящее время выполняется. Это не является ошибкой в системе GNU; текст по мере необходимости копируется.

Файл слишком большой; размер файла больше чем позволено системой.

Нет места на устройстве; операция записи в файл потерпела неудачу, потому что диск полон.

Недопустимая операция установки.

Слишком много связей; число связей одиночного файла слишком велико. Переименование может вызывать эту ошибку, если переименовываемый файл уже имеет максимальное число связей (см. раздел 9.6 [Переименование файлов]).

Ошибка области; использование математических функций, когда значение параметра не относится к области над которой функция определена.

Ошибка диапазона; использование математических функций, когда значение результата не представимо из-за переполнения.

Ресурс временно недоступен; обращение может работать, если Вы пробуете позже.

int EWOULDBLOCK (макрос)

Операция, которая бы была блокировала предпринята на объекте, который имеет выбранный режим не-блокирования.

int EINPROGRESS (макрос)

Операция, которая не может завершаться немедленно, была инициализирована в объекте, который имеет выбранный режим неблокирования. Некоторые функции, которые должны всегда блокировать (типа, connect ; см., раздел 11.8.1 [Соединение] ) никогда не возвращает EWOULDBLOCK. Взамен, они возвращают EINPROGRESS, чтобы указать, что операция начата и займет некоторое время. Попытайтесь управлять объектом прежде, чем обращение завершится возвратив EALREADY.

int EALREADY (макрос)

Операция уже выполняется в объекте, который имеет выбранный режим неблокирования.

int ENOTSOCK (макрос)

Был определен файл,а не гнездо, когда требуется гнездо.

int EDESTADDRREQ (макрос)

Нет был обеспечен адрес адресата для операции гнезда.

int EMSGSIZE (макрос)

Размер сообщения, посланного на гнездо был больше чем обеспечиваемый максимальный размер.

int EPROTOTYPE (макрос)

Тип гнезда не поддерживает запрашиваемый протокол связи.

int ENOPROTOOPT (макрос)

Вы определили опцию гнезда, которая не имеет смысла для специфического протокола, используемого гнездом. См. раздел 11.11 [Опции гнезда].

int EPROTONOSUPPORT (макрос)

Область гнезда не поддерживает запрашиваемый протокол связи (возможно, потому что запрашиваемый протокол полностью недопустим.) См. раздел 11.7.1 [Создание гнезда].

int ESOCKTNOSUPPORT (макрос)

Тип гнезда не установлен.

int EOPNOTSUPP (макрос)

Операция, которую Вы запросили, не обеспечивается. Некоторые функции гнезда не имеют смысла для всех типов гнезд, а другие не имеют права выполнения для всех протоколов связи.

int EPFNOSUPPORT (макрос)

Семейство протоколов связи гнезда, которое Вы запросили, не обеспечивается.

int EAFNOSUPPORT (макрос)

Семейство адресов, заданное для гнезда несогласованно с протоколом, используемым на гнезде. См. Главу 11 [Гнезда].

int EADDRINUSE (макрос)

int EADDRNOTAVAIL (макрос)

Запрашиваемый адрес гнезда не доступен; например, Вы попробовали дать гнезду имя, которое не соответствует местному главному имени. См. раздел 11.3 [Адрес Гнезда].

int ENETDOWN (макрос)

Операция с гнездом потерпела неудачу, потому что нет сети.

int ENETUNREACH (макрос)

Операция гнезда потерпела неудачу, потому что подсеть, содержащая главную ЭВМ была недоступна.

int ENETRESET (макрос)

Сетевое соединение было сброшено, потому что отдаленная главная ЭВМ умерла.

int ECONNABORTED (макрос)

Сетевое соединение было прервано локально.

int ECONNRESET (макрос)

Сетевое соединение было закрыто по внешним причинам контроля над местной главной ЭВМ, например из-за неисправимого нарушения протокола.

int ENOBUFS (макрос)

int EISCONN (макрос)

Вы пытаетесь соединить гнездо, которое уже соединено. См. раздел 11.8.1 [Соединение].

int ENOTCONN (макрос)

int ESHUTDOWN (макрос)

Гнездо уже было закрыто.

int ETIMEDOUT (макрос)

Операция гнезда с заданной блокировкой по времени не получила никакого ответа в течение периода блокировки по времени.

int ECONNREFUSED (макрос)

Отдаленная главная ЭВМ отказала в сетевом соединении (обычно из-за того, что не запущено запрашиваемое обслуживание).

При поиске имени файла столкнулись со слишком многими уровнями символических связей. Часто это указывает на цикл символических связей.

int ENAMETOOLONG (макрос)

Имя файла слишком длинное (больше чем PATH_MAX; см. раздел 27.6 [Ограничения для файлов]) или главное имя слишком длинное (в gethostname или sethostname; см. раздел 26.1 [Главная идентификация]).

int EHOSTDOWN (макрос)

Отдаленная главная ЭВМ для запрашиваемого сетевого соединения не реагирует.

int EHOSTUNREACH (макрос)

Отдаленная главная ЭВМ для запрашиваемого сетевого соединения не доступна.

int ENOTEMPTY (макрос)

Каталог, не пустой, а ожидался пустой каталог. Обычно эта ошибка происходит, когда Вы пробуете удалять каталог.

Файловая система спутана, потому что имеется слишком много пользователей.

Пользовательское дисковое пространство превышено.

Просроченная NFS программа обработки файла. Это указывает на внутренний беспорядок в NFS системе, который появляется из-за перестановок файловой системы на главной ЭВМ станции. Восстановление этого условия обычно требует переустановки файловой системы NFS на местной главной ЭВМ.

int EREMOTE (макрос)

Была сделана попытка NFS-подсоединения удаленной файловой системой с именем файла, которое уже определяет установленный файл NFS. (Эта ошибка воникает на некоторых операционных системах, но мы думаем что это будет работать правильно на системе GNU, делающей этот код ошибки невозможным.)

Нет доступной блокировки. Это используется средствами закрытия файла; см. раздел 8.11 [Блокировки файла]. Эта ошибка никогда не происходит в системе GNU.

int EBACKGROUND (макрос)

В системе GNU, станции, обеспечивающие протокол терминала возвращают эту ошибку для некоторых операций, когда вызывающий оператор не входит в группу приоритетного процесса терминала. Пользователи обычно не видят эту ошибку, потому что функции типа чтения и записи транслируют ее в SIGTTIN или SIGTTOU сигнал. См. Главу 24 [Управление заданиями], для уточнения информации относительно групп процессов и этих сигналов.

Опытный пользователь будет знать, что неправильно.

int EGREGIOUS (макрос)

Идите домой и выпейте стакан теплого молока.

int EGRATUITOUS (макрос)

Этот код ошибки не имеет никакой цели.

Библиотека имеет функции и переменные, разработанные, чтобы облегчить для вашей программы вывод информативных сообщений об ошибках в обычном формате. Функции strerror и perror дают Вам стандартное сообщение об ошибках для данного кода ошибки; переменная program_invocation_short_name дает Вам удобный доступ к имени программы, которая столкнулась с ошибкой.

Значение errnum обычно исходит из переменной errno.

Вы не должны изменять строку, возвращаемую strerror. Также, если Вы делаете последующие обращения к strerror, новая строка могла быть записана поверх старой. (Но гарантируется, что никакая библиотечная функция не вызовет strerror за вашей спиной.) Функция strerror объявлена в «string.h».

Если Вы вызываете perror с сообщением, которое является или нулевым указателем или пустой строкой, perror печатает сообщение об ошибках, соответствуя errno, добавляя конечный символ перевода строки.

Если Вы обеспечиваете не-нулевой параметр сообщения, то perror начинает вывод с этой строки. Она добавляет двоеточие и пробел, чтобы отделить сообщение от строки ошибки, соответствующей errno.

Функция perror объявлена в «stdio.h».

strerror и perror производят точно то же самое сообщение для любого данного кода ошибки; точный текст изменяется от системы до системы. На системе GNU, сообщения довольно коротки; не имеются никаких многострочных сообщений или вложенных символов перевода строки. Каждое сообщение об ошибках начинается заголовочной буквой и не включает ни какой пунктуации завершения.

Множество программ, которые не читают ввод с терминала, разработаны, чтобы выйти, если любой системный вызов терпит неудачу. В соответствии c соглашением, сообщение об ошибках из такой программы должно начаться с имени программы. Вы можете найти это имя в переменной program_invocation_short_name; полное имя файла сохранено в переменной program_invocation_name:

Библиотечные код инициализации устанавливает обе из этих переменных перед вызовом main.

Примечание относительно переносимости: Эти две переменные ­ расширения GNU. Если Вы хотите, чтобы ваша программа работала с библиотеками, не относящимися к GNU, Вы должны сохранить значение argv [0] в main (основной программе), и удалить имена каталогов самостоятельно. Мы добавили эти расширения, чтобы сделать возможной написание замкнутых сообщений об ошибках подпрограммы, которые не требуют никакого явного сотрудничества с основной программой.

Имеется пример, показывающий, как обработать отказ открывать файл. Функция open_ sesame пробует открывать указанный файл для чтения и возвращает поток. Библиотечная функция fopen возвращает нулевой указатель, если она не может открыть файл по некоторым причинам. В той ситуации, open_sesame создает соответствующее сообщение об ошибках, используя функцию strerror, и завершает программу. Если мы хотим сделать другие вызовы из библиотек перед передачей кода ошибки к strerror, мы должны сохранить его в местной переменной, потому что те другие библиотечные функции могут записывать поверх errno.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *