getaddrinfo()返回0(成功),但将errno设置为EINVAL(22)

时间:2020-02-18 20:20:33

标签: c linux sockets getaddrinfo

以下代码段出现问题:

#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,无效的参数)?

1 个答案:

答案 0 :(得分:7)

它为什么发生并不重要。 errno仅在您自己的代码中函数调用失败时才对您有意义,并且该函数经过设计设计,可以使用errno向您报告错误。但是在大多数情况下,getaddrinfo()并非如此。

getaddrinfo()可能(并且很可能)在内部使用其他功能来执行其工作,并且如果这些功能失败,则getaddrinfo()将根据需要在内部静默处理它们。如果这些错误对getaddrinfo()的工作是致命的,则它将退出,并根据需要将其自己的错误代码返回给您。

因此,只要getaddrinfo() 自己没有向您报告错误代码,就比您根本不能依靠errno拥有任何一种有意义的价值。 errno改变价值只是getaddrinfo()在系统上内部实现的副作用

errno退出后,您应该查看getaddrinfo()的唯一时间是getaddrinfo()返回EAI_SYSTEM时,只有errno才有意义你。