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( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/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::makeSibling
00207     //  METHOD TYPE : TmpFile
00208     //
00209     TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
00210     {
00211       TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
00212       // clone mode if sibling_r exists
00213       PathInfo p( sibling_r );
00214       if ( p.isExist() )
00215       {
00216         chmod( ret.path(), p.st_mode() );
00217       }
00218       return ret;
00219     }
00220 
00222     //
00223     //  METHOD NAME : TmpFile::defaultPrefix
00224     //  METHOD TYPE : const std::string &
00225     //
00226     const std::string &
00227     TmpFile::defaultPrefix()
00228     {
00229       static string p( "TmpFile." );
00230       return p;
00231     }
00232 
00234     //
00235     //  CLASS NAME : TmpDir
00236     //
00238 
00240     //
00241     //  METHOD NAME : TmpDir::TmpDir
00242     //  METHOD TYPE : Constructor
00243     //
00244     TmpDir::TmpDir( const Pathname & inParentDir_r,
00245                     const std::string & prefix_r )
00246     {
00247       // parent dir must exist
00248       PathInfo p( inParentDir_r );
00249       if ( ! p.isDir() )
00250         {
00251           ERR << "Parent directory does not exist: " << p << endl;
00252           return;
00253         }
00254 
00255       // create the temp dir
00256       Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
00257       char * buf = ::strdup( tmpPath.asString().c_str() );
00258       if ( ! buf )
00259         {
00260           ERR << "Out of memory" << endl;
00261           return;
00262         }
00263 
00264       char * tmp = ::mkdtemp( buf );
00265       if ( tmp )
00266         // success; create _impl
00267         _impl = RW_pointer<Impl>( new Impl( tmp ) );
00268       else
00269         ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
00270 
00271       ::free( buf );
00272     }
00273 
00275     //
00276     //  METHOD NAME : TmpDir::makeSibling
00277     //  METHOD TYPE : TmpDir
00278     //
00279     TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
00280     {
00281       TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
00282       // clone mode if sibling_r exists
00283       PathInfo p( sibling_r );
00284       if ( p.isExist() )
00285       {
00286         chmod( ret.path(), p.st_mode() );
00287       }
00288       return ret;
00289     }
00290 
00292     //
00293     //  METHOD NAME : TmpDir::defaultPrefix
00294     //  METHOD TYPE : const std::string &
00295     //
00296     const std::string &
00297     TmpDir::defaultPrefix()
00298     {
00299       static string p( "TmpDir." );
00300       return p;
00301     }
00302 
00303   } // namespace filesystem
00304 } // namespace zypp

Generated on Tue Sep 25 19:23:10 2007 for libzypp by  doxygen 1.5.3