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