TmpPath.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include <cstdlib>
00014 #include <cstring>
00015 #include <cerrno>
00016 
00017 #include <iostream>
00018 
00019 #include "zypp/base/ReferenceCounted.h"
00020 #include "zypp/base/NonCopyable.h"
00021 #include "zypp/base/Logger.h"
00022 #include "zypp/PathInfo.h"
00023 #include "zypp/TmpPath.h"
00024 
00025 using namespace std;
00026 
00027 namespace zypp {
00028   namespace filesystem {
00029 
00031     //
00032     //  CLASS NAME : TmpPath::Impl
00036     class TmpPath::Impl : public base::ReferenceCounted, private base::NonCopyable
00037     {
00038       public:
00039     
00040         enum Flags
00041           {
00042             NoOp         = 0,
00043             Autodelete   = 1L << 0,
00044             KeepTopdir   = 1L << 1,
00045             //
00046             CtorDefault  = Autodelete
00047           };
00048     
00049       public:
00050     
00051         Impl( const Pathname & path_r, Flags flags_r = CtorDefault )
00052         : _path( path_r ), _flags( flags_r )
00053         {}
00054     
00055         ~Impl()
00056         {
00057           if ( ! (_flags & Autodelete) || _path.empty() )
00058             return;
00059     
00060           PathInfo p( _path, PathInfo::LSTAT );
00061           if ( ! p.isExist() )
00062             return;
00063     
00064           int res = 0;
00065           if ( p.isDir() )
00066             {
00067               if ( _flags & KeepTopdir )
00068                 res = clean_dir( _path );
00069               else
00070                 res = recursive_rmdir( _path );
00071             }
00072           else
00073             res = unlink( _path );
00074     
00075           if ( res )
00076             INT << "TmpPath cleanup error (" << res << ") " << p << endl;
00077           else
00078             DBG << "TmpPath cleaned up " << p << endl;
00079         }
00080     
00081         const Pathname &
00082         path() const
00083         { return _path; }
00084     
00085       private:
00086         Pathname _path;
00087         Flags    _flags;
00088     };
00090     
00092     //
00093     //  CLASS NAME : TmpPath
00094     //
00096     
00098     //
00099     //  METHOD NAME : TmpPath::TmpPath
00100     //  METHOD TYPE : Constructor
00101     //
00102     TmpPath::TmpPath()
00103     :_impl( 0 ) // empty Pathname
00104     {
00105     }
00106     
00108     //
00109     //  METHOD NAME : TmpPath::TmpPath
00110     //  METHOD TYPE : Constructor
00111     //
00112     TmpPath::TmpPath( const Pathname & tmpPath_r )
00113     :_impl( tmpPath_r.empty() ? 0 : new Impl( tmpPath_r ) )
00114     {
00115     }
00116     
00118     //
00119     //  METHOD NAME : TmpPath::~TmpPath
00120     //  METHOD TYPE : Destructor
00121     //
00122     TmpPath::~TmpPath()
00123     {
00124       // virtual not inlined dtor.
00125     }
00126    
00128     //
00129     //      METHOD NAME : TmpPath::operator const void *const
00130     //      METHOD TYPE :
00131     //
00132     TmpPath::operator const void *const() const
00133     {
00134       return _impl.get();
00135     }
00136  
00138     //
00139     //  METHOD NAME : TmpPath::path
00140     //  METHOD TYPE : Pathname
00141     //
00142     Pathname
00143     TmpPath::path() const
00144     {
00145       return _impl.get() ? _impl->path() : Pathname();
00146     }
00147     
00149     //
00150     //  METHOD NAME : TmpPath::defaultLocation
00151     //  METHOD TYPE : const Pathname &
00152     //
00153     const Pathname &
00154     TmpPath::defaultLocation()
00155     {
00156       static Pathname p( "/var/tmp" );
00157       return p;
00158     }
00160     //
00161     //  CLASS NAME : TmpFile
00162     //
00164     
00165     
00167     //
00168     //  METHOD NAME : TmpFile::TmpFile
00169     //  METHOD TYPE : Constructor
00170     //
00171     TmpFile::TmpFile( const Pathname & inParentDir_r,
00172                       const std::string & prefix_r )
00173     {
00174       // parent dir must exist
00175       PathInfo p( inParentDir_r );
00176       if ( ! p.isDir() )
00177         {
00178           ERR << "Parent directory does not exist: " << p << endl;
00179           return;
00180         }
00181     
00182       // create the temp file
00183       Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
00184       char * buf = ::strdup( tmpPath.asString().c_str() );
00185       if ( ! buf )
00186         {
00187           ERR << "Out of memory" << endl;
00188           return;
00189         }
00190     
00191       int tmpFd = ::mkstemp( buf );
00192       if ( tmpFd != -1 )
00193         {
00194           // success; create _impl
00195           ::close( tmpFd );
00196           _impl = RW_pointer<Impl>( new Impl( buf ) );
00197         }
00198       else
00199         ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
00200     
00201       ::free( buf );
00202     }
00203     
00205     //
00206     //  METHOD NAME : TmpFile::defaultPrefix
00207     //  METHOD TYPE : const std::string &
00208     //
00209     const std::string &
00210     TmpFile::defaultPrefix()
00211     {
00212       static string p( "TmpFile." );
00213       return p;
00214     }
00215     
00217     //
00218     //  CLASS NAME : TmpDir
00219     //
00221     
00223     //
00224     //  METHOD NAME : TmpDir::TmpDir
00225     //  METHOD TYPE : Constructor
00226     //
00227     TmpDir::TmpDir( const Pathname & inParentDir_r,
00228                     const std::string & prefix_r )
00229     {
00230       // parent dir must exist
00231       PathInfo p( inParentDir_r );
00232       if ( ! p.isDir() )
00233         {
00234           ERR << "Parent directory does not exist: " << p << endl;
00235           return;
00236         }
00237     
00238       // create the temp dir
00239       Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
00240       char * buf = ::strdup( tmpPath.asString().c_str() );
00241       if ( ! buf )
00242         {
00243           ERR << "Out of memory" << endl;
00244           return;
00245         }
00246     
00247       char * tmp = ::mkdtemp( buf );
00248       if ( tmp )
00249         // success; create _impl
00250         _impl = RW_pointer<Impl>( new Impl( tmp ) );
00251       else
00252         ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
00253     
00254       ::free( buf );
00255     }
00256     
00258     //
00259     //  METHOD NAME : TmpDir::defaultPrefix
00260     //  METHOD TYPE : const std::string &
00261     //
00262     const std::string &
00263     TmpDir::defaultPrefix()
00264     {
00265       static string p( "TmpDir." );
00266       return p;
00267     }
00268 
00269   } // namespace filesystem
00270 } // namespace zypp

Generated on Thu Jul 6 00:07:28 2006 for zypp by  doxygen 1.4.6