CMS 3D CMS Logo

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