I\'m trying to compile this program, as referenced in Beej\'s Guide to Network Programming on page 19.
#include
#include
add at the top of your file
#define _XOPEN_SOURCE 600
../main.c:8:18: error: storage size of ‘hints’ isn’t known ../main.c:13:19: error: ‘AI_PASSIVE’ undeclared (first use in this function) ../main.c:16:3: warning: implicit declaration of function ‘gai_strerror’
It appears that gcc isn't linking with netdb.h....
These are not linking errors, and you don't need a netdb shared object
file (there is no such beast; netdb.h
simply defines data structures
and macros for use in your code).
These are compiler errors: gcc complaining because you're using names
that it doesn't recognize (AI_PASSIVE
) and data types for which the
structure is unknown (struct addrinfo
).
The code as you've presented it appears to be correct, and addrinfo
is defined in /usr/include/netdb.h
. What happens if you compile it
like this:
gcc -c main.c
Do you still get the same behavior? If so, take a look at the output of:
gcc -E main.c
This generates a preprocessed version of the code, with all of the
#include
statements replaced by their actual content. You should be
able to grep through this and see if the compiler is actually getting
/usr/include/netdb.h
if if it's finding something else:
$ gcc -E foo.c | grep netdb.h | awk '{print $3}' | sort -u
Which on my system yields:
"/usr/include/bits/netdb.h"
"/usr/include/netdb.h"
"/usr/include/rpc/netdb.h"
When you add -ansi
to the command line, your are changing the way
gcc
behaves in ways that will break the Linux kernel and many system
header files. The addrinfo
definition in netdb.h
is protected
like this:
#ifdef __USE_POSIX
/* Structure to contain information about address of a service provider. */
struct addrinfo
{
int ai_flags; /* Input flags. */
int ai_family; /* Protocol family for socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol for socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct sockaddr *ai_addr; /* Socket address for socket. */
char *ai_canonname; /* Canonical name for service location. */
struct addrinfo *ai_next; /* Pointer to next in list. */
};
// ...other stuff...
#endif
When you run gcc
with the -ansi
flag, this undefines the
__USE_POSIX
macro, because things protected by this may not be
strictly ANSI compliant. You can see the difference if you compare
this:
gcc -E /usr/include/netdb.h
With this:
gcc -E -ansi /usr/include/netdb.h
Only the former contains the addrinfo
structure.
Use #include <netinet/in.h>
....along with that.....and in compilation (ubuntu)....
gcc server/client -o server/client.c -lpthread
(here lpthread
is a linki processing thread)...which solves your problem. :-D
Linking doesn't attach a header file to the program, pre-processing handles header files.
Linking attaches shared object libraries (look in /usr/lib) to compiled objects. Sometimes it is not sufficent to just add "-lnetdb" as the library might not be in the linker path. In that case, you need to use a -L(path) to add a path entry so the directive "-lnetdb" can find the correct netdb.so file.