1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

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
parent ee5f13cb6b
commit aa41743ebd
12 changed files with 351 additions and 44 deletions

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

View 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

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

View 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

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

View File

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

View File

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

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

View File

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

View File

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