unix网络编程卷1:套接字联网 源码编译

时间:2021-05-14 10:59:51

QUICK AND DIRTY

Execute the following from the src/ directory:
一:

./configure    # try to figure out all 

结果是:

........
checking for struct addrinfo... yes
checking for struct if_nameindex... yes
checking for struct sockaddr_dl... no
checking for struct timespec... yes
checking for /dev/tcp... no
checking for /dev/xti/tcp... no
checking for /dev/streams/xtiso/tcp... no
checking for bzero... yes
checking for getaddrinfo... yes
checking for gethostname... yes
checking for gethostbyname2... yes
checking for gethostbyname_r... yes
checking for getnameinfo... yes
checking for hstrerror... yes
checking for if_nametoindex... yes
checking for inet_aton... yes
checking for inet_pton... yes
checking for inet6_rth_init... yes
checking for kqueue... no
checking for kevent... no
checking for mkstemp... yes
checking for poll... yes
checking for pselect... yes
checking for snprintf... yes
checking for sockatmark... yes
checking for vsnprintf... yes
checking for IPv4 support... yes
checking for IPv6 support... yes
checking for Unix domain sockets... yes
checking for multicast support... yes
checking for -I/home/xiahuixia/doc/unp2ev1/src/include... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Make.defines
config.status: creating config.h

configure之后,多出了Makefile, Makefile.defines, config.h文件

二:

 cd lib         # build the basic library that all programs need
make # use "gmake" everywhere on BSD/OS systems

注:lib下的makefile文件内容

include ../Make.defines

all: ${LIB_OBJS}
ar rv ${LIBUNP_NAME} $?
${RANLIB} ${LIBUNP_NAME}

clean:
rm -f ${PROGS} ${CLEANFILES}

注:通过configure生成的Make.defines文件是

#
# This file is generated by autoconf from "Make.defines.in".
#
# This is the "Make.defines" file that almost every "Makefile" in the
# source directories below this directory include.
# The "../" in the pathnames actually refer to this directory, since
# "make" is executed in all the subdirectories of this directory.
#
# System = x86_64-unknown-linux-gnu

CC = gcc
CFLAGS = -I../lib -g -O2 -D_REENTRANT -Wall
LIBS = ../libunp.a -lpthread
LIBS_XTI = ../libunpxti.a ../libunp.a -lpthread
RANLIB = ranlib

# Following is the main library, built from all the object files
# in the lib/ and libfree/ directories.
LIBUNP_NAME = ../libunp.a

# Following is the XTI library, built from all the object files
# in the libxti/ directory.
LIBUNPXTI_NAME = ../libunpxti.a

# Following are all the object files to create in the lib/ directory.
LIB_OBJS = connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o

# Following are all the object files to create in the libfree/ directory.
LIBFREE_OBJS = in_cksum.o inet_ntop.o inet_pton.o

# Following are all the object files to create in the libgai/ directory.
LIBGAI_OBJS =

# Following are all the object files to create in the libroute/ directory.
LIBROUTE_OBJS = get_rtaddrs.o if_indextoname.o if_nameindex.o if_nametoindex.o net_rt_iflist.o net_rt_dump.o sock_masktop.o

# Following are all the object files to create in the libxti/ directory.
LIBXTI_OBJS = wrapxti.o xti_accept.o xti_flags_str.o xti_getopt.o xti_ntop.o xti_ntop_host.o xti_rdwr.o xti_setopt.o xti_str_opts.o xti_tlook_str.o

CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \
*.lc *.lh *.bsdi *.sparc *.uw

结果是:

