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

recvmsgt.c

Go to the documentation of this file.
00001 
00002 /* This is neccessary to avoid muliple definitions of fd_set, etc when both
00003 * RPC via PCNFS and Windows Sockets are to be available. */
00004 #ifdef USE_PCNFS
00005 #undef USE_PCNFS
00006 #endif
00007 
00008 
00009 #include "rcs_defs.hh"          /* MSDOS, _Windows */
00010 
00011 #include "recvmsgt.h"           /* Forward Prototype */
00012 #include "_timer.h"             /* etime(), etime_disabled */
00013 
00014 #if  !defined(_Windows) || defined(USE_PCNFS) || defined(gnuwin32)
00015 #ifdef MSDOS
00016 #include <tklib.h>
00017 #else
00018 #include <sys/types.h>          /* u_char etc needed by sys/socket.h */
00019                                 /* fd_set, FD_ZERO, FD_SET */
00020 #include <sys/socket.h>         /* stuct msghdr, sendmsg() */
00021 #ifndef VXWORKS
00022 #include <sys/time.h>           /* struct timeval */
00023 #else
00024 #include <sys/times.h>          /* struct timeval */
00025 #include <sockLib.h>            /* recvmsg() */
00026 #endif
00027 #ifndef _Windows
00028 #include <unistd.h>             /* select() */
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>            /* select(), typedef fd_set, FD_ZERO, FD_SET, struct */
00037 #else
00038 #include <winsock2.h>
00039 #endif
00040 
00041 #endif
00042 #ifndef irix6
00043 #include <math.h>               /* fmod() */
00044 #else
00045 /*
00046  Work around for the conflict between the gcc includes and /usr/includes
00047  on some of our SGI's regarding the definition of initstate()
00048  */
00049 extern double fmod (double, double);
00050 #endif
00051 
00052 #ifndef UNDER_CE
00053 #include <errno.h>              /* errno variable */
00054 #endif
00055 #include <string.h>             /* strerror() */
00056 #include <stdlib.h>             /* malloc(), free() */
00057 #include "rcs_prnt.hh"          /* rcs_print_error() */
00058 #include "sokintrf.h"           /* dl_recvfrom(), dl_select() */
00059 #include "dbg_mem.h"            /* DEBUG_FREE,DEBUG_MALLOC,DEBUG_CALLOC */
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 }

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