Любая функция может устанавливать errno, но только если она устанавливает ненулевое значение. Спецификация ANSI C гласит:
Значение errno равно нулю при запуске программы, но никогда не устанавливается на
ноль любой библиотечной функцией. * Значение errno может быть установлено в
отличным от нуля при вызове библиотечной функции, независимо от того, есть ли ошибка,
при условии, что использование errno не задокументировано в описании
функция в стандарте.
* Таким образом, программа, которая использует errno для проверки ошибок, должна установить его
обнулить перед вызовом библиотечной функции, затем проверить его перед
последующий вызов библиотечной функции.
Итак, если вы используете errno, наилучший подход состоит в том, чтобы установить значение 0 непосредственно перед вызовом библиотеки, который может завершиться ошибкой, и прочитать его сразу после. В приведенном выше случае было бы достаточно добавить что-то вроде:
int localErrno = errno
непосредственно перед оператором printf и используйте localErrno для вашего ключа. Это, конечно, предполагает, что нет никаких библиотечных вызовов между ошибочной функцией и вашим вызовом к printerror. Если есть, вам нужно будет сохранить errno после неудачного вызова и передать его в вашу функцию printerror.