00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_Types.hpp"
00038 #include "OW_TmpFile.hpp"
00039 #include "OW_IOException.hpp"
00040 #include "OW_MutexLock.hpp"
00041 #include "OW_String.hpp"
00042 #include "OW_Format.hpp"
00043 #include "OW_System.hpp"
00044 #include <cstring>
00045 #include <cstdlib>
00046 #include <cerrno>
00047 #include <cstdio>
00048 extern "C"
00049 {
00050 #include <sys/types.h>
00051 #include <sys/stat.h>
00052 #include <fcntl.h>
00053
00054 #if defined(OW_WIN32)
00055 #include <io.h>
00056 #endif
00057 }
00058
00059 namespace OW_NAMESPACE
00060 {
00061
00062 namespace {
00063
00064 #ifndef OW_WIN32
00065 inline int
00066 closeFile(int fd)
00067 {
00068 return ::close(fd);
00069 }
00070
00071 #else
00072 inline int
00073 closeFile(HANDLE fh)
00074 {
00075 return CloseHandle(fh) ? 0 : -1;
00076 }
00077 #endif
00078
00079 }
00080
00082 TmpFileImpl::TmpFileImpl()
00083 : m_filename(NULL)
00084 , m_hdl(OW_INVALID_FILEHANDLE)
00085 {
00086 open();
00087 }
00089 TmpFileImpl::TmpFileImpl(String const& filename)
00090 : m_filename(NULL)
00091 , m_hdl(OW_INVALID_FILEHANDLE)
00092 {
00093 size_t len = filename.length();
00094 m_filename = new char[len + 1];
00095 ::strncpy(m_filename, filename.c_str(), len);
00096 m_filename[len] = '\0';
00097 #if defined(OW_WIN32)
00098 m_hdl = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
00099 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
00100 FILE_ATTRIBUTE_NORMAL, NULL);
00101 #else
00102 m_hdl = ::open(m_filename, O_RDWR);
00103 #endif
00104 if (m_hdl == OW_INVALID_FILEHANDLE)
00105 {
00106 delete[] m_filename;
00107 m_filename = NULL;
00108 OW_THROW(IOException, Format("Error opening file %1: %2", filename,
00109 System::lastErrorMsg()).c_str());
00110 }
00111 }
00113 TmpFileImpl::~TmpFileImpl()
00114 {
00115 close();
00116 }
00117
00118 #ifdef OW_WIN32
00119
00120 int
00121 TmpFileImpl::seek(long offset, int whence)
00122 {
00123 DWORD moveMethod;
00124 switch(whence)
00125 {
00126 case SEEK_END: moveMethod = FILE_END; break;
00127 case SEEK_CUR: moveMethod = FILE_CURRENT; break;
00128 default: moveMethod = FILE_BEGIN; break;
00129 }
00130 return (int) SetFilePointer(m_hdl, (LONG)offset, NULL, moveMethod);
00131 }
00132
00134 long
00135 TmpFileImpl::tell()
00136 {
00137 return (long) SetFilePointer(m_hdl, 0L, NULL, FILE_CURRENT);
00138 }
00139
00141 void
00142 TmpFileImpl::rewind()
00143 {
00144 SetFilePointer(m_hdl, 0L, NULL, FILE_BEGIN);
00145 }
00146
00148 int
00149 TmpFileImpl::flush()
00150 {
00151 if(m_hdl != OW_INVALID_FILEHANDLE)
00152 {
00153 FlushFileBuffers(m_hdl);
00154 }
00155 return 0;
00156 }
00157 #endif
00158
00160 long
00161 TmpFileImpl::getSize()
00162 {
00163 #ifdef OW_WIN32
00164 return (long) GetFileSize(m_hdl, NULL);
00165 #else
00166 long cv = tell();
00167 seek(0L, SEEK_END);
00168 long rv = tell();
00169 seek(cv, SEEK_SET);
00170 return rv;
00171 #endif
00172 }
00174 #if defined(OW_WIN32)
00175 void
00176 TmpFileImpl::open()
00177 {
00178 close();
00179
00180 char bfr[MAX_PATH];
00181 if(!GetTempFileName(".", "owtempfile", 0, bfr))
00182 {
00183 OW_THROW(IOException,
00184 Format("Error generating temp file name: %1",
00185 System::lastErrorMsg()).c_str());
00186 }
00187
00188 size_t len = ::strlen(bfr);
00189 m_filename = new char[len + 1];
00190 ::strncpy(m_filename, bfr, len);
00191 m_filename[len] = '\0';
00192
00193 static Mutex tmpfileMutex;
00194 MutexLock tmpfileML(tmpfileMutex);
00195 m_hdl = CreateFile(m_filename, GENERIC_READ | GENERIC_WRITE,
00196 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
00197 FILE_ATTRIBUTE_NORMAL, NULL);
00198 if (m_hdl == INVALID_HANDLE_VALUE)
00199 {
00200 delete[] m_filename;
00201 m_filename = NULL;
00202 OW_THROW(IOException, Format("Error opening temp file %1: %2",
00203 bfr, System::lastErrorMsg()).c_str());
00204 }
00205 }
00206 #else
00207 void
00208 TmpFileImpl::open()
00209 {
00210 close();
00211 String sfname("/tmp/owtmpfileXXXXXX");
00212 size_t len = sfname.length();
00213 m_filename = new char[len + 1];
00214 strncpy(m_filename, sfname.c_str(), len);
00215 m_filename[len] = '\0';
00216 static Mutex tmpfileMutex;
00217 MutexLock tmpfileML(tmpfileMutex);
00218 m_hdl = mkstemp(m_filename);
00219 if (m_hdl == -1)
00220 {
00221 delete[] m_filename;
00222 m_filename = NULL;
00223 OW_THROW_ERRNO_MSG(IOException, "mkstemp failed");
00224 }
00225 }
00226 #endif
00227
00229 int
00230 TmpFileImpl::close()
00231 {
00232 int rv = -1;
00233 if (m_hdl != OW_INVALID_FILEHANDLE)
00234 {
00235 rv = closeFile(m_hdl);
00236 #if defined(OW_WIN32)
00237 DeleteFile(m_filename);
00238 #else
00239 remove(m_filename);
00240 #endif
00241 delete [] m_filename;
00242 m_filename = NULL;
00243 m_hdl = OW_INVALID_FILEHANDLE;
00244 }
00245 return rv;
00246 }
00248 size_t
00249 TmpFileImpl::read(void* bfr, size_t numberOfBytes, long offset)
00250 {
00251 if (offset == -1L)
00252 {
00253 seek(0L, SEEK_CUR);
00254 }
00255 else
00256 {
00257 seek(offset, SEEK_SET);
00258 }
00259 #if defined(OW_WIN32)
00260 DWORD bytesRead;
00261 size_t cc = (size_t)-1;
00262 if(ReadFile(m_hdl, bfr, (DWORD)numberOfBytes, &bytesRead, NULL))
00263 {
00264 cc = (size_t)bytesRead;
00265 }
00266 return cc;
00267 #else
00268 return ::read(m_hdl, bfr, numberOfBytes);
00269 #endif
00270 }
00272 size_t
00273 TmpFileImpl::write(const void* bfr, size_t numberOfBytes, long offset)
00274 {
00275 if (offset == -1L)
00276 {
00277 seek(0L, SEEK_CUR);
00278 }
00279 else
00280 {
00281 seek(offset, SEEK_SET);
00282 }
00283 #if defined(OW_WIN32)
00284 DWORD bytesWritten;
00285 int rv = -1;
00286 if(WriteFile(m_hdl, bfr, (DWORD)numberOfBytes, &bytesWritten, NULL))
00287 {
00288 rv = (int)bytesWritten;
00289 }
00290 return rv;
00291 #else
00292 int rv = ::write(m_hdl, bfr, numberOfBytes);
00293 if (rv == -1)
00294 {
00295 perror("TmpFile::write()");
00296 }
00297 return rv;
00298 #endif
00299 }
00301 String
00302 TmpFileImpl::releaseFile()
00303 {
00304 String rval(m_filename);
00305 if (m_hdl != OW_INVALID_FILEHANDLE)
00306 {
00307 if (closeFile(m_hdl) == -1)
00308 {
00309 OW_THROW_ERRNO_MSG(IOException, "Unable to close file");
00310 }
00311
00312
00313 delete [] m_filename;
00314 m_filename = NULL;
00315 m_hdl = OW_INVALID_FILEHANDLE;
00316 }
00317 return rval;
00318 }
00319
00320 }
00321