xiahuixia@xiahuixia-Inspiron-3437:~/unix/unpv13e/lib$ make
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o connect_nonb.o connect_nonb.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o connect_timeo.o connect_timeo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daemon_inetd.o daemon_inetd.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daemon_init.o daemon_init.c
daemon_init.c: In function ‘daemon_init’:
daemon_init.c:34:7: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result [-Wunused-result]
chdir("/"); /* change working directory */
^
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o dg_cli.o dg_cli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o dg_echo.o dg_echo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o error.o error.c
error.c: In function ‘err_doit’:
error.c:102:3: warning: format not a string literal and no format arguments [-Wformat-security]
syslog(level, buf);
^
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o get_ifi_info.o get_ifi_info.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o gf_time.o gf_time.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o host_serv.o host_serv.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o family_to_level.o family_to_level.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_leave.o mcast_leave.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_join.o mcast_join.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_get_if.o mcast_get_if.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_get_loop.o mcast_get_loop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_get_ttl.o mcast_get_ttl.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_set_if.o mcast_set_if.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_set_loop.o mcast_set_loop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o mcast_set_ttl.o mcast_set_ttl.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o my_addrs.o my_addrs.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o read_fd.o read_fd.c
read_fd.c: In function ‘read_fd’:
read_fd.c:45:3: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
*recvfd = *((int *) CMSG_DATA(cmptr));
^
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o readline.o readline.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o readn.o readn.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o readable_timeo.o readable_timeo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o rtt.o rtt.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o signal.o signal.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o signal_intr.o signal_intr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_bind_wild.o sock_bind_wild.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_cmp_addr.o sock_cmp_addr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_cmp_port.o sock_cmp_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_ntop.o sock_ntop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_ntop_host.o sock_ntop_host.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_get_port.o sock_get_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_set_addr.o sock_set_addr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_set_port.o sock_set_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sock_set_wild.o sock_set_wild.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o sockfd_to_family.o sockfd_to_family.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o str_cli.o str_cli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o str_echo.o str_echo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o tcp_connect.o tcp_connect.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o tcp_listen.o tcp_listen.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o tv_sub.o tv_sub.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o udp_client.o udp_client.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o udp_connect.o udp_connect.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o udp_server.o udp_server.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wraplib.o wraplib.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrapsock.o wrapsock.c
wrapsock.c: In function ‘Inet6_rth_space’:
wrapsock.c:81:2: warning: implicit declaration of function ‘inet6_rth_space’ [-Wimplicit-function-declaration]
ret = inet6_rth_space(type, segments);
^
wrapsock.c: In function ‘Inet6_rth_init’:
wrapsock.c:93:2: warning: implicit declaration of function ‘inet6_rth_init’ [-Wimplicit-function-declaration]
ret = inet6_rth_init(rthbuf, rthlen, type, segments);
^
wrapsock.c:93:6: warning: assignment makes pointer from integer without a cast [enabled by default]
ret = inet6_rth_init(rthbuf, rthlen, type, segments);
^
wrapsock.c: In function ‘Inet6_rth_add’:
wrapsock.c:103:2: warning: implicit declaration of function ‘inet6_rth_add’ [-Wimplicit-function-declaration]
if (inet6_rth_add(rthbuf, addr) < 0)
^
wrapsock.c: In function ‘Inet6_rth_reverse’:
wrapsock.c:110:2: warning: implicit declaration of function ‘inet6_rth_reverse’ [-Wimplicit-function-declaration]
if (inet6_rth_reverse(in, out) < 0)
^
wrapsock.c: In function ‘Inet6_rth_segments’:
wrapsock.c:119:2: warning: implicit declaration of function ‘inet6_rth_segments’ [-Wimplicit-function-declaration]
ret = inet6_rth_segments(rthbuf);
^
wrapsock.c: In function ‘Inet6_rth_getaddr’:
wrapsock.c:131:2: warning: implicit declaration of function ‘inet6_rth_getaddr’ [-Wimplicit-function-declaration]
ret = inet6_rth_getaddr(rthbuf, idx);
^
wrapsock.c:131:6: warning: assignment makes pointer from integer without a cast [enabled by default]
ret = inet6_rth_getaddr(rthbuf, idx);
^
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrapstdio.o wrapstdio.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrappthread.o wrappthread.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o wrapunix.o wrapunix.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o write_fd.o write_fd.c
write_fd.c: In function ‘write_fd’:
write_fd.c:24:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
*((int *) CMSG_DATA(cmptr)) = sendfd;
^
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o writen.o writen.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o writable_timeo.o writable_timeo.c
ar rv ../libunp.a connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o
ar: creating ../libunp.a
a - connect_nonb.o
a - connect_timeo.o
a - daemon_inetd.o
a - daemon_init.o
a - dg_cli.o
a - dg_echo.o
a - error.o
a - get_ifi_info.o
a - gf_time.o
a - host_serv.o
a - family_to_level.o
a - mcast_leave.o
a - mcast_join.o
a - mcast_get_if.o
a - mcast_get_loop.o
a - mcast_get_ttl.o
a - mcast_set_if.o
a - mcast_set_loop.o
a - mcast_set_ttl.o
a - my_addrs.o
a - read_fd.o
a - readline.o
a - readn.o
a - readable_timeo.o
a - rtt.o
a - signal.o
a - signal_intr.o
a - sock_bind_wild.o
a - sock_cmp_addr.o
a - sock_cmp_port.o
a - sock_ntop.o
a - sock_ntop_host.o
a - sock_get_port.o
a - sock_set_addr.o
a - sock_set_port.o
a - sock_set_wild.o
a - sockfd_to_family.o
a - str_cli.o
a - str_echo.o
a - tcp_connect.o
a - tcp_listen.o
a - tv_sub.o
a - udp_client.o
a - udp_connect.o
a - udp_server.o
a - wraplib.o
a - wrapsock.o
a - wrapstdio.o
a - wrappthread.o
a - wrapunix.o
a - write_fd.o
a - writen.o
a - writable_timeo.o
ranlib ../libunp.a

