00042 {
00043 int nleft, nrecv;
00044 int select_ret;
00045 char *ptr;
00046 double start_time, current_time;
00047 struct timeval timeout_tv;
00048 fd_set recv_fd_set;
00049 int bytes_ready;
00050 int bytes_to_read;
00051 if (etime_disabled)
00052 {
00053 _timeout = -1.0;
00054 }
00055
00056 bytes_ready = bytes_to_read = 0;
00057 timeout_tv.tv_sec = (long) _timeout;
00058 timeout_tv.tv_usec = (long) (_timeout * 1000000.0);
00059 if (timeout_tv.tv_usec >= 1000000)
00060 {
00061 timeout_tv.tv_usec = timeout_tv.tv_usec % 1000000;
00062 }
00063 FD_ZERO (&recv_fd_set);
00064 RCS_FD_SET (fd, &recv_fd_set);
00065
00066 recvn_timedout = 0;
00067 ptr = (char *) vptr;
00068 nleft = n;
00069 if (NULL != bytes_read_ptr)
00070 {
00071 if (*bytes_read_ptr >= n)
00072 {
00073 rcs_print_error
00074 ("recvn: Invalid parameter -- (*bytes_read_ptr = %d) must be less than (n = %d).\n",
00075 *bytes_read_ptr, n);
00076 return -1;
00077 }
00078 if (*bytes_read_ptr < 0)
00079 {
00080 rcs_print_error
00081 ("recvn: Invalid parameter -- (*bytes_read_ptr = %d) must be greater than or equal to zero.\n");
00082 return -1;
00083 }
00084 ptr += *bytes_read_ptr;
00085 nleft -= *bytes_read_ptr;
00086 }
00087
00088 start_time = etime ();
00089 while (nleft > 0)
00090 {
00091 if (_timeout > 0.0)
00092 {
00093 switch (select_ret =
00094 dl_select (fd + 1, &recv_fd_set, (fd_set *) NULL,
00095 (fd_set *) NULL, &timeout_tv))
00096 {
00097 case -1:
00098 #if !defined(_Windows) || defined(gnuwin32)
00099 rcs_print_error ("Error in select: %d -> %s\n", errno,
00100 strerror (errno));
00101 #else
00102 rcs_print_error ("Error in select: %d\n",
00103 dl_WSAGetLastError ());
00104 #endif
00105 if (NULL == bytes_read_ptr)
00106 {
00107 rcs_print_error
00108 ("recvn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f) failed.\n",
00109 fd, vptr, n, flags, _timeout);
00110 }
00111 else
00112 {
00113 rcs_print_error
00114 ("recvn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f,bytes_read=%d) failed.\n",
00115 fd, vptr, n, flags, _timeout, *bytes_read_ptr);
00116 }
00117 return -1;
00118
00119 case 0:
00120 if (print_recvn_timeout_errors)
00121 {
00122 rcs_print_error ("Recv timed out.\n");
00123 if (NULL == bytes_read_ptr)
00124 {
00125 rcs_print_error
00126 ("recvn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f) failed.\n",
00127 fd, vptr, n, flags, _timeout);
00128 }
00129 else
00130 {
00131 rcs_print_error
00132 ("recvn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f,bytes_read=%d) failed.\n",
00133 fd, vptr, n, flags, _timeout, *bytes_read_ptr);
00134 }
00135 }
00136 recvn_timedout = 1;
00137 if (NULL != bytes_read_ptr)
00138 {
00139 *bytes_read_ptr = (n - nleft);
00140 }
00141 return -1;
00142
00143 default:
00144 break;
00145 }
00146 bytes_ready = 0;
00147 #if defined(WIN32) && !defined(gnuwin32)
00148 dl_ioctlsocket (fd, FIONREAD, &bytes_ready);
00149 #else
00150 #ifndef VXWORKS
00151 #ifdef MSDOS
00152 bytes_ready = nleft;
00153 #else
00154 ioctl (fd, FIONREAD, (caddr_t) & bytes_ready);
00155 #endif
00156 #else
00157 ioctl (fd, FIONREAD, (int) &bytes_ready);
00158 #endif
00159 #endif
00160 bytes_to_read = (nleft <= bytes_ready) ? nleft : bytes_ready;
00161 }
00162 else
00163 {
00164 bytes_to_read = nleft;
00165 }
00166 nrecv = 0;
00167 if (bytes_to_read > 0)
00168 {
00169 if ((nrecv = dl_recv (fd, ptr, bytes_to_read, flags)) == -1)
00170 {
00171 if (
00172 #if !defined(_WINDOWS) || defined(gnuwin32)
00173 #ifdef MSDOS
00174 (EWOULDBLOCK == (tk_geterrno (fd)))
00175 #else
00176 (errno == EWOULDBLOCK)
00177 #endif
00178 #else
00179 (WSAEWOULDBLOCK == (dl_WSAGetLastError ()))
00180 #endif
00181 )
00182 {
00183 if (fabs (_timeout) < 1e-6)
00184 {
00185 recvn_timedout = 1;
00186 if (NULL != bytes_read_ptr)
00187 {
00188 *bytes_read_ptr = (n - nleft);
00189 }
00190 return -1;
00191 }
00192 }
00193 else
00194 {
00195 #ifndef UNDER_CE
00196 #ifdef WIN32
00197 rcs_print_sys_error (WSAGETLASTERROR_ERROR_SOURCE,
00198 "recv error:");
00199 #else
00200 rcs_print_error ("Recv error: %d = %s\n", errno,
00201 strerror (errno));
00202 #endif
00203 #endif
00204 if (NULL == bytes_read_ptr)
00205 {
00206 rcs_print_error
00207 ("recvn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f) failed.\n",
00208 fd, vptr, n, flags, _timeout);
00209 }
00210 else
00211 {
00212 rcs_print_error
00213 ("recvn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f,bytes_read=%d) failed.\n",
00214 fd, vptr, n, flags, _timeout, *bytes_read_ptr);
00215 }
00216 if (NULL != bytes_read_ptr)
00217 {
00218 *bytes_read_ptr = (n - nleft);
00219 }
00220 return (-1);
00221 }
00222 nrecv = 0;
00223 }
00224 else if (nrecv == 0)
00225 {
00226 rcs_print_error ("recvn: Premature EOF recieved.\n");
00227 return (-2);
00228 }
00229 }
00230 nleft -= nrecv;
00231 ptr += nrecv;
00232 if (nleft > 0 && _timeout > 0.0)
00233 {
00234 esleep (0.001);
00235 current_time = etime ();
00236 if (current_time - start_time > _timeout)
00237 {
00238 rcs_print_error ("Recv timed out.\n");
00239 recvn_timedout = 1;
00240 if (NULL != bytes_read_ptr)
00241 {
00242 *bytes_read_ptr = (n - nleft);
00243 }
00244 return (-1);
00245 }
00246 }
00247 }
00248 rcs_print_debug (PRINT_SOCKET_READ_SIZE, "read %d bytes from %d\n", n, fd);
00249 if (NULL != bytes_read_ptr)
00250 {
00251 *bytes_read_ptr = (n - nleft);
00252 }
00253 return (n - nleft);
00254 }