getaddrinfo() returns 0(成功)但将 errno 设置为 EINVAL (22)
getaddrinfo() returns 0 (success) but sets errno to EINVAL (22)
我在使用以下代码时遇到问题:
#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
;相反,它 returns 一个错误代码。为什么它可能在内部将 errno
设置为 EINVAL
(22,无效参数)?
为什么会发生并不重要。 errno
仅当您自己的代码中的函数调用失败时才对您有意义,并且该函数 设计 以使用 errno
向您报告错误。但在大多数情况下 getaddrinfo()
并非如此。
getaddrinfo()
可能(并且很可能)在内部使用其他函数来完成其工作,如果这些函数失败,那么 getaddrinfo()
将根据需要在内部静默处理它们。如果这些错误对 getaddrinfo()
的工作是致命的,那么它将退出并根据需要返回给您自己的错误代码。
因此,只要 getaddrinfo()
本身 没有向您报告错误代码,您就不能完全依赖 errno
任何种有意义的值。 errno
更改值只是 副作用 getaddrinfo()
在您的系统上的内部实现。
在 getaddrinfo()
退出后,您唯一应该查看 errno
的时间是 getaddrinfo()
returns EAI_SYSTEM
,然后才会 errno
对你有有意义的价值。
我在使用以下代码时遇到问题:
#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
;相反,它 returns 一个错误代码。为什么它可能在内部将 errno
设置为 EINVAL
(22,无效参数)?
为什么会发生并不重要。 errno
仅当您自己的代码中的函数调用失败时才对您有意义,并且该函数 设计 以使用 errno
向您报告错误。但在大多数情况下 getaddrinfo()
并非如此。
getaddrinfo()
可能(并且很可能)在内部使用其他函数来完成其工作,如果这些函数失败,那么 getaddrinfo()
将根据需要在内部静默处理它们。如果这些错误对 getaddrinfo()
的工作是致命的,那么它将退出并根据需要返回给您自己的错误代码。
因此,只要 getaddrinfo()
本身 没有向您报告错误代码,您就不能完全依赖 errno
任何种有意义的值。 errno
更改值只是 副作用 getaddrinfo()
在您的系统上的内部实现。
在 getaddrinfo()
退出后,您唯一应该查看 errno
的时间是 getaddrinfo()
returns EAI_SYSTEM
,然后才会 errno
对你有有意义的价值。