seunje
seunje

Reputation: 151

Weird printf behaviour with inet_ntoa

#include <sys/socket.h>
#include <err.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char **argv) {

    struct sockaddr_in X = {0};
    X.sin_family = AF_INET;
    X.sin_addr.s_addr = inet_addr("127.0.0.1");
    X.sin_port = htons(8080);

    struct sockaddr_in Y = {0};
    Y.sin_family = AF_INET;
    Y.sin_addr.s_addr = inet_addr("212.43.159.20");
    Y.sin_port = htons(80);

    printf("X:Y %s:%s\n", inet_ntoa(X.sin_addr), inet_ntoa(Y.sin_addr));
    printf("X %s\n", inet_ntoa(X.sin_addr));
    printf("Y %s\n", inet_ntoa(Y.sin_addr));

    return 0;
}

Why does first pritnf print same IP twice rather than whats given? Second and third seem to be okay. Seems to happend on linux gcc/clang and freebsd clang, is this is something known?

Upvotes: 4

Views: 658

Answers (2)

dbush
dbush

Reputation: 223897

From the man page for inet_ntoa:

The inet_ntoa() function converts the Internet host address in given in network byte order to a string in standard numbers-and-dots notation. The string is returned in a statically allocated buffer, which subsequent calls will overwrite.

Since inet_ntoa uses a static buffer for its output, and because you call it twice in one function call, printf gets passed two copies of the same pointer. It contains the contents of whichever call was done last.

You need to split the printing into two separate calls, like you do in the following lines.

Upvotes: 5

Mat
Mat

Reputation: 206689

Take a look at the POSIX docs for inet_ntoa, notable the "Application Usage" section:

The return value of inet_ntoa() may point to static data that may be overwritten by subsequent calls to inet_ntoa().

This is what is happening here: one of the two calls in your first printf is overwriting what the other did (and you don't know which one - order of evaluation of function arguments is implementation defined).

So either stick with two printfs, or copy the string returned by inet_ntoa into your own buffers and then print them.

Upvotes: 3

Related Questions