CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Utilities/StorageFactory/src/UnixIOChannel.cc

Go to the documentation of this file.
00001 #include "Utilities/StorageFactory/interface/IOChannel.h"
00002 #include "Utilities/StorageFactory/src/SysIOChannel.h"
00003 #include "Utilities/StorageFactory/src/Throw.h"
00004 #include <algorithm>
00005 #include <vector>
00006 #include <cassert>
00007 
00008 IOSize
00009 IOChannel::read (void *into, IOSize n)
00010 {
00011   ssize_t s;
00012   do
00013     s = ::read (fd (), into, n);
00014   while (s == -1 && errno == EINTR);
00015 
00016   if (s == -1)
00017     throwStorageError ("IOChannel::read()", "read()", errno);
00018 
00019   return s;
00020 }
00021 
00022 IOSize
00023 IOChannel::readv (IOBuffer *into, IOSize buffers)
00024 {
00025   assert (! buffers || into);
00026 
00027   // readv may not support zero buffers.
00028   if (! buffers)
00029     return 0;
00030 
00031   ssize_t n = 0;
00032 
00033   // Convert the buffers to system format.
00034   std::vector<iovec> bufs (buffers);
00035   for (IOSize i = 0; i < buffers; ++i)
00036   {
00037     bufs [i].iov_len  = into [i].size ();
00038     bufs [i].iov_base = (caddr_t) into [i].data ();
00039   }
00040 
00041   // Read as long as signals cancel the read before doing anything.
00042   do
00043     n = ::readv (fd (), &bufs [0], buffers);
00044   while (n == -1 && errno == EINTR);
00045 
00046   // If it was serious error, throw it.
00047   if (n == -1)
00048     throwStorageError ("IOChannel::readv", "readv()", errno);
00049 
00050   // Return the number of bytes actually read.
00051   return n;
00052 }
00053 
00057 IOSize
00058 IOChannel::write (const void *from, IOSize n)
00059 {
00060   ssize_t s;
00061   do
00062     s = ::write (fd (), from, n);
00063   while (s == -1 && errno == EINTR);
00064 
00065   if (s == -1 && errno != EWOULDBLOCK)
00066     throwStorageError ("IOChannel::write()", "write()", errno);
00067 
00068   return s >= 0 ? s : 0;
00069 }
00070 
00071 IOSize
00072 IOChannel::writev (const IOBuffer *from, IOSize buffers)
00073 {
00074   assert (! buffers || from);
00075 
00076   // writev may not support zero buffers.
00077   if (! buffers)
00078     return 0;
00079 
00080   ssize_t n = 0;
00081 
00082   // Convert the buffers to system format.
00083   std::vector<iovec> bufs (buffers);
00084   for (IOSize i = 0; i < buffers; ++i)
00085   {
00086     bufs [i].iov_len  = from [i].size ();
00087     bufs [i].iov_base = (caddr_t) from [i].data ();
00088   }
00089 
00090   // Read as long as signals cancel the read before doing anything.
00091   do
00092     n = ::writev (fd (), &bufs [0], buffers);
00093   while (n == -1 && errno == EINTR);
00094 
00095   // If it was serious error, throw it.
00096   if (n == -1)
00097     throwStorageError ("IOChannel::writev()", "writev()", errno);
00098 
00099   // Return the number of bytes actually written.
00100   return n;
00101 }
00102 
00106 void
00107 IOChannel::setBlocking (bool value)
00108 {
00109 #ifdef O_NONBLOCK
00110   int mode;
00111   int off = value ? ~0 : ~(O_NDELAY | O_NONBLOCK);
00112   int on  = value ? O_NONBLOCK : 0;
00113 
00114   if ((mode = fcntl (fd (), F_GETFL, 0)) == -1
00115       || fcntl (fd (), F_SETFL, (mode & off) | on) == -1)
00116     throwStorageError ("IOChannel::setBlocking()", "fcntl()", errno);
00117 #elif defined FIONBIO
00118   int mode = value;
00119   if (ioctl (fd (), FIONBIO, &value) == -1)
00120     throwStorageError ("IOChannel::setBlocking()", "ioctl()", errno);
00121 #endif
00122 }
00123 
00124 bool
00125 IOChannel::isBlocking (void) const
00126 {
00127 #ifdef O_NONBLOCK
00128   int mode;
00129   if ((mode = fcntl (fd (), F_GETFL, 0)) == -1)
00130     throwStorageError ("IOChannel::isBlocking()", "fcntl()", errno);
00131 
00132   return mode & (O_NDELAY | O_NONBLOCK);
00133 #else // ! O_NONBLOCK
00134   return true;
00135 #endif // O_NONBLOCK
00136 }
00137 
00141 bool
00142 IOChannel::sysclose (IOFD fd, int *error /* = 0 */)
00143 {
00144   int ret = ::close (fd);
00145   if (error) *error = errno;
00146   return ret != -1;
00147 }