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?
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.