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
1.5.0