SOCK_IO.cpp

Go to the documentation of this file.
00001 // SOCK_IO.cpp,v 4.35 2006/02/26 19:21:00 jwillemsen Exp
00002 
00003 #include "ace/SOCK_IO.h"
00004 
00005 #include "ace/Handle_Set.h"
00006 #include "ace/OS_NS_sys_select.h"
00007 #include "ace/OS_NS_sys_socket.h"
00008 #include "ace/OS_Memory.h"
00009 #include "ace/Truncate.h"
00010 
00011 #if !defined (__ACE_INLINE__)
00012 #include "ace/SOCK_IO.inl"
00013 #endif /* __ACE_INLINE__ */
00014 
00015 ACE_RCSID(ace, SOCK_IO, "SOCK_IO.cpp,v 4.35 2006/02/26 19:21:00 jwillemsen Exp")
00016 
00017 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_IO)
00020 
00021 void
00022 ACE_SOCK_IO::dump (void) const
00023 {
00024 #if defined (ACE_HAS_DUMP)
00025   ACE_TRACE ("ACE_SOCK_IO::dump");
00026 #endif /* ACE_HAS_DUMP */
00027 }
00028 
00029 // Allows a client to read from a socket without having to provide
00030 // a buffer to read.  This method determines how much data is in the
00031 // socket, allocates a buffer of this size, reads in the data, and
00032 // returns the number of bytes read.
00033 
00034 ssize_t
00035 ACE_SOCK_IO::recvv (iovec *io_vec,
00036                     const ACE_Time_Value *timeout) const
00037 {
00038   ACE_TRACE ("ACE_SOCK_IO::recvv");
00039 #if defined (FIONREAD)
00040   ACE_Handle_Set handle_set;
00041   handle_set.reset ();
00042   handle_set.set_bit (this->get_handle ());
00043 
00044   io_vec->iov_base = 0;
00045 
00046   // Check the status of the current socket.
00047   int select_width;
00048 #  if defined (ACE_WIN32)
00049   // This arg is ignored on Windows and causes pointer truncation
00050   // warnings on 64-bit compiles.
00051   select_width = 0;
00052 #  else
00053   select_width = int (this->get_handle ()) + 1;
00054 #  endif /* ACE_WIN32 */
00055   switch (ACE_OS::select (select_width,
00056                           handle_set,
00057                           0, 0,
00058                           timeout))
00059     {
00060     case -1:
00061       return -1;
00062       /* NOTREACHED */
00063     case 0:
00064       errno = ETIME;
00065       return -1;
00066       /* NOTREACHED */
00067     default:
00068       // Goes fine, fallthrough to get data
00069       break;
00070     }
00071 
00072   int inlen = 0;
00073 
00074   if (ACE_OS::ioctl (this->get_handle (),
00075                      FIONREAD,
00076                      &inlen) == -1)
00077     return -1;
00078   else if (inlen > 0)
00079     {
00080       ACE_NEW_RETURN (io_vec->iov_base,
00081                       char[inlen],
00082                       -1);
00083       // It's ok to blindly cast this value since 'inlen' is an int and, thus,
00084       // we can't get more than that back. Besides, if the recv() fails, we
00085       // don't want that value cast to unsigned and returned.
00086       ssize_t recv_len = this->recv (io_vec->iov_base, inlen);
00087       if (recv_len > 0)
00088         // u_long is the Windows type; size_t is everyone else's. A u_long
00089         // should go into a size_t anywhere without an issue.
00090         io_vec->iov_len = static_cast<u_long> (recv_len);
00091       return recv_len;
00092     }
00093   else
00094     return 0;
00095 #else
00096   ACE_UNUSED_ARG (io_vec);
00097   ACE_UNUSED_ARG (timeout);
00098   ACE_NOTSUP_RETURN (-1);
00099 #endif /* FIONREAD */
00100 }
00101 
00102 // Send N char *ptrs and int lengths.  Note that the char *'s precede
00103 // the ints (basically, an varargs version of writev).  The count N is
00104 // the *total* number of trailing arguments, *not* a couple of the
00105 // number of tuple pairs!
00106 
00107 ssize_t
00108 ACE_SOCK_IO::send (size_t n, ...) const
00109 {
00110   ACE_TRACE ("ACE_SOCK_IO::send");
00111 
00112   va_list argp;
00113   int total_tuples = ACE_Utils::Truncate<size_t> (n / 2);
00114   iovec *iovp = 0;
00115 #if defined (ACE_HAS_ALLOCA)
00116   iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
00117 #else
00118   ACE_NEW_RETURN (iovp,
00119                   iovec[total_tuples],
00120                   -1);
00121 #endif /* !defined (ACE_HAS_ALLOCA) */
00122 
00123   va_start (argp, n);
00124 
00125   for (int i = 0; i < total_tuples; i++)
00126     {
00127       iovp[i].iov_base = va_arg (argp, char *);
00128       iovp[i].iov_len = va_arg (argp, int);
00129     }
00130 
00131   ssize_t result = ACE_OS::sendv (this->get_handle (),
00132                                   iovp,
00133                                   total_tuples);
00134 #if !defined (ACE_HAS_ALLOCA)
00135   delete [] iovp;
00136 #endif /* !defined (ACE_HAS_ALLOCA) */
00137   va_end (argp);
00138   return result;
00139 }
00140 
00141 // This is basically an interface to ACE_OS::readv, that doesn't use
00142 // the struct iovec_Base explicitly.  The ... can be passed as an arbitrary
00143 // number of (char *ptr, int len) tuples.  However, the count N is the
00144 // *total* number of trailing arguments, *not* a couple of the number
00145 // of tuple pairs!
00146 
00147 ssize_t
00148 ACE_SOCK_IO::recv (size_t n, ...) const
00149 {
00150   ACE_TRACE ("ACE_SOCK_IO::recv");
00151 
00152   va_list argp;
00153   int total_tuples = ACE_Utils::Truncate<size_t> (n / 2);
00154   iovec *iovp;
00155 #if defined (ACE_HAS_ALLOCA)
00156   iovp = (iovec *) alloca (total_tuples * sizeof (iovec));
00157 #else
00158   ACE_NEW_RETURN (iovp,
00159                   iovec[total_tuples],
00160                   -1);
00161 #endif /* !defined (ACE_HAS_ALLOCA) */
00162 
00163   va_start (argp, n);
00164 
00165   for (int i = 0; i < total_tuples; i++)
00166     {
00167       iovp[i].iov_base = va_arg (argp, char *);
00168       iovp[i].iov_len = va_arg (argp, int);
00169     }
00170 
00171   ssize_t result = ACE_OS::recvv (this->get_handle (),
00172                                   iovp,
00173                                   total_tuples);
00174 #if !defined (ACE_HAS_ALLOCA)
00175   delete [] iovp;
00176 #endif /* !defined (ACE_HAS_ALLOCA) */
00177   va_end (argp);
00178   return result;
00179 }
00180 
00181 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:42:04 2006 for ACE by doxygen 1.3.6