libMems/Files.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * $Id: Files.h,v 1.23 2004/04/19 23:10:13 darling Exp $
00003  * This file is copyright 2002-2007 Aaron Darling and authors listed in the AUTHORS file.
00004  * This file is licensed under the GPL.
00005  * Please see the file called COPYING for licensing details.
00006  * **************
00007  ******************************************************************************/
00008 
00009 #ifndef __libMems_Files_h__
00010 #define __libMems_Files_h__
00011 
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #endif
00015 
00016 // for CreateTempFilename
00017 #ifdef WIN32
00018 #include "windows.h"
00019 #else
00020 #include "unistd.h"
00021 #endif
00022 
00023 #include "boost/filesystem/operations.hpp"
00024 #include "boost/filesystem/exception.hpp"
00025 #include "boost/algorithm/string.hpp"
00026 #include <string>
00027 #include <sstream>
00028 #include <iostream>
00029 #include <iomanip>
00030 
00031 
00038 std::vector< std::string >& registerFileToDelete( std::string fname = "" );
00039 
00040 inline
00041 std::vector< std::string >& registerFileToDelete( std::string fname ) {
00042         // since this vector is needed when atexit() is called we allocate it
00043         // on the heap so its destructor won't get called
00044         static std::vector< std::string >* files = new std::vector< std::string >();
00045 #pragma omp critical
00046 {
00047         if( fname != "" )
00048                 files->push_back( fname );
00049 }
00050         return *files;
00051 }
00052 
00053 void deleteRegisteredFiles();
00054 inline
00055 void deleteRegisteredFiles() {
00056         // don't be a slob, clean up after yourself:
00057         // delete any files that are laying around
00058         std::vector< std::string >& del_files = registerFileToDelete();
00059         for( int fileI = 0; fileI < del_files.size(); fileI++ )
00060                 boost::filesystem::remove( del_files[ fileI ] );
00061         del_files.clear();      // clear the deleted files from the list
00062 }
00063 
00064 
00068 std::string CreateTempFileName(const std::string& prefix);
00069 
00070 
00071 /* shamelessly ripped from wxWidgets and boostified*/
00072 inline
00073 std::string CreateTempFileName(const std::string& prefix)
00074 {
00075    std::string dir, name, ret_path;
00076 #ifdef WIN32
00077         char buf[MAX_PATH + 1];
00078 #else
00079         char buf[PATH_MAX + 1];
00080 #endif
00081         boost::filesystem::path path( prefix );
00082         dir = path.branch_path().string();
00083         name = path.leaf();
00084         if( name == "/" )
00085         {
00086                 dir += name;
00087                 name.clear();
00088         }
00089 #if defined(WIN32)
00090 
00091     if ( dir.size() == 0 )
00092     {
00093                 strncpy(buf, dir.c_str(), MAX_PATH);
00094         if ( !::GetTempPath(MAX_PATH, buf) )
00095                         std::cerr << "GetTempPath\n";
00096 
00097                 dir = buf;
00098         if ( dir.size()==0 )
00099             dir = ".";  // GetTempFileName() fails if we pass it an emptystd::string
00100     }
00101     else // we have a dir to create the file in
00102     {
00103         // ensure we use only the back slashes as GetTempFileName(), unlike all
00104         // the other APIs, is picky and doesn't accept the forward ones
00105                 boost::algorithm::replace_all( dir, "/", "\\" );
00106     }
00107 
00108         strncpy(buf, path.string().c_str(), MAX_PATH);
00109         if ( !::GetTempFileName(dir.c_str(), name.c_str(), 0, buf) )
00110     {
00111         std::cerr << "GetTempFileName\n";
00112                 path = boost::filesystem::path();
00113     }
00114         ret_path = buf;
00115 
00116 #else // !Windows
00117     if ( dir.empty() )
00118     {
00119         char* env_val = getenv("TMP");
00120         dir = env_val != NULL ? env_val : "";
00121 
00122         if ( dir.size() == 0 ){
00123             env_val = getenv("TEMP");
00124             dir = env_val != NULL ? env_val : "";
00125         }
00126 
00127         if ( dir.size()==0 )
00128         {
00129             // default
00130             #ifdef __DOS__
00131                 dir = ".";
00132             #else
00133                 dir = "/tmp";
00134             #endif
00135         }
00136     }
00137 
00138     path = dir;
00139     path /= name;
00140 
00141     // we need to copy the path to the buffer in which mkstemp() can modify it
00142        std::string path_str = path.string();
00143         path_str += "XXXXXX";  // scratch space for mkstemp()
00144         strncpy( buf, path_str.c_str(), path_str.size()+1 );
00145 
00146 #if defined(HAVE_MKSTEMP)
00147     // cast is safe because thestd::string length doesn't change
00148     int fdTemp = mkstemp( buf );
00149     if ( fdTemp == -1 )
00150     {
00151         // this might be not necessary as mkstemp() on most systems should have
00152         // already done it but it doesn't hurt neither...
00153 //        path.clear();
00154     }
00155     else // mkstemp() succeeded
00156     {
00157                 ret_path = buf;
00158         close(fdTemp);
00159     }
00160 #else // !HAVE_MKSTEMP
00161 
00162 #ifdef HAVE_MKTEMP
00163     // same as above
00164     if ( mktemp( buf ) )
00165                 ret_path = buf;
00166 
00167 #else // !HAVE_MKTEMP (includes __DOS__)
00168     // generate the unique file name ourselves
00169     unsigned my_pid = 0;
00170     #ifndef __DOS__
00171     my_pid = getpid();
00172     #endif
00173 
00174         std::ostringstream oss;
00175 
00176     std::string oss_str;
00177     static const size_t numTries = 1000;
00178     for ( size_t n = 0; n < numTries; n++ )
00179     {
00180         std::ostringstream oss;
00181                 oss << path.string() << my_pid << "." << std::setfill('0') << std::setw(3) << n;
00182         // 3 hex digits is enough for numTries == 1000 < 4096
00183                 boost::filesystem::path pathTry( oss.str() );
00184         oss_str = oss.str();
00185         if ( !boost::filesystem::exists(pathTry) )
00186             break;
00187 
00188     }
00189 
00190     ret_path = oss_str;
00191 #endif // HAVE_MKTEMP/!HAVE_MKTEMP
00192 
00193 #endif // HAVE_MKSTEMP/!HAVE_MKSTEMP
00194 
00195 #endif // Windows/!Windows
00196 
00197         return ret_path;
00198 }
00199 
00200 
00201 #endif // __libMems_Files_h__
00202 

Generated on Fri Mar 14 06:01:02 2008 for libMems by doxygen 1.3.6