OW_TmpFile.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
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 }  // end of unnamed namespace
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       // work like close, but don't delete the file, it will be given to the
00312       // caller
00313       delete [] m_filename;
00314       m_filename = NULL;
00315       m_hdl = OW_INVALID_FILEHANDLE;
00316    }
00317    return rval;
00318 }
00319 
00320 } // end namespace OW_NAMESPACE
00321 

Generated on Thu Feb 9 08:48:17 2006 for openwbem by  doxygen 1.4.6