I have the following piece of code for getting the hostname and IP address,
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h> /* This is the header file needed for gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
struct hostent *he;
if (argc!=2){
printf("Usage: %s <hostname>\n",argv[0]);
exit(-1);
}
if ((he=gethostbyname(argv[1]))==NULL){
printf("gethostbyname() error\n");
exit(-1);
}
printf("Hostname : %s\n",he->h_name); /* prints the hostname */
printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr))); /* prints IP address */
}
But I am getting a warning during compilation:
$cc host.c -o host
host.c: In function ‘main’:
host.c:24: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
Then there is a segmentation fault when I run the code:
./host 192.168.1.4
Hostname : 192.168.1.4
Segmentation fault
What is the error in the code?
The warning about the mismatch for the printf format is an important warning. In this case, it comes because the compiler is thinking that the function
inet_ntoareturns anint, but you specified to expect a string in the format-string.The incorrect return-type for
inet_ntoais the result of an old C rule that states that if you try to use a function without a prior declaration, then the compiler must assume the function returns anintand takes an unknown (but fixed) number of arguments. The mismatch between the assumed return type and the actual return type of the function results in undefined behaviour, which manifests itself as a crash in your case.The solution is to include the correct header for
inet_ntoa.