以下代码段出现问题:
#include <errno.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
[...]
struct protoent *tcp;
struct addrinfo hint = {0};
struct addrinfo *addrs;
int status;
tcp = getprotobyname("tcp");
if (!tcp)
return -EINVAL;
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = tcp->p_proto;
// errno is 0
status = getaddrinfo("localhost", "30002", &hint, &addrs);
// errno is 22
if (status)
return -labs(status);
[...]
问题是,尽管它可以工作(我正在使用它进行确实有效的TCP通信),但是却不一致:
man getaddrinfo
没对errno
说什么;而是返回一个错误代码。为什么会在内部将errno
设置为EINVAL
(22,无效的参数)?
答案 0 :(得分:7)
它为什么发生并不重要。 errno
仅在您自己的代码中函数调用失败时才对您有意义,并且该函数经过设计设计,可以使用errno
向您报告错误。但是在大多数情况下,getaddrinfo()
并非如此。
getaddrinfo()
可能(并且很可能)在内部使用其他功能来执行其工作,并且如果这些功能失败,则getaddrinfo()
将根据需要在内部静默处理它们。如果这些错误对getaddrinfo()
的工作是致命的,则它将退出,并根据需要将其自己的错误代码返回给您。
因此,只要getaddrinfo()
自己没有向您报告错误代码,就比您根本不能依靠errno
拥有任何一种有意义的价值。 errno
改变价值只是getaddrinfo()
在系统上内部实现的副作用。
errno
退出后,您应该查看getaddrinfo()
的唯一时间是getaddrinfo()
返回EAI_SYSTEM
时,只有errno
才有意义你。