我在下面的代码段中遇到问题:
#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,无效的参数)?
为什么会发生都没关系。 errno
仅在您自己的代码中函数调用失败时才有意义,并且该函数已设计以使用errno
向您报告错误。但在大多数情况下,getaddrinfo()
并非如此。
[getaddrinfo()
]可能(并且很可能)在内部使用其他功能来完成其工作,如果这些功能失败,则getaddrinfo()
将根据需要在内部静默处理它们。如果这些错误对getaddrinfo()
的工作致命,则它将退出,并根据需要将其自己的错误代码返回给您。
因此,只要getaddrinfo()
本身没有向您报告错误代码,那么您就不能仅仅依靠errno
具有any种有意义的值。 errno
更改值只是getaddrinfo()
在系统上的内部实现的副作用。
errno
退出后,您唯一应查看getaddrinfo()
的时间是getaddrinfo()
返回EAI_SYSTEM
时,只有errno
对您而言有意义的值。