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