Question

More or less what it says in the title. I have a call to getaddrinfo like so:

struct addrinfo crossplat, *actual_addr;
crossplat.ai_family = AF_UNSPEC; //IPv4 or IPv6.
crossplat.ai_socktype = SOCK_STREAM; 

if(int i = getaddrinfo("localhost", "8000", &crossplat, &actual_addr)!=0){
    cerr << "error code " << i << " received. Meaning: "<<  gai_strerror(i) << endl;
    return -1;
}

Which proudly prints:

error code 1 received. Meaning: Unknown error

on my system.

The getaddrinfo man page on my system:

RETURN VALUE
   getaddrinfo() returns 0 if it succeeds, or one of the following 
   nonzero error codes:

   EAI_ADDRFAMILY....


   ...The gai_strerror() function translates these error codes to a 
       human readable string, suitable for error reporting.

Which suggests to me that all non-zero codes returned by getaddrinfo should be one of the listed EAI_* family codes. Searching online suggests that gai_strerror() will only return "Unknown error" when it is passed an error code which is not a member of the EAI_* family, which would seem to rule out "1" being such a code.

Apparently I'm doing something rather wrong here, so any assistance would be greatly appreciated!

Was it helpful?

Solution

This expression is a syntax error in C, but assuming you are using C++ it's not grouped how you're expecting:

if (int i = getaddrinfo("localhost", "8000", &crossplat, &actual_addr)!=0){

This will assign the result of getaddrinfo("localhost", "8000", &crossplat, &actual_addr) != 0 to i, which is always either 0 or 1. Any non-zero return by getaddrinfo() will leave i with the value of 1.

You need to declare i earlier so that you can paranthesize the assignment:

int i;
if ((i = getaddrinfo("localhost", "8000", &crossplat, &actual_addr)) != 0) {

(of course, having done this you'd probably also move the getaddrinfo() call to the initializer of i).

OTHER TIPS

I think you'll need to initialise crossplat.ai_protocol. The man page section on the hints argument mentions this being used in addition to the addrinfo members you already initialise.

You might also need to initialise crossplat.ai_flags. It'd probably be easier to just memset the whole structure:

struct addrinfo crossplat, *actual_addr;
memset(&crossplat, 0, sizeof(crossplat));
crossplat.ai_family = AF_UNSPEC; //IPv4 or IPv6.
crossplat.ai_socktype = SOCK_STREAM;

In getaddrinfo.h : #define EAI_ADDRFAMILY 1, which means : address family for hostname not supported

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top