00001 #include "Utilities/DCacheAdaptor/interface/DCacheFile.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include <unistd.h>
00005 #include <fcntl.h>
00006 #include <dcap.h>
00007
00008 DCacheFile::DCacheFile (void)
00009 : m_fd (EDM_IOFD_INVALID),
00010 m_close (false)
00011 {}
00012
00013 DCacheFile::DCacheFile (IOFD fd)
00014 : m_fd (fd),
00015 m_close (true)
00016 {}
00017
00018 DCacheFile::DCacheFile (const char *name,
00019 int flags ,
00020 int perms )
00021 : m_fd (EDM_IOFD_INVALID),
00022 m_close (false)
00023 { open (name, flags, perms); }
00024
00025 DCacheFile::DCacheFile (const std::string &name,
00026 int flags ,
00027 int perms )
00028 : m_fd (EDM_IOFD_INVALID),
00029 m_close (false)
00030 { open (name.c_str (), flags, perms); }
00031
00032 DCacheFile::~DCacheFile (void)
00033 {
00034 if (m_close)
00035 edm::LogError("DCacheFileError")
00036 << "Destructor called on dCache file '" << m_name
00037 << "' but the file is still open";
00038 }
00039
00041 void
00042 DCacheFile::create (const char *name,
00043 bool exclusive ,
00044 int perms )
00045 {
00046 open (name,
00047 (IOFlags::OpenCreate | IOFlags::OpenWrite | IOFlags::OpenTruncate
00048 | (exclusive ? IOFlags::OpenExclusive : 0)),
00049 perms);
00050 }
00051
00052 void
00053 DCacheFile::create (const std::string &name,
00054 bool exclusive ,
00055 int perms )
00056 {
00057 open (name.c_str (),
00058 (IOFlags::OpenCreate | IOFlags::OpenWrite | IOFlags::OpenTruncate
00059 | (exclusive ? IOFlags::OpenExclusive : 0)),
00060 perms);
00061 }
00062
00063 void
00064 DCacheFile::open (const std::string &name,
00065 int flags ,
00066 int perms )
00067 { open (name.c_str (), flags, perms); }
00068
00069 void
00070 DCacheFile::open (const char *name,
00071 int flags ,
00072 int perms )
00073 {
00074 m_name = name;
00075
00076
00077 if ((name == 0) || (*name == 0))
00078 throw cms::Exception("DCacheFile::open()")
00079 << "Cannot open a file without a name";
00080
00081 if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0)
00082 throw cms::Exception("DCacheFile::open()")
00083 << "Must open file '" << name << "' at least for read or write";
00084
00085
00086 if (m_fd != EDM_IOFD_INVALID && m_close)
00087 close ();
00088
00089
00090 int openflags = 0;
00091
00092 if ((flags & IOFlags::OpenRead) && (flags & IOFlags::OpenWrite))
00093 openflags |= O_RDWR;
00094 else if (flags & IOFlags::OpenRead)
00095 openflags |= O_RDONLY;
00096 else if (flags & IOFlags::OpenWrite)
00097 openflags |= O_WRONLY;
00098
00099 if (flags & IOFlags::OpenNonBlock)
00100 openflags |= O_NONBLOCK;
00101
00102 if (flags & IOFlags::OpenAppend)
00103 openflags |= O_APPEND;
00104
00105 if (flags & IOFlags::OpenCreate)
00106 openflags |= O_CREAT;
00107
00108 if (flags & IOFlags::OpenExclusive)
00109 openflags |= O_EXCL;
00110
00111 if (flags & IOFlags::OpenTruncate)
00112 openflags |= O_TRUNC;
00113
00114 IOFD newfd = EDM_IOFD_INVALID;
00115 dc_errno = 0;
00116 if ((newfd = dc_open (name, openflags, perms)) == -1)
00117 throw cms::Exception("DCacheFile::open()")
00118 << "dc_open(name='" << name
00119 << "', flags=0x" << std::hex << openflags
00120 << ", permissions=0" << std::oct << perms << std::dec
00121 << ") => error '" << dc_strerror(dc_errno)
00122 << "' (dc_errno=" << dc_errno << ")";
00123
00124 m_fd = newfd;
00125
00126
00127
00128
00129
00130
00131
00132 if (flags & IOFlags::OpenUnbuffered)
00133 dc_noBuffering(m_fd);
00134 else
00135 dc_setBufferSize(m_fd, 64000);
00136
00137 m_close = true;
00138
00139 edm::LogInfo("DCacheFileInfo") << "Opened " << m_name;
00140 }
00141
00142 void
00143 DCacheFile::close (void)
00144 {
00145 if (m_fd == EDM_IOFD_INVALID)
00146 {
00147 edm::LogError("DCacheFileError")
00148 << "DCacheFile::close(name='" << m_name
00149 << "') called but the file is not open";
00150 m_close = false;
00151 return;
00152 }
00153
00154 dc_errno = 0;
00155 if (dc_close (m_fd) == -1)
00156 edm::LogWarning("DCacheFileWarning")
00157 << "dc_close(name='" << m_name
00158 << "') failed with error '" << dc_strerror (dc_errno)
00159 << "' (dc_errno=" << dc_errno << ")";
00160
00161 m_close = false;
00162 m_fd = EDM_IOFD_INVALID;
00163
00164
00165
00166 }
00167
00168 void
00169 DCacheFile::abort (void)
00170 {
00171 if (m_fd != EDM_IOFD_INVALID)
00172 dc_close (m_fd);
00173
00174 m_close = false;
00175 m_fd = EDM_IOFD_INVALID;
00176 }
00177
00179 static const int BUGLINE = __LINE__ + 1;
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 IOSize
00195 DCacheFile::read (void *into, IOSize n)
00196 {
00197 IOSize done = 0;
00198 while (done < n)
00199 {
00200 dc_errno = 0;
00201 ssize_t s = dc_read (m_fd, (char *) into + done, n - done);
00202 if (s == -1)
00203 throw cms::Exception("DCacheFile::read()")
00204 << "dc_read(name='" << m_name << "', n=" << (n-done)
00205 << ") failed with error '" << dc_strerror(dc_errno)
00206 << "' (dc_errno=" << dc_errno << ")";
00207 else if (s == 0)
00208
00209 break;
00210 else if (s < ssize_t (n-done))
00211 edm::LogInfo("DCacheFileWarning")
00212 << "dc_read(name='" << m_name << "', n=" << (n-done)
00213 << ") returned a short read of " << s << " bytes; "
00214 << "please report a bug in dCache referencing the "
00215 << "comment on line " << BUGLINE << " of " << __FILE__;
00216 done += s;
00217 }
00218
00219 return done;
00220 }
00221
00222 IOSize
00223 DCacheFile::write (const void *from, IOSize n)
00224 {
00225 IOSize done = 0;
00226 while (done < n)
00227 {
00228 dc_errno = 0;
00229 ssize_t s = dc_write (m_fd, (const char *) from + done, n - done);
00230 if (s == -1)
00231 throw cms::Exception("DCacheFile::write()")
00232 << "dc_write(name='" << m_name << "', n=" << (n-done)
00233 << ") failed with error '" << dc_strerror(dc_errno)
00234 << "' (dc_errno=" << dc_errno << ")";
00235 else if (s < ssize_t (n-done))
00236 edm::LogInfo("DCacheFileWarning")
00237 << "dc_write(name='" << m_name << "', n=" << (n-done)
00238 << ") returned a short write of " << s << " bytes; "
00239 << "please report a bug in dCache referencing the "
00240 << "comment on line " << BUGLINE << " of " << __FILE__;
00241 done += s;
00242 }
00243
00244 return done;
00245 }
00246
00250 IOOffset
00251 DCacheFile::position (IOOffset offset, Relative whence )
00252 {
00253 if (m_fd == EDM_IOFD_INVALID)
00254 throw cms::Exception("DCacheFile::position()")
00255 << "DCacheFile::position() called on a closed file";
00256 if (whence != CURRENT && whence != SET && whence != END)
00257 throw cms::Exception("DCacheFile::position()")
00258 << "DCacheFile::position() called with incorrect 'whence' parameter";
00259
00260 IOOffset result;
00261 int mywhence = (whence == SET ? SEEK_SET
00262 : whence == CURRENT ? SEEK_CUR
00263 : SEEK_END);
00264
00265 dc_errno = 0;
00266 if ((result = dc_lseek64 (m_fd, offset, mywhence)) == -1)
00267 throw cms::Exception("DCacheFile::position()")
00268 << "dc_lseek64(name='" << m_name << "', offset=" << offset
00269 << ", whence=" << mywhence << ") failed with error '"
00270 << dc_strerror (dc_errno) << "' (dc_errno=" << dc_errno << ")";
00271
00272
00273
00274 if (whence == SEEK_END && (result = dc_lseek64 (m_fd, result, SEEK_SET)) == -1)
00275 throw cms::Exception("DCacheFile::position()")
00276 << "dc_lseek64(name='" << m_name << "', offset=" << offset
00277 << ", whence=" << SEEK_SET << ") failed with error '"
00278 << dc_strerror (dc_errno) << "' (dc_errno=" << dc_errno << ")";
00279
00280 return result;
00281 }
00282
00283 void
00284 DCacheFile::resize (IOOffset )
00285 {
00286 throw cms::Exception("DCacheFile::resize()")
00287 << "DCacheFile::resize(name='" << m_name << "') not implemented";
00288 }