rearrange to allow internal/private use of ares_writev to any system
authorYang Tse <yangsita@gmail.com>
Tue, 16 Sep 2008 16:42:48 +0000 (16:42 +0000)
committerYang Tse <yangsita@gmail.com>
Tue, 16 Sep 2008 16:42:48 +0000 (16:42 +0000)
that lacks the writev function.

Makefile.inc
Makefile.vc6
ares_private.h
ares_writev.c [new file with mode: 0644]
ares_writev.h [new file with mode: 0644]
configure.ac
m4/cares-functions.m4
nameser.h
vc/areslib/areslib.dsp
windows_port.c

index 1c22abb..d6bf064 100644 (file)
@@ -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               \
index 8bf5a08..7b8af31 100644 (file)
@@ -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
index e138cdd..0b4edf9 100644 (file)
@@ -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
 #  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 (file)
index 0000000..045373b
--- /dev/null
@@ -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 <limits.h>
+#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 (file)
index 0000000..f5850ef
--- /dev/null
@@ -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 */
index 6468dbe..bc98a5e 100644 (file)
@@ -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
index 70864ab..d985135 100644 (file)
@@ -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 <sys/types.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include <sys/uio.h>
+#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
+])
index b5add93..f2b68f1 100644 (file)
--- a/nameser.h
+++ b/nameser.h
 
 #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. */
index 83cab07..2862afd 100644 (file)
@@ -197,6 +197,10 @@ SOURCE=..\..\ares_version.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\ares_writev.c\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\bitncmp.c\r
 # End Source File\r
 # Begin Source File\r
@@ -245,6 +249,10 @@ SOURCE=..\..\ares_version.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\ares_writev.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\bitncmp.h\r
 # End Source File\r
 # Begin Source File\r
index 8b5e149..cc31036 100644 (file)
@@ -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 */