Reputation: 1155
I have encountered an issue that inet_ntoa results in segmentation fault on OSX, and this doesn't occur on Linux.
My test code is following.
// sample.c
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
//#include <arpa/inet.h> // adding this line prevents the segfault
int main() {
struct sockaddr_in addr;
struct sockaddr_in client;
int sock0 = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sock0, (struct sockaddr *)&addr, sizeof(addr));
listen(sock0, 5);
while (1) {
int len = sizeof(client);
int sock = accept(sock0, (struct sockaddr *)&client, (socklen_t *)&len);
printf("accepted connection from %s, port=%d\n",
inet_ntoa(client.sin_addr), ntohs(client.sin_port));
send(sock, "HELLO", 5, 0);
close(sock);
}
close(sock0);
return 0;
}
I searched for a while and found a solution which is adding an include "arpa/inet.h". I confirmed inet_ntoa is surely declared in inet.h and I'm sure this is correct way.
But I can't understand why this code doesn't work without it. What happens when I build and link this code without the include line?
I know building this code shows warnings "implicit declaration of function", but link error doesn't occur. This means linker found the implementation of inet_ntoa somehow, I think. Is this wrong?
Thanks! Any advice is highly appreciated.
Upvotes: 2
Views: 1317
Reputation: 3484
I'm going to guess that your OSX system is 64-bit while your Linux system is 32-bit. An undeclared function is assumed to return an integer. If the 64-bit pointer decays to a 32-bit integer which is dereferenced as a pointer, you will likely get a segmentation fault.
Upvotes: 6
Reputation: 12194
C permits implicit declarations of functions (Implicit function declarations in C). This is why you don't get a compiler error. Also inet_ntoa is in glibc which is linked by default by gcc, so the linker finds the definition of the function, so you don't get a linker error. The segfault happens because 1) C assumes that, because it is implicitly declared, the function returns an int and 2) on the Mac inet_ntoa in glibc is returning a 64 bit pointer which gets converted to a 32 bit value and loses information.
Upvotes: 4