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

sendmsgt.c

Go to the documentation of this file.
00001 
00002 
00003 
00004 /* This is neccessary to avoid muliple definitions of fd_set, etc when both
00005 * RPC via PCNFS and Windows Sockets are to be available. */
00006 #ifdef USE_PCNFS
00007 #undef USE_PCNFS
00008 #endif
00009 
00010 
00011 #include "rcs_defs.hh"          /* MSDOS, _Windows */
00012 #include "dbg_mem.h"            // DEBUG_MALLOC, DEBUG_FREE
00013 
00014 
00015 #include "sendmsgt.h"           /* Forward Prototype */
00016 
00017 #ifndef UNDER_CE
00018 #include <sys/types.h>          /* u_char etc needed by sys/socket.h */
00019                                 /* fd_set, FD_ZERO, FD_SET */
00020 #else
00021 #include <windows.h>            /* WORD */
00022 #endif
00023 
00024 #if !defined(DOS_WINDOWS) || defined(gnuwin32)
00025 #include <sys/socket.h>         /* stuct msghdr, sendmsg() */
00026 #ifndef VXWORKS
00027 #include <sys/time.h>           /* struct timeval */
00028 #else
00029 #include <sys/times.h>          /* struct timeval */
00030 #include <sockLib.h>            /* sendmsg() */
00031 #endif
00032 #ifndef _Windows
00033 #include <unistd.h>             /* select() */
00034 #endif
00035 #else
00036 #if defined(MSDOS) && !defined(WINDOWS)
00037 #include <tklib.h>
00038 #include <sys/socket.h>         /* stuct msghdr, sendmsg() */
00039 #include <sys/uio.h>            /* stuct iovec */
00040 #else
00041 #ifdef USE_OLD_WINSOCK
00042 #include <winsock.h>            /* select(), typedef fd_set, FD_ZERO, FD_SET, struct */
00043 #else
00044 #include <winsock2.h>
00045 #endif
00046 
00047 #endif
00048 #endif
00049 #ifndef irix6
00050 #include <math.h>               /* fmod() */
00051 #else
00052 /*
00053  Work around for the conflict between the gcc includes and /usr/includes
00054  on some of our SGI's regarding the definition of initstate()
00055 */
00056 extern double fmod (double, double);
00057 #endif
00058 
00059 #ifndef UNDER_CE
00060 #include <errno.h>              /* errno variable */
00061 #endif
00062 #include <string.h>             /* strerror() */
00063 #include <stdlib.h>             /* DEBUG_MALLOC(), free() */
00064 #include "rcs_prnt.hh"          /* rcs_print_error() */
00065 #include "sokintrf.h"           /* dl_sendto(), dl_select(), dl_WSAGetLastError() */
00066 
00067 static long total_bytes_sent = 0;
00068 
00069 #define USE_SENDTO
00070 #if defined(_Windows) && !defined(USE_PCNFS)
00071 #ifndef USE_SENDTO
00072 #define USE_SENDTO
00073 #endif
00074 #endif
00075 
00076 
00077 
00078 #ifdef USE_SENDTO
00079 static char RCS_FAR *collection_buffer = NULL;
00080 static long collection_buffer_size = 0;
00081 #endif
00082 
00083 int sendmsgt_timed_out = 0;
00084 
00085 int
00086 sendmsgt (int _socket_fd, struct msghdr *_msg_header, int _flags,
00087           double _timeout)
00088 {
00089   struct timeval timeout_timeval;
00090   fd_set write_fd_set;
00091   int bytes_sent, i;
00092   long required_size = 0;
00093   char *temp_pointer;
00094   sendmsgt_timed_out = 0;
00095 
00096 #ifdef USE_SENDTO
00097   if (_msg_header->msg_iovlen > 1)
00098     {
00099       for (i = 0, required_size = 0; i < _msg_header->msg_iovlen; i++)
00100         {
00101           required_size += _msg_header->msg_iov[i].iov_len;
00102         }
00103       if (required_size > collection_buffer_size)
00104         {
00105           if (NULL != collection_buffer)
00106             {
00107               DEBUG_FREE (collection_buffer);
00108               collection_buffer = NULL;
00109             }
00110           collection_buffer = (char *) DEBUG_MALLOC (required_size);
00111           collection_buffer_size = required_size;
00112         }
00113       if (NULL == collection_buffer)
00114         {
00115           collection_buffer_size = 0;
00116           rcs_print_error ("Couldn't malloc collection buffer of size %ld.\n",
00117                            required_size);
00118           return (-1);
00119         }
00120       for (i = 0, temp_pointer = collection_buffer;
00121            i < _msg_header->msg_iovlen; i++)
00122         {
00123           memcpy (temp_pointer, _msg_header->msg_iov[i].iov_base,
00124                   _msg_header->msg_iov[i].iov_len);
00125           temp_pointer += _msg_header->msg_iov[i].iov_len;
00126         }
00127     }
00128 #endif
00129 
00130   if (_timeout > 1E-6)
00131     {
00132       timeout_timeval.tv_sec = (long) _timeout;
00133       timeout_timeval.tv_usec = (long) (_timeout * 1000000.0);
00134       if (timeout_timeval.tv_usec >= 1000000)
00135         {
00136           timeout_timeval.tv_usec = timeout_timeval.tv_usec % 1000000;
00137         }
00138       FD_ZERO (&write_fd_set);
00139       RCS_FD_SET (_socket_fd, &write_fd_set);
00140       switch (dl_select
00141               (_socket_fd + 1, NULL, &write_fd_set, NULL, &timeout_timeval))
00142         {
00143         case -1:
00144 #ifndef UNDER_CE
00145           rcs_print_error ("sendmsgt: select error: %d %s\n",
00146                            errno, strerror (errno));
00147 #endif
00148           return -1;
00149 
00150         case 0:
00151           sendmsgt_timed_out = 1;
00152           rcs_print_error ("sendmgt: select timed out.\n");
00153           return (0);
00154 
00155         default:
00156           break;
00157         }
00158     }
00159   else if (_timeout > -1E-6)
00160     {
00161       timeout_timeval.tv_sec = 0L;
00162       timeout_timeval.tv_usec = 0L;
00163       FD_ZERO (&write_fd_set);
00164       RCS_FD_SET (_socket_fd, &write_fd_set);
00165       switch (dl_select
00166               (_socket_fd + 1, NULL, &write_fd_set, NULL, &timeout_timeval))
00167         {
00168         case -1:
00169 #ifndef UNDER_CE
00170           rcs_print_error ("sendmsgt: select error: %d %s\n",
00171                            errno, strerror (errno));
00172 #endif
00173           return -1;
00174 
00175         case 0:
00176           sendmsgt_timed_out = 1;
00177           return (0);
00178 
00179         default:
00180           break;
00181         }
00182     }
00183 #ifdef USE_SENDTO
00184   if (_msg_header->msg_iovlen > 1)
00185     {
00186       bytes_sent =
00187         dl_sendto (_socket_fd, collection_buffer, required_size, _flags,
00188                    (struct sockaddr *) _msg_header->msg_name,
00189                    _msg_header->msg_namelen);
00190     }
00191   else
00192     {
00193       bytes_sent = dl_sendto (_socket_fd, _msg_header->msg_iov[0].iov_base,
00194                               _msg_header->msg_iov[0].iov_len, _flags,
00195                               (struct sockaddr *) _msg_header->msg_name,
00196                               _msg_header->msg_namelen);
00197     }
00198 #if defined(_Windows) && !defined(gnuwin32)
00199   if (bytes_sent == SOCKET_ERROR)
00200     {
00201       rcs_print_error ("sendmsgt: send_to error %d\n", dl_WSAGetLastError ());
00202       return (-1);
00203     }
00204 #else
00205   if (bytes_sent < 0)
00206     {
00207       rcs_print_error ("sendto(%d,%p,%d,0x%X,%s,%d) failed: %d -- %s \n",
00208                        _socket_fd, _msg_header->msg_iov[0].iov_base,
00209                        _msg_header->msg_iov[0].iov_len, _flags,
00210                        dl_inet_ntoa (
00211                                      ((struct sockaddr_in *)
00212                                       _msg_header->msg_name)->sin_addr),
00213                        _msg_header->msg_namelen,
00214 #ifndef UNDER_CE
00215                        errno, strerror (errno));
00216 #else
00217                        0, "?");
00218 #endif
00219     }
00220 #endif
00221 #else
00222   bytes_sent = sendmsg (_socket_fd, _msg_header, _flags);
00223   if (bytes_sent < 0)
00224     {
00225       rcs_print_error ("sendmsg(%d,%p,%d) error: %d = %s\n",
00226                        _socket_fd, _msg_header, _flags,
00227 #ifndef UNDER_CE
00228                        errno, strerror (errno));
00229 #else
00230                        0, "?");
00231 #endif
00232       rcs_print_error (" _msg_header->msg_iovlen = %d\n",
00233                        _msg_header->msg_iovlen);
00234       rcs_print_error ("_msg_header->msg_iov[0].iov_len = %d\n",
00235                        _msg_header->msg_iov[0].iov_len);
00236     }
00237 #endif
00238   total_bytes_sent += bytes_sent;
00239   rcs_print_debug (PRINT_SOCKET_WRITE_SIZE, "sendmsg %d bytes to %d\n",
00240                    bytes_sent, _socket_fd);
00241   return (bytes_sent);
00242 }
00243 
00244 
00245 void
00246 free_sendmsg_collection_buffer ()
00247 {
00248 #if defined(_Windows) && !defined(USE_PCNFS)
00249   if (NULL != collection_buffer)
00250     {
00251       DEBUG_FREE (collection_buffer);
00252       collection_buffer = NULL;
00253       collection_buffer_size = 0;
00254     }
00255 #endif
00256 }

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