00001
00002
00003
00004
00005
00006 #ifdef USE_PCNFS
00007 #undef USE_PCNFS
00008 #endif
00009
00010
00011 #include "rcs_defs.hh"
00012 #include "dbg_mem.h"
00013
00014
00015 #include "sendmsgt.h"
00016
00017 #ifndef UNDER_CE
00018 #include <sys/types.h>
00019
00020 #else
00021 #include <windows.h>
00022 #endif
00023
00024 #if !defined(DOS_WINDOWS) || defined(gnuwin32)
00025 #include <sys/socket.h>
00026 #ifndef VXWORKS
00027 #include <sys/time.h>
00028 #else
00029 #include <sys/times.h>
00030 #include <sockLib.h>
00031 #endif
00032 #ifndef _Windows
00033 #include <unistd.h>
00034 #endif
00035 #else
00036 #if defined(MSDOS) && !defined(WINDOWS)
00037 #include <tklib.h>
00038 #include <sys/socket.h>
00039 #include <sys/uio.h>
00040 #else
00041 #ifdef USE_OLD_WINSOCK
00042 #include <winsock.h>
00043 #else
00044 #include <winsock2.h>
00045 #endif
00046
00047 #endif
00048 #endif
00049 #ifndef irix6
00050 #include <math.h>
00051 #else
00052
00053
00054
00055
00056 extern double fmod (double, double);
00057 #endif
00058
00059 #ifndef UNDER_CE
00060 #include <errno.h>
00061 #endif
00062 #include <string.h>
00063 #include <stdlib.h>
00064 #include "rcs_prnt.hh"
00065 #include "sokintrf.h"
00066
00067 static long total_bytes_sent = 0;
00068
00069 #define USE_SENDTO
00070 #if defined(_Windows) && !defined(USE_PCNFS)
00071 #ifndef USE_SENDTO
00072 #define USE_SENDTO
00073 #endif
00074 #endif
00075
00076
00077
00078 #ifdef USE_SENDTO
00079 static char RCS_FAR *collection_buffer = NULL;
00080 static long collection_buffer_size = 0;
00081 #endif
00082
00083 int sendmsgt_timed_out = 0;
00084
00085 int
00086 sendmsgt (int _socket_fd, struct msghdr *_msg_header, int _flags,
00087 double _timeout)
00088 {
00089 struct timeval timeout_timeval;
00090 fd_set write_fd_set;
00091 int bytes_sent, i;
00092 long required_size = 0;
00093 char *temp_pointer;
00094 sendmsgt_timed_out = 0;
00095
00096 #ifdef USE_SENDTO
00097 if (_msg_header->msg_iovlen > 1)
00098 {
00099 for (i = 0, required_size = 0; i < _msg_header->msg_iovlen; i++)
00100 {
00101 required_size += _msg_header->msg_iov[i].iov_len;
00102 }
00103 if (required_size > collection_buffer_size)
00104 {
00105 if (NULL != collection_buffer)
00106 {
00107 DEBUG_FREE (collection_buffer);
00108 collection_buffer = NULL;
00109 }
00110 collection_buffer = (char *) DEBUG_MALLOC (required_size);
00111 collection_buffer_size = required_size;
00112 }
00113 if (NULL == collection_buffer)
00114 {
00115 collection_buffer_size = 0;
00116 rcs_print_error ("Couldn't malloc collection buffer of size %ld.\n",
00117 required_size);
00118 return (-1);
00119 }
00120 for (i = 0, temp_pointer = collection_buffer;
00121 i < _msg_header->msg_iovlen; i++)
00122 {
00123 memcpy (temp_pointer, _msg_header->msg_iov[i].iov_base,
00124 _msg_header->msg_iov[i].iov_len);
00125 temp_pointer += _msg_header->msg_iov[i].iov_len;
00126 }
00127 }
00128 #endif
00129
00130 if (_timeout > 1E-6)
00131 {
00132 timeout_timeval.tv_sec = (long) _timeout;
00133 timeout_timeval.tv_usec = (long) (_timeout * 1000000.0);
00134 if (timeout_timeval.tv_usec >= 1000000)
00135 {
00136 timeout_timeval.tv_usec = timeout_timeval.tv_usec % 1000000;
00137 }
00138 FD_ZERO (&write_fd_set);
00139 RCS_FD_SET (_socket_fd, &write_fd_set);
00140 switch (dl_select
00141 (_socket_fd + 1, NULL, &write_fd_set, NULL, &timeout_timeval))
00142 {
00143 case -1:
00144 #ifndef UNDER_CE
00145 rcs_print_error ("sendmsgt: select error: %d %s\n",
00146 errno, strerror (errno));
00147 #endif
00148 return -1;
00149
00150 case 0:
00151 sendmsgt_timed_out = 1;
00152 rcs_print_error ("sendmgt: select timed out.\n");
00153 return (0);
00154
00155 default:
00156 break;
00157 }
00158 }
00159 else if (_timeout > -1E-6)
00160 {
00161 timeout_timeval.tv_sec = 0L;
00162 timeout_timeval.tv_usec = 0L;
00163 FD_ZERO (&write_fd_set);
00164 RCS_FD_SET (_socket_fd, &write_fd_set);
00165 switch (dl_select
00166 (_socket_fd + 1, NULL, &write_fd_set, NULL, &timeout_timeval))
00167 {
00168 case -1:
00169 #ifndef UNDER_CE
00170 rcs_print_error ("sendmsgt: select error: %d %s\n",
00171 errno, strerror (errno));
00172 #endif
00173 return -1;
00174
00175 case 0:
00176 sendmsgt_timed_out = 1;
00177 return (0);
00178
00179 default:
00180 break;
00181 }
00182 }
00183 #ifdef USE_SENDTO
00184 if (_msg_header->msg_iovlen > 1)
00185 {
00186 bytes_sent =
00187 dl_sendto (_socket_fd, collection_buffer, required_size, _flags,
00188 (struct sockaddr *) _msg_header->msg_name,
00189 _msg_header->msg_namelen);
00190 }
00191 else
00192 {
00193 bytes_sent = dl_sendto (_socket_fd, _msg_header->msg_iov[0].iov_base,
00194 _msg_header->msg_iov[0].iov_len, _flags,
00195 (struct sockaddr *) _msg_header->msg_name,
00196 _msg_header->msg_namelen);
00197 }
00198 #if defined(_Windows) && !defined(gnuwin32)
00199 if (bytes_sent == SOCKET_ERROR)
00200 {
00201 rcs_print_error ("sendmsgt: send_to error %d\n", dl_WSAGetLastError ());
00202 return (-1);
00203 }
00204 #else
00205 if (bytes_sent < 0)
00206 {
00207 rcs_print_error ("sendto(%d,%p,%d,0x%X,%s,%d) failed: %d -- %s \n",
00208 _socket_fd, _msg_header->msg_iov[0].iov_base,
00209 _msg_header->msg_iov[0].iov_len, _flags,
00210 dl_inet_ntoa (
00211 ((struct sockaddr_in *)
00212 _msg_header->msg_name)->sin_addr),
00213 _msg_header->msg_namelen,
00214 #ifndef UNDER_CE
00215 errno, strerror (errno));
00216 #else
00217 0, "?");
00218 #endif
00219 }
00220 #endif
00221 #else
00222 bytes_sent = sendmsg (_socket_fd, _msg_header, _flags);
00223 if (bytes_sent < 0)
00224 {
00225 rcs_print_error ("sendmsg(%d,%p,%d) error: %d = %s\n",
00226 _socket_fd, _msg_header, _flags,
00227 #ifndef UNDER_CE
00228 errno, strerror (errno));
00229 #else
00230 0, "?");
00231 #endif
00232 rcs_print_error (" _msg_header->msg_iovlen = %d\n",
00233 _msg_header->msg_iovlen);
00234 rcs_print_error ("_msg_header->msg_iov[0].iov_len = %d\n",
00235 _msg_header->msg_iov[0].iov_len);
00236 }
00237 #endif
00238 total_bytes_sent += bytes_sent;
00239 rcs_print_debug (PRINT_SOCKET_WRITE_SIZE, "sendmsg %d bytes to %d\n",
00240 bytes_sent, _socket_fd);
00241 return (bytes_sent);
00242 }
00243
00244
00245 void
00246 free_sendmsg_collection_buffer ()
00247 {
00248 #if defined(_Windows) && !defined(USE_PCNFS)
00249 if (NULL != collection_buffer)
00250 {
00251 DEBUG_FREE (collection_buffer);
00252 collection_buffer = NULL;
00253 collection_buffer_size = 0;
00254 }
00255 #endif
00256 }