Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

stcpsvr.cc File Reference

#include "rcs_defs.hh"
#include "sokintrf.h"
#include "timer.hh"
#include "dbg_mem.h"
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "cms.hh"
#include "stcpsvr.hh"
#include "rcs_prnt.hh"
#include "linklist.hh"
#include "stcpopts.hh"
#include "recvline.h"
#include "sendline.h"

Include dependency graph for stcpsvr.cc:

Include dependency graph

Go to the source code of this file.

Functions

int recvline (int fd, char *cptr, int max, int flags, double timeout, int *bytes_read)
void clean_prev_read_info (int fd)
int get_bytes_already_read (int fd)
int sendline (int fd, const char *cptr, int flags, double timeout)

Variables

int recvline_timedout


Function Documentation

int recvline int    fd,
char *    cptr,
int    max,
int    flags,
double    timeout,
int *    bytes_read
 

Definition at line 172 of file recvline.c.

Referenced by STCPMEM::check_if_read(), STCPMEM::login(), STCPMEM::peek(), STCPMEM::read(), and STCPMEM::write_if_read().

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 }

void clean_prev_read_info int    fd
 

Definition at line 88 of file recvline.c.

Referenced by CMS_SERVER_REMOTE_STCP_PORT::CMS_SERVER_REMOTE_STCP_PORT(), and STCPMEM::~STCPMEM().

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 }

int get_bytes_already_read int    fd
 

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 }

int sendline int    fd,
const char *    cptr,
int    flags,
double    timeout
 


Variable Documentation

int recvline_timedout
 

Definition at line 57 of file stcpsvr.cc.


Generated on Sun Dec 2 15:57:59 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001