getaddrinfo() returns 0 (success) but sets errno to EINVAL (22)

Cacahuete Frito :

I'm having problems with the following piece of code:

#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);
[...]

The problem is that although it works (I'm using this for a TCP communication which indeed is working), it's inconsistent:

man getaddrinfo says nothing about errno; instead it returns an error code. Why may it be setting errno to EINVAL (22, Invalid argument) internally?

Remy Lebeau :

It doesn't matter why it happens. errno only has meaning to you when a function call fails in your own code, and that function is designed to use errno to report errors to you. But that is not the case with getaddrinfo() in most situations.

getaddrinfo() may be (and likely is) using other functions internally to do its work, and if those functions fail then getaddrinfo() will silently handle them internally as needed. If those errors are fatal to getaddrinfo()'s work then it will exit with its own error code returned to you as needed.

So, as long as getaddrinfo() itself is not reporting an error code to you than you simply can't rely on errno having any kind of meaningful value. errno changing value is simply a side effect of getaddrinfo()'s internal implementation on your system.

The ONLY time you should be looking at errno after getaddrinfo() exits is when getaddrinfo() returns EAI_SYSTEM, ONLY THEN will errno have a meaningful value to you.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=12150&siteId=1