Reputation: 151
#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
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
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 toinet_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