From 1a9795b401092199b401843bb74cb05dd3849445 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 16 Sep 2008 16:42:48 +0000 Subject: [PATCH] rearrange to allow internal/private use of ares_writev to any system that lacks the writev function. --- Makefile.inc | 6 +-- Makefile.vc6 | 4 ++ ares_private.h | 6 +++ ares_writev.c | 77 +++++++++++++++++++++++++++++++++++ ares_writev.h | 37 +++++++++++++++++ configure.ac | 2 + m4/cares-functions.m4 | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ nameser.h | 12 +----- vc/areslib/areslib.dsp | 8 ++++ windows_port.c | 31 --------------- 10 files changed, 245 insertions(+), 44 deletions(-) create mode 100644 ares_writev.c create mode 100644 ares_writev.h diff --git a/Makefile.inc b/Makefile.inc index 1c22abb..d6bf064 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -5,12 +5,12 @@ ares_gethostbyname.c ares_strerror.c ares_cancel.c ares_init.c \ ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c \ ares_expand_name.c ares_parse_a_reply.c windows_port.c ares_strdup.c \ ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c \ -ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c \ +ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c ares_writev.c \ ares_parse_ns_reply.c ares_llist.c ares__timeval.c ares_strcasecmp.c HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \ - nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h \ - setup_once.h ares_llist.h ares_strdup.h ares_strcasecmp.h + nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h setup_once.h \ + ares_llist.h ares_strdup.h ares_strcasecmp.h ares_writev.h MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \ ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \ diff --git a/Makefile.vc6 b/Makefile.vc6 index 8bf5a08..7b8af31 100644 --- a/Makefile.vc6 +++ b/Makefile.vc6 @@ -74,6 +74,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj \ $(OBJ_DIR)\windows_port.obj \ $(OBJ_DIR)\ares_expand_string.obj \ $(OBJ_DIR)\ares_parse_ptr_reply.obj \ + $(OBJ_DIR)\ares_writev.obj \ $(OBJ_DIR)\bitncmp.obj \ $(OBJ_DIR)\inet_net_pton.obj \ $(OBJ_DIR)\inet_ntop.obj @@ -246,3 +247,6 @@ $(OBJ_DIR)\ares_getopt.obj: ares_getopt.c ares_getopt.h $(OBJ_DIR)\ares_llist.obj: ares_llist.c setup.h setup_once.h ares.h \ ares_private.h ares_llist.h + +$(OBJ_DIR)\ares_writev.obj: ares_writev.c setup.h setup_once.h ares.h \ + ares_writev.h diff --git a/ares_private.h b/ares_private.h index e138cdd..0b4edf9 100644 --- a/ares_private.h +++ b/ares_private.h @@ -43,6 +43,7 @@ #undef closesocket #define closesocket(s) close_s(s) #define writev(s,v,c) writev_s(s,v,c) +#define HAVE_WRITEV 1 #endif #ifdef NETWARE @@ -109,6 +110,11 @@ # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n) #endif +#ifndef HAVE_WRITEV +# include "ares_writev.h" +# define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) +#endif + struct query; struct send_request { diff --git a/ares_writev.c b/ares_writev.c new file mode 100644 index 0000000..045373b --- /dev/null +++ b/ares_writev.c @@ -0,0 +1,77 @@ + +/* $Id$ */ + +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "setup.h" + +#include +#include "ares.h" +#include "ares_private.h" + +#ifndef HAVE_WRITEV +ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt) +{ + char *buffer, *bp; + int i; + size_t bytes = 0; + ssize_t result; + + /* Validate iovcnt */ + if (iovcnt <= 0) + { + SET_ERRNO(EINVAL); + return (-1); + } + + /* Validate and find the sum of the iov_len values in the iov array */ + for (i = 0; i < iovcnt; i++) + { + if (iov[i].iov_len > INT_MAX - bytes) + { + SET_ERRNO(EINVAL); + return (-1); + } + bytes += iov[i].iov_len; + } + + if (bytes == 0) + return (0); + + /* Allocate a temporary buffer to hold the data */ + buffer = malloc(bytes); + if (!buffer) + { + SET_ERRNO(ENOMEM); + return (-1); + } + + /* Copy the data into buffer */ + for (bp = buffer, i = 0; i < iovcnt; ++i) + { + memcpy (bp, iov[i].iov_base, iov[i].iov_len); + bp += iov[i].iov_len; + } + + /* Send buffer contents */ + result = swrite(s, buffer, bytes); + + free(buffer); + + return (result); +} +#endif + diff --git a/ares_writev.h b/ares_writev.h new file mode 100644 index 0000000..f5850ef --- /dev/null +++ b/ares_writev.h @@ -0,0 +1,37 @@ +#ifndef HEADER_CARES_WRITEV_H +#define HEADER_CARES_WRITEV_H + +/* $Id$ */ + +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "setup.h" +#include "ares.h" + +#ifndef HAVE_WRITEV + +/* Structure for scatter/gather I/O. */ +struct iovec +{ + void *iov_base; /* Pointer to data. */ + size_t iov_len; /* Length of data. */ +}; + +extern ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt); + +#endif + +#endif /* HEADER_CARES_WRITEV_H */ diff --git a/configure.ac b/configure.ac index 6468dbe..bc98a5e 100644 --- a/configure.ac +++ b/configure.ac @@ -545,6 +545,7 @@ AC_CHECK_HEADERS( sys/socket.h \ sys/ioctl.h \ sys/param.h \ + sys/uio.h \ netdb.h \ netinet/in.h \ netinet/tcp.h \ @@ -651,6 +652,7 @@ CARES_CHECK_FUNC_STRICMP CARES_CHECK_FUNC_STRNCASECMP CARES_CHECK_FUNC_STRNCMPI CARES_CHECK_FUNC_STRNICMP +CARES_CHECK_FUNC_WRITEV dnl check for AF_INET6 diff --git a/m4/cares-functions.m4 b/m4/cares-functions.m4 index 70864ab..d985135 100644 --- a/m4/cares-functions.m4 +++ b/m4/cares-functions.m4 @@ -43,6 +43,27 @@ cares_includes_string="\ ]) +dnl CARES_INCLUDES_SYS_UIO +dnl ------------------------------------------------- +dnl Set up variable with list of headers that must be +dnl included when sys/uio.h is to be included. + +AC_DEFUN([CARES_INCLUDES_SYS_UIO], [ +cares_includes_sys_uio="\ +/* includes start */ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_UIO_H +# include +#endif +/* includes end */" + AC_CHECK_HEADERS( + sys/types.h sys/uio.h, + [], [], [$cares_includes_sys_uio]) +]) + + dnl CARES_CHECK_FUNC_STRCASECMP dnl ------------------------------------------------- dnl Verify if strcasecmp is available, prototyped, and @@ -636,3 +657,88 @@ AC_DEFUN([CARES_CHECK_FUNC_STRNICMP], [ ac_cv_func_strnicmp="no" fi ]) + + +dnl CARES_CHECK_FUNC_WRITEV +dnl ------------------------------------------------- +dnl Verify if writev is available, prototyped, and +dnl can be compiled. If all of these are true, and +dnl usage has not been previously disallowed with +dnl shell variable cares_disallow_writev, then +dnl HAVE_WRITEV will be defined. + +AC_DEFUN([CARES_CHECK_FUNC_WRITEV], [ + AC_REQUIRE([CARES_INCLUDES_SYS_UIO])dnl + # + tst_links_writev="unknown" + tst_proto_writev="unknown" + tst_compi_writev="unknown" + tst_allow_writev="unknown" + # + AC_MSG_CHECKING([if writev can be linked]) + AC_LINK_IFELSE([ + AC_LANG_FUNC_LINK_TRY([writev]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_writev="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_writev="no" + ]) + # + if test "$tst_links_writev" = "yes"; then + AC_MSG_CHECKING([if writev is prototyped]) + AC_EGREP_CPP([writev],[ + $cares_includes_sys_uio + ],[ + AC_MSG_RESULT([yes]) + tst_proto_writev="yes" + ],[ + AC_MSG_RESULT([no]) + tst_proto_writev="no" + ]) + fi + # + if test "$tst_proto_writev" = "yes"; then + AC_MSG_CHECKING([if writev is compilable]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $cares_includes_sys_uio + ]],[[ + if(0 != writev(0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_writev="yes" + ],[ + AC_MSG_RESULT([no]) + tst_compi_writev="no" + ]) + fi + # + if test "$tst_compi_writev" = "yes"; then + AC_MSG_CHECKING([if writev usage allowed]) + if test "x$cares_disallow_writev" != "xyes"; then + AC_MSG_RESULT([yes]) + tst_allow_writev="yes" + else + AC_MSG_RESULT([no]) + tst_allow_writev="no" + fi + fi + # + AC_MSG_CHECKING([if writev might be used]) + if test "$tst_links_writev" = "yes" && + test "$tst_proto_writev" = "yes" && + test "$tst_compi_writev" = "yes" && + test "$tst_allow_writev" = "yes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_WRITEV, 1, + [Define to 1 if you have the writev function.]) + ac_cv_func_writev="yes" + else + AC_MSG_RESULT([no]) + ac_cv_func_writev="no" + fi +]) diff --git a/nameser.h b/nameser.h index b5add93..f2b68f1 100644 --- a/nameser.h +++ b/nameser.h @@ -13,20 +13,10 @@ #ifndef NETWARE -/* Structure for scatter/gather I/O. */ -struct iovec -{ - void *iov_base; /* Pointer to data. */ - size_t iov_len; /* Length of data. */ -}; - #ifndef __WATCOMC__ #define getpid() _getpid() #endif -int ares_writev (SOCKET s, const struct iovec *vector, size_t count); -#define writev(s,vect,count) ares_writev(s,vect,count) - #endif /* !NETWARE */ #define NS_CMPRSFLGS 0xc0 @@ -94,6 +84,8 @@ typedef enum __ns_type { ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ ns_t_sink = 40, /* Kitchen sink (experimentatl) */ ns_t_opt = 41, /* EDNS0 option (meta-RR) */ + ns_t_apl = 42, /* Address prefix list (RFC3123) */ + ns_t_tkey = 249, /* Transaction key */ ns_t_tsig = 250, /* Transaction signature. */ ns_t_ixfr = 251, /* Incremental zone transfer. */ ns_t_axfr = 252, /* Transfer zone of authority. */ diff --git a/vc/areslib/areslib.dsp b/vc/areslib/areslib.dsp index 83cab07..2862afd 100644 --- a/vc/areslib/areslib.dsp +++ b/vc/areslib/areslib.dsp @@ -197,6 +197,10 @@ SOURCE=..\..\ares_version.c # End Source File # Begin Source File +SOURCE=..\..\ares_writev.c +# End Source File +# Begin Source File + SOURCE=..\..\bitncmp.c # End Source File # Begin Source File @@ -245,6 +249,10 @@ SOURCE=..\..\ares_version.h # End Source File # Begin Source File +SOURCE=..\..\ares_writev.h +# End Source File +# Begin Source File + SOURCE=..\..\bitncmp.h # End Source File # Begin Source File diff --git a/windows_port.c b/windows_port.c index 8b5e149..cc31036 100644 --- a/windows_port.c +++ b/windows_port.c @@ -34,36 +34,5 @@ WINAPI DllMain (HINSTANCE hnd, DWORD reason, LPVOID reserved) } #endif -int -ares_writev (ares_socket_t s, const struct iovec *vector, size_t count) -{ - char *buffer, *bp; - size_t i, bytes = 0; - - /* Find the total number of bytes to write - */ - for (i = 0; i < count; i++) - bytes += vector[i].iov_len; - - if (bytes == 0) /* not an error */ - return (0); - /* Allocate a temporary buffer to hold the data - */ - buffer = bp = (char*) alloca (bytes); - if (!buffer) - { - SET_ERRNO(ENOMEM); - return (-1); - } - - /* Copy the data into buffer. - */ - for (i = 0; i < count; ++i) - { - memcpy (bp, vector[i].iov_base, vector[i].iov_len); - bp += vector[i].iov_len; - } - return (int)swrite(s, buffer, bytes); -} #endif /* WIN32 builds only */ -- 2.7.4