三:

  cd ../libfree  # continue building the basic library
make

结果报错:

xiahuixia@xiahuixia-Inspiron-3437:~/unix/unpv13e/libfree$ make
gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o inet_ntop.o inet_ntop.c
inet_ntop.c: In function ‘inet_ntop’:
inet_ntop.c:60:9: error: argument ‘size’ doesn’t match prototype
size_t size;
^
In file included from inet_ntop.c:27:0:
/usr/include/arpa/inet.h:64:20: error: prototype declaration
extern const char *inet_ntop (int __af, const void *__restrict __cp,
^
make: *** [inet_ntop.o] Error 1

解决方法:
经过查询inet_ntop.c 和 inet.h 文件发现在头文件中inet_ntop的原型声明与inet_ntop.c中的该函数实现原型的第三个参数类型不一致

inet.h 和 inet_ntop.c中的函数原型如下:



//inet.h
__const char *inet_ntop (int __af, __const void *__restrict __cp, char *__restrict __buf, socklen_t __len) __THROW;
//inet_ntop.c
const char *
inet_ntop(int af, const void *src, char *dst, size_t size);

其中第三个参数类型分别为socklen_t和size_t,解决方案为在inet_ntop.c中加入以下代码:

#define size_t socklen_t

五:

cd ../libroute # only if your system supports 4.4BSD style routing sockets
make # only if your system supports 4.4BSD style routing sockets

cd ../libxti # only if your system supports XTI
make # only if your system supports XTI

cd ../intro # build and test a basic client program
make daytimetcpcli
./daytimetcpcli 127.0.0.1

If all that works, you’re all set to start compiling individual programs.

Notice that all the source code assumes tabs every 4 columns, not 8.

MORE DETAILS

  1. If you need to make any changes to the “unp.h” header, notice that it
    is a hard link in each directory, so you only need to change it once.

  2. Go into the “lib/” directory and type “make”. This builds the library
    “libunp.a” that is required by almost all of the programs. There may
    be compiler warnings (see NOTES below). This step is where you’ll find
    all of your system’s dependencies, and you must just update your cf/
    files from step 1, rerun “config” and do this step again.

  3. Go into the “libfree/” directory and type “make”. This adds to the
    “libunp.a” library. The files in this directory do not #include
    the “unp.h” header, as people may want to use these functions
    independent of the book’s examples.

  4. Once the library is made from steps 5 and 6, you can then go into any
    of the source code directories and make whatever program you are
    interested in. Note that the horizontal rules at the beginning and
    end of each program listing in the book contain the directory name and
    filename.

    BEWARE: Not all programs in each directory will compile on all systems
    (e.g., the file src/advio/recvfromflags.c will not compile unless your
    system supports the IP_RECVDSTADDR socket option). Also, not all files
    in each directory are included in the book. Beware of any files with
    “test” in the filename: they are probably a quick test program that I
    wrote to check something, and may or may not work.

NOTES

  • Many systems do not have correct function prototypes for the socket
    functions, and this can cause many warnings during compilation.
    For example, Solaris 2.5 omits the “const” from the 2nd argument
    to connect(). Lots of systems use “int” for the length of socket
    address structures, while Posix.1g specifies “size_t”. Lots of
    systems still have the pointer argument to [sg]etsockopt() as a
    “char ” instead of a “void “, and this also causes warnings.

  • SunOS 4.1.x: If you are using Sun’s acc compiler, you need to run
    the configure program as

    CC=acc CFLAGS=-w CPPFLAGS=-w ./configure

    Failure to do this results in numerous system headers (

COMMON DIFFERENCES

These are the common differences that I see in various headers that are
not “yet” at the level of Posix.1g or X/Open XNS Issue 5.

  • getsockopt() and setsockopt(): 5th argument is not correct type.

  • t_bind(): second argument is missing “const”.

  • t_connect(): second argument is missing “const”.

  • t_open(): first argument is missing “const”.

  • t_optmsmg(): second argument is missing “const”.

  • If your