#include "rcs_defs.hh"
#include "recvline.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stddef.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "rcs_prnt.hh"
#include "sokintrf.h"
#include "_timer.h"
#include "dbg_mem.h"
Include dependency graph for recvline.c:
Go to the source code of this file.
Data Structures | |
struct | prev_read_info_struct |
Functions | |
void | clean_prev_read_info (int fd) |
int | get_bytes_already_read (int fd) |
int | recvline (int fd, char *cptr, int maxbytes, int flags, double _timeout, int *bytes_read_ptr) |
Variables | |
int | recvline_timedout = 0 |
prev_read_info_struct | prev_read_info [256] |
int | prev_read_infos = 0 |
int | initialized = 0 |
|
Definition at line 88 of file recvline.c. 00089 { 00090 int max_prev_read_info = 0; 00091 int i; 00092 00093 if (fd < 1) 00094 { 00095 return; 00096 } 00097 #ifdef VXWORKS 00098 if (tasklock_recvline_prev_read_info) 00099 taskLock (); 00100 #endif 00101 00102 for (i = 0; i < 256; i++) 00103 { 00104 if (prev_read_info[i].fd == fd) 00105 { 00106 prev_read_info[i].ptr = NULL; 00107 if (NULL != prev_read_info[i].buf) 00108 { 00109 DEBUG_FREE (prev_read_info[i].buf); 00110 prev_read_info[i].buf = NULL; 00111 } 00112 prev_read_info[i].buf_size = 0; 00113 prev_read_info[i].fd = -1; 00114 continue; 00115 } 00116 if (prev_read_info[i].fd > 0) 00117 { 00118 max_prev_read_info = i; 00119 } 00120 } 00121 prev_read_infos = max_prev_read_info; 00122 00123 #ifdef VXWORKS 00124 if (tasklock_recvline_prev_read_info) 00125 taskUnlock (); 00126 #endif 00127 00128 } |
|
Definition at line 132 of file recvline.c. 00133 { 00134 int bytes_left; 00135 int i; 00136 00137 if (fd < 1) 00138 { 00139 return -1; 00140 } 00141 00142 #ifdef VXWORKS 00143 if (tasklock_recvline_prev_read_info) 00144 taskLock (); 00145 #endif 00146 00147 for (i = 0; i < prev_read_infos; i++) 00148 { 00149 if (prev_read_info[i].fd == fd) 00150 { 00151 bytes_left = prev_read_info[i].buf_size - 00152 ((unsigned long) prev_read_info[i].ptr 00153 - (unsigned long) prev_read_info[i].buf); 00154 #ifdef VXWORKS 00155 if (tasklock_recvline_prev_read_info) 00156 taskUnlock (); 00157 #endif 00158 return bytes_left; 00159 } 00160 } 00161 00162 #ifdef VXWORKS 00163 if (tasklock_recvline_prev_read_info) 00164 taskUnlock (); 00165 #endif 00166 00167 return 0; 00168 } |
|
Definition at line 172 of file recvline.c. 00174 { 00175 #if defined(_Windows) 00176 int error_value = 0; 00177 #endif 00178 char *previous_read_ptr = NULL; 00179 char *previous_read_buf = NULL; 00180 char *nptr; 00181 int bytes_read = 0; 00182 int bytes_ready; 00183 int nrecv; 00184 int i; 00185 int select_ret; 00186 char *ptr; 00187 int bytes_left; 00188 double start_time, current_time; 00189 struct timeval timeout_tv; 00190 fd_set recv_fd_set; 00191 int first_empty_slot = -1; 00192 int max_prev_read_info = 0; 00193 int current_prev_read_info = -1; 00194 if (etime_disabled) 00195 { 00196 _timeout = -1.0; 00197 } 00198 00199 if (fd < 1 || cptr == NULL) 00200 { 00201 rcs_print_error ("recvline: Invalid parameter. fd=%d, cptr=%p\n", fd, 00202 cptr); 00203 return -1; 00204 } 00205 recvline_timedout = 0; 00206 timeout_tv.tv_sec = (long) _timeout; 00207 timeout_tv.tv_usec = (long) (_timeout * 1000000.0); 00208 if (timeout_tv.tv_usec >= 1000000) 00209 { 00210 timeout_tv.tv_usec = timeout_tv.tv_usec % 1000000; 00211 } 00212 FD_ZERO (&recv_fd_set); 00213 RCS_FD_SET (fd, &recv_fd_set); 00214 00215 #ifdef VXWORKS 00216 if (tasklock_recvline_prev_read_info) 00217 taskLock (); 00218 #endif 00219 00220 if (!initialized) 00221 { 00222 for (i = 0; i < 256; i++) 00223 { 00224 prev_read_info[i].ptr = NULL; 00225 prev_read_info[i].buf = NULL; 00226 prev_read_info[i].fd = 0; 00227 prev_read_info[i].buf_size = 0; 00228 } 00229 prev_read_infos = 0; 00230 initialized = 1; 00231 } 00232 00233 #ifdef VXWORKS 00234 if (tasklock_recvline_prev_read_info) 00235 taskUnlock (); 00236 #endif 00237 00238 00239 for (i = 0; i < prev_read_infos; i++) 00240 { 00241 if (prev_read_info[i].fd == fd) 00242 { 00243 previous_read_ptr = prev_read_info[i].ptr; 00244 previous_read_buf = prev_read_info[i].buf; 00245 if (NULL == prev_read_info[i].buf || NULL == prev_read_info[i].ptr) 00246 { 00247 rcs_print_error 00248 ("Invalid prev_read_info. buf =%p, ptr=%p, fd = %d, buf_size=%d(0x%X)\n", 00249 prev_read_info[i].buf, prev_read_info[i].ptr, 00250 prev_read_info[i].fd, prev_read_info[i].buf_size, 00251 prev_read_info[i].buf_size); 00252 prev_read_info[i].ptr = NULL; 00253 prev_read_info[i].buf = NULL; 00254 prev_read_info[i].fd = 0; 00255 prev_read_info[i].buf_size = 0; 00256 continue; 00257 } 00258 else if ((unsigned long) previous_read_ptr > 00259 ((unsigned long) previous_read_buf) + 00260 prev_read_info[i].buf_size) 00261 { 00262 rcs_print_error 00263 ("Invalid prev_read_info. buf =%p, ptr=%p, fd = %d, buf_size=%d(0x%X)\n", 00264 prev_read_info[i].buf, prev_read_info[i].ptr, 00265 prev_read_info[i].fd, prev_read_info[i].buf_size, 00266 prev_read_info[i].buf_size); 00267 prev_read_info[i].ptr = NULL; 00268 prev_read_info[i].buf = NULL; 00269 prev_read_info[i].fd = 0; 00270 prev_read_info[i].buf_size = 0; 00271 continue; 00272 } 00273 else if ((unsigned long) previous_read_ptr < 00274 ((unsigned long) previous_read_buf)) 00275 { 00276 rcs_print_error 00277 ("Invalid prev_read_info. buf =%p, ptr=%p, fd = %d, buf_size=%d(0x%X)\n", 00278 prev_read_info[i].buf, prev_read_info[i].ptr, 00279 prev_read_info[i].fd, prev_read_info[i].buf_size, 00280 prev_read_info[i].buf_size); 00281 prev_read_info[i].ptr = NULL; 00282 prev_read_info[i].buf = NULL; 00283 prev_read_info[i].fd = 0; 00284 prev_read_info[i].buf_size = 0; 00285 continue; 00286 } 00287 00288 max_prev_read_info = i; 00289 current_prev_read_info = i; 00290 break; 00291 } 00292 if (prev_read_info[i].fd < 1 && first_empty_slot < 0) 00293 { 00294 first_empty_slot = i; 00295 } 00296 else 00297 { 00298 max_prev_read_info = i; 00299 } 00300 } 00301 if (first_empty_slot < 0) 00302 { 00303 first_empty_slot = prev_read_infos; 00304 } 00305 prev_read_infos = max_prev_read_info + 1; 00306 00307 00308 if (previous_read_ptr != NULL) 00309 { 00310 if (*previous_read_ptr != 0) 00311 { 00312 ptr = strchr (previous_read_ptr, '\n'); 00313 if (NULL != ptr) 00314 { 00315 *ptr = 0; 00316 bytes_left = 00317 prev_read_info[current_prev_read_info].buf_size - 00318 ((unsigned long) previous_read_ptr - 00319 (unsigned long) previous_read_buf); 00320 if (bytes_left <= 0) 00321 { 00322 rcs_print_error ("Problem with previous_read_ptr.\n"); 00323 prev_read_info[current_prev_read_info].ptr = NULL; 00324 prev_read_info[current_prev_read_info].buf = NULL; 00325 prev_read_info[current_prev_read_info].fd = 0; 00326 prev_read_info[current_prev_read_info].buf_size = 0; 00327 return -1; 00328 } 00329 strncpy (cptr, previous_read_ptr, bytes_left); 00330 previous_read_ptr = ptr; 00331 previous_read_ptr++; 00332 bytes_read = strlen (cptr); 00333 if (NULL != bytes_read_ptr) 00334 { 00335 *bytes_read_ptr = bytes_read; 00336 } 00337 bytes_left = 00338 prev_read_info[current_prev_read_info].buf_size - 00339 ((unsigned long) previous_read_ptr - 00340 (unsigned long) previous_read_buf); 00341 if (bytes_left > 0) 00342 { 00343 prev_read_info[current_prev_read_info].ptr = 00344 previous_read_ptr; 00345 if (NULL == prev_read_info[current_prev_read_info].buf 00346 || NULL == prev_read_info[current_prev_read_info].ptr) 00347 { 00348 rcs_print_error 00349 ("Invalid prev_read_info. buf =%p, ptr=%p, fd = %d, buf_size=%d(0x%X)\n", 00350 prev_read_info[current_prev_read_info].buf, 00351 prev_read_info[current_prev_read_info].ptr, 00352 prev_read_info[current_prev_read_info].fd, 00353 prev_read_info[current_prev_read_info].buf_size, 00354 prev_read_info[current_prev_read_info].buf_size); 00355 prev_read_info[current_prev_read_info].ptr = NULL; 00356 prev_read_info[current_prev_read_info].buf = NULL; 00357 prev_read_info[current_prev_read_info].fd = 0; 00358 prev_read_info[current_prev_read_info].buf_size = 0; 00359 return -1; 00360 } 00361 else if ((unsigned long) previous_read_ptr > 00362 ((unsigned long) previous_read_buf) + 00363 prev_read_info[current_prev_read_info].buf_size) 00364 { 00365 rcs_print_error 00366 ("Invalid prev_read_info. buf =%p, ptr=%p, fd = %d, buf_size=%d(0x%X)\n", 00367 prev_read_info[current_prev_read_info].buf, 00368 prev_read_info[current_prev_read_info].ptr, 00369 prev_read_info[current_prev_read_info].fd, 00370 prev_read_info[current_prev_read_info].buf_size, 00371 prev_read_info[current_prev_read_info].buf_size); 00372 prev_read_info[current_prev_read_info].ptr = NULL; 00373 prev_read_info[current_prev_read_info].buf = NULL; 00374 prev_read_info[current_prev_read_info].fd = 0; 00375 prev_read_info[current_prev_read_info].buf_size = 0; 00376 return -1; 00377 } 00378 else if ((unsigned long) previous_read_ptr < 00379 ((unsigned long) previous_read_buf)) 00380 { 00381 rcs_print_error 00382 ("Invalid prev_read_info. buf =%p, ptr=%p, fd = %d, buf_size=%d(0x%X)\n", 00383 prev_read_info[current_prev_read_info].buf, 00384 prev_read_info[current_prev_read_info].ptr, 00385 prev_read_info[current_prev_read_info].fd, 00386 prev_read_info[current_prev_read_info].buf_size, 00387 prev_read_info[current_prev_read_info].buf_size); 00388 prev_read_info[current_prev_read_info].ptr = NULL; 00389 prev_read_info[current_prev_read_info].buf = NULL; 00390 prev_read_info[current_prev_read_info].fd = 0; 00391 prev_read_info[current_prev_read_info].buf_size = 0; 00392 return -1; 00393 } 00394 } 00395 else 00396 { 00397 prev_read_info[current_prev_read_info].ptr = NULL; 00398 prev_read_info[current_prev_read_info].fd = 0; 00399 previous_read_buf = NULL; 00400 if (prev_read_info[current_prev_read_info].buf != NULL) 00401 { 00402 DEBUG_FREE (prev_read_info[current_prev_read_info].buf); 00403 prev_read_info[current_prev_read_info].buf = NULL; 00404 } 00405 prev_read_info[current_prev_read_info].buf = NULL; 00406 prev_read_info[current_prev_read_info].buf_size = 0; 00407 } 00408 return bytes_read; 00409 } 00410 else 00411 { 00412 strcpy (cptr, previous_read_ptr); 00413 previous_read_ptr = previous_read_buf; 00414 bytes_read = strlen (cptr); 00415 prev_read_info[current_prev_read_info].ptr = NULL; 00416 prev_read_info[current_prev_read_info].fd = 0; 00417 previous_read_buf = NULL; 00418 if (prev_read_info[current_prev_read_info].buf != NULL) 00419 { 00420 DEBUG_FREE (prev_read_info[current_prev_read_info].buf); 00421 prev_read_info[current_prev_read_info].buf = NULL; 00422 } 00423 prev_read_info[current_prev_read_info].buf = NULL; 00424 prev_read_info[current_prev_read_info].buf_size = 0; 00425 if (current_prev_read_info > first_empty_slot) 00426 { 00427 current_prev_read_info = -1; 00428 } 00429 cptr += bytes_read; 00430 } 00431 } 00432 } 00433 00434 ptr = (char *) cptr; 00435 start_time = etime (); 00436 while (1) 00437 { 00438 if (fabs (_timeout) > 1E-6) 00439 { 00440 if (_timeout > 0) 00441 { 00442 select_ret = 00443 dl_select (fd + 1, &recv_fd_set, (fd_set *) NULL, 00444 (fd_set *) NULL, &timeout_tv); 00445 } 00446 else 00447 { 00448 select_ret = 00449 dl_select (fd + 1, &recv_fd_set, (fd_set *) NULL, 00450 (fd_set *) NULL, NULL); 00451 } 00452 switch (select_ret) 00453 { 00454 case -1: 00455 #if !defined(_Windows) || defined(gnuwin32) 00456 rcs_print_error ("Error in select: %d -> %s\n", errno, 00457 strerror (errno)); 00458 #else 00459 rcs_print_error ("Error in select: %d\n", 00460 dl_WSAGetLastError ()); 00461 #endif 00462 return -1; 00463 00464 case 0: 00465 rcs_print_error ("Recvline timed out.\n"); 00466 recvline_timedout = 1; 00467 return -1; 00468 00469 default: 00470 break; 00471 } 00472 } 00473 #if defined(WIN32) && !defined(gnuwin32) 00474 dl_ioctlsocket (fd, FIONREAD, &bytes_ready); 00475 #else 00476 #ifndef VXWORKS 00477 ioctl (fd, FIONREAD, (caddr_t) & bytes_ready); 00478 #else 00479 ioctl (fd, FIONREAD, (int) &bytes_ready); 00480 #endif 00481 #endif 00482 if (bytes_ready <= 0) 00483 { 00484 if (fabs (_timeout) < 1e-6) 00485 { 00486 recvline_timedout = 1; 00487 if (NULL != bytes_read_ptr) 00488 { 00489 *bytes_read_ptr = bytes_read; 00490 } 00491 return (-1); 00492 } 00493 else 00494 { 00495 rcs_print_error ("recvline: Premature EOF recieved.\n"); 00496 return (-1); 00497 } 00498 } 00499 if (bytes_read < 0) 00500 { 00501 bytes_read = 0; 00502 } 00503 if (bytes_ready > maxbytes - bytes_read) 00504 { 00505 bytes_ready = maxbytes - bytes_read; 00506 } 00507 if ((nrecv = dl_recv (fd, ptr, bytes_ready, flags)) == -1) 00508 { 00509 #if (!defined(_WINDOWS) && !defined(MSDOS)) || defined(gnuwin32) 00510 if (errno == EWOULDBLOCK) 00511 { 00512 if (fabs (_timeout) < 1e-6) 00513 { 00514 recvline_timedout = 1; 00515 if (NULL != bytes_read_ptr) 00516 { 00517 *bytes_read_ptr = bytes_read; 00518 } 00519 return (-1); 00520 } 00521 } 00522 else 00523 { 00524 rcs_print_error ("Recv error: %d = %s\n", errno, 00525 strerror (errno)); 00526 if (NULL != bytes_read_ptr) 00527 { 00528 *bytes_read_ptr = bytes_read; 00529 } 00530 return (-1); 00531 } 00532 #else 00533 #if defined(_Windows) 00534 error_value = dl_WSAGetLastError (); 00535 if (WSAEWOULDBLOCK != error_value) 00536 { 00537 rcs_print_error ("Recv error: %d\n", error_value); 00538 return (-1); /* error, return < 0 */ 00539 } 00540 else 00541 { 00542 if (fabs (_timeout) < 1e-6) 00543 { 00544 recvline_timedout = 1; 00545 return (-1); 00546 } 00547 } 00548 #else 00549 error_value = tk_geterrno (fd); 00550 if (EWOULDBLOCK != error_value) 00551 { 00552 rcs_print_error ("Recv error: %d\n", error_value); 00553 return (-1); /* error, return < 0 */ 00554 } 00555 else 00556 { 00557 if (fabs (_timeout) < 1e-6) 00558 { 00559 recvline_timedout = 1; 00560 return (-1); 00561 } 00562 } 00563 #endif 00564 #endif 00565 continue; 00566 } 00567 else if (nrecv == 0) 00568 { 00569 rcs_print_error ("recvline: Premature EOF recieved.\n"); 00570 return (-1); 00571 } 00572 nptr = strchr (ptr, '\n'); 00573 if (NULL != nptr) 00574 { 00575 *nptr = 0; 00576 bytes_read += strlen (ptr); 00577 if (NULL != bytes_read_ptr) 00578 { 00579 *bytes_read_ptr = bytes_read; 00580 } 00581 nptr++; 00582 if (nrecv > ((int) (strlen (ptr) + 1))) 00583 { 00584 if (current_prev_read_info < 0) 00585 { 00586 current_prev_read_info = first_empty_slot; 00587 } 00588 00589 prev_read_info[current_prev_read_info].buf = NULL; 00590 prev_read_info[current_prev_read_info].ptr = NULL; 00591 prev_read_info[current_prev_read_info].fd = 0; 00592 prev_read_info[current_prev_read_info].buf_size = 0; 00593 prev_read_info[current_prev_read_info].buf = 00594 DEBUG_MALLOC (nrecv - strlen (ptr)); 00595 prev_read_info[current_prev_read_info].buf_size = 00596 nrecv - strlen (ptr); 00597 prev_read_info[current_prev_read_info].fd = fd; 00598 previous_read_buf = prev_read_info[current_prev_read_info].buf; 00599 memcpy (previous_read_buf, nptr, nrecv - (strlen (ptr) + 1)); 00600 *(((char *) previous_read_buf) + 00601 prev_read_info[current_prev_read_info].buf_size - 1) = 0; 00602 previous_read_ptr = previous_read_buf; 00603 prev_read_info[current_prev_read_info].ptr = previous_read_ptr; 00604 if (prev_read_infos < current_prev_read_info + 1) 00605 { 00606 prev_read_infos = current_prev_read_info + 1; 00607 } 00608 } 00609 return bytes_read; 00610 } 00611 ptr += nrecv; 00612 bytes_read += nrecv; 00613 if (bytes_read > maxbytes) 00614 { 00615 rcs_print_error ("recvline: Buffer size of %d exceeded.\n", 00616 maxbytes); 00617 return (-1); 00618 } 00619 if (_timeout > 0.0) 00620 { 00621 esleep (0.001); 00622 current_time = etime (); 00623 if (current_time - start_time > _timeout) 00624 { 00625 rcs_print_error 00626 ("recvline: timed out after %lf seconds between %lf and %lf\n", 00627 current_time - start_time, start_time, current_time); 00628 recvline_timedout = 1; 00629 if (NULL != bytes_read_ptr) 00630 { 00631 *bytes_read_ptr = bytes_read; 00632 } 00633 return (-1); 00634 } 00635 } 00636 } 00637 rcs_print_debug (PRINT_SOCKET_READ_SIZE, 00638 "recvline:(%d bytes from %d) %s \n", bytes_read, fd, cptr); 00639 00640 if (NULL != bytes_read_ptr) 00641 { 00642 *bytes_read_ptr = bytes_read; 00643 } 00644 return (bytes_read); /* return >= 0 */ 00645 } |
|
Definition at line 46 of file recvline.c. |
|
Definition at line 57 of file recvline.c. |
|
Definition at line 58 of file recvline.c. |
|
Definition at line 59 of file recvline.c. |