rearrange to allow internal/private use of ares_writev to any system

that lacks the writev function.
pull/1/head
Yang Tse 17 years ago
parent 25d9912b38
commit 1a9795b401
  1. 6
      Makefile.inc
  2. 4
      Makefile.vc6
  3. 6
      ares_private.h
  4. 77
      ares_writev.c
  5. 37
      ares_writev.h
  6. 2
      configure.ac
  7. 106
      m4/cares-functions.m4
  8. 12
      nameser.h
  9. 8
      vc/areslib/areslib.dsp
  10. 31
      windows_port.c

@ -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 \

@ -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

@ -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 {

@ -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

@ -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 */

@ -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

@ -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
])

@ -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. */

@ -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

@ -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 */

Loading…
Cancel
Save