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

that lacks the writev function.
This commit is contained in:
Yang Tse 2008-09-16 16:42:48 +00:00
Родитель ee5f13cb6b
Коммит aa41743ebd
12 изменённых файлов: 351 добавлений и 44 удалений

Просмотреть файл

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

77
ares/ares_writev.c Normal file
Просмотреть файл

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

37
ares/ares_writev.h Normal file
Просмотреть файл

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

Просмотреть файл

@ -1900,6 +1900,7 @@ AC_CHECK_HEADERS(
sys/select.h \
sys/socket.h \
sys/ioctl.h \
sys/uio.h \
assert.h \
unistd.h \
stdlib.h \
@ -2051,6 +2052,7 @@ CURL_CHECK_FUNC_STRNCMPI
CURL_CHECK_FUNC_STRNICMP
CURL_CHECK_FUNC_STRTOK_R
CURL_CHECK_FUNC_STRTOLL
CURL_CHECK_FUNC_WRITEV
dnl Checks for library functions.
dnl AC_PROG_GCC_TRADITIONAL

Просмотреть файл

@ -112,6 +112,27 @@ curl_includes_string="\
])
dnl CURL_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([CURL_INCLUDES_SYS_UIO], [
curl_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,
[], [], [$curl_includes_sys_uio])
])
dnl CURL_INCLUDES_TIME
dnl -------------------------------------------------
dnl Set up variable with list of headers that must be
@ -1722,3 +1743,86 @@ AC_DEFUN([CURL_CHECK_FUNC_STRTOLL], [
])
dnl CURL_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 curl_disallow_writev, then
dnl HAVE_WRITEV will be defined.
AC_DEFUN([CURL_CHECK_FUNC_WRITEV], [
AC_REQUIRE([CURL_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],[
$curl_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([[
$curl_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$curl_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
])