Я предполагаю, что вы используете Linux, и я полагаю, что вы не напрямую используете системный вызов, а некоторые (простые) оболочки (из вашей библиотеки C), перечисленные в системные вызовы(2). Обратите внимание, что некоторые странные системные вызовы не обертываются библиотекой C (хорошо известным примером развернутого системного вызова может быть sigreturn(2), который вам, вероятно, никогда не следует использовать). Довольно часто библиотека C — это GNU glibc, но это может быть и musl-libc и т. д. Также обратите внимание, что необработанные системные вызовы ядра имеют разные соглашения о вызовах, чем обычные функции C (поэтому на практике требуется оболочка libc, которая отвечает за работу с errno
). Заметьте также, что errno(3) обычно является макросом (почти ведет себя как некоторая переменная).
msgrcv(2) документирует, что errno
может быть одним из E2BIG
, EACCES
, EFAULT
... ENOMSG
, ENOSYS
... (обратитесь к этой справочной странице, чтобы получить список всех возможных ошибок).
Итак, вы бы написали что-то вроде
ssize_t siz = msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
if (siz<0) { // msgrcv failed and has set errno
if (errno == ENOMSG)
dosomething();
else if (errno == EAGAIN)
dosomethingelse();
/// etc
else {
syslog(LOG_DAEMON|LOG_ERR, "msgrcv failure with %s\n",
strerror(errno));
exit(EXIT_FAILURE);
};
};
Является ли заявление if (errno == ENOMSG)
.... действительным?
Да, это; вы хотите протестировать errno
только после некоторого сбоя системного вызова (например, когда siz<0
).
Есть ли такая переменная errno
?
Уже нет. Пожалуйста, внимательно прочитайте документацию errno(3). Вы не должны объявлять extern int errno;
(это было возможно в 1980-х, а не в 21st веке), но вы должны всегда #include <errno.h>
и использовать errno
как если бы это была переменная, но это почти всегда является некоторым макросом (определение которого появляется в /usr/include/bits/errno.h
, который включен в /usr/include/errno.h
).
Кстати, средства в стиле SysV, как правило, устаревают и не всегда доступны. Я рекомендую использовать средства очередей сообщений POSIX, прочитайте mq_overview(7). .
Вы можете прочитать бесплатно загружаемый Advanced Linux Programming (старая книга; вы можете купить что-то лучше и новее) и/или все справочные страницы, доступные на intro(2) & системные вызовы(2) и введение(3 )а>.
person
Basile Starynkevitch
schedule
02.09.2017
man
страницу), это позволит вам узнать, что вам следует протестировать. - person Myst   schedule 02.09.2017errno
в ноль, и вы не должны тестировать ее, если только функция не указывает на ошибку и документально не устанавливаетerrno
. Обратите внимание, что многие функции pthreads, например, не устанавливаютerrno
; вместо этого они возвращают номер ошибки. Кроме того, функции могут устанавливатьerrno
в ненулевое значение даже в случае успеха. Например, в Solaris, если стандартный вывод не является терминалом,errno
можно установить в ENOTTY, даже если вызовprintf()
выполнен успешно. - person Jonathan Leffler   schedule 02.09.2017