libzypp 8.13.6
|
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 * 00130 // METHOD TYPE : 00131 // 00132 TmpPath::operator const void * () 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 if ( filesystem::assert_dir( inParentDir_r ) != 0 ) 00176 { 00177 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl; 00178 return; 00179 } 00180 00181 // create the temp file 00182 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX"); 00183 char * buf = ::strdup( tmpPath.asString().c_str() ); 00184 if ( ! buf ) 00185 { 00186 ERR << "Out of memory" << endl; 00187 return; 00188 } 00189 00190 int tmpFd = ::mkstemp( buf ); 00191 if ( tmpFd != -1 ) 00192 { 00193 // success; create _impl 00194 ::close( tmpFd ); 00195 _impl = RW_pointer<Impl>( new Impl( buf ) ); 00196 } 00197 else 00198 ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl; 00199 00200 ::free( buf ); 00201 } 00202 00204 // 00205 // METHOD NAME : TmpFile::makeSibling 00206 // METHOD TYPE : TmpFile 00207 // 00208 TmpFile TmpFile::makeSibling( const Pathname & sibling_r ) 00209 { 00210 TmpFile ret( sibling_r.dirname(), sibling_r.basename() ); 00211 // clone mode if sibling_r exists 00212 PathInfo p( sibling_r ); 00213 if ( p.isFile() ) 00214 { 00215 ::chmod( ret.path().c_str(), p.st_mode() ); 00216 } 00217 return ret; 00218 } 00219 00221 // 00222 // METHOD NAME : TmpFile::defaultPrefix 00223 // METHOD TYPE : const std::string & 00224 // 00225 const std::string & 00226 TmpFile::defaultPrefix() 00227 { 00228 static string p( "TmpFile." ); 00229 return p; 00230 } 00231 00233 // 00234 // CLASS NAME : TmpDir 00235 // 00237 00239 // 00240 // METHOD NAME : TmpDir::TmpDir 00241 // METHOD TYPE : Constructor 00242 // 00243 TmpDir::TmpDir( const Pathname & inParentDir_r, 00244 const std::string & prefix_r ) 00245 { 00246 // parent dir must exist 00247 if ( filesystem::assert_dir( inParentDir_r ) != 0 ) 00248 { 00249 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl; 00250 return; 00251 } 00252 00253 // create the temp dir 00254 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX"); 00255 char * buf = ::strdup( tmpPath.asString().c_str() ); 00256 if ( ! buf ) 00257 { 00258 ERR << "Out of memory" << endl; 00259 return; 00260 } 00261 00262 char * tmp = ::mkdtemp( buf ); 00263 if ( tmp ) 00264 // success; create _impl 00265 _impl = RW_pointer<Impl>( new Impl( tmp ) ); 00266 else 00267 ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl; 00268 00269 ::free( buf ); 00270 } 00271 00273 // 00274 // METHOD NAME : TmpDir::makeSibling 00275 // METHOD TYPE : TmpDir 00276 // 00277 TmpDir TmpDir::makeSibling( const Pathname & sibling_r ) 00278 { 00279 TmpDir ret( sibling_r.dirname(), sibling_r.basename() ); 00280 // clone mode if sibling_r exists 00281 PathInfo p( sibling_r ); 00282 if ( p.isDir() ) 00283 { 00284 ::chmod( ret.path().c_str(), p.st_mode() ); 00285 } 00286 return ret; 00287 } 00288 00290 // 00291 // METHOD NAME : TmpDir::defaultPrefix 00292 // METHOD TYPE : const std::string & 00293 // 00294 const std::string & 00295 TmpDir::defaultPrefix() 00296 { 00297 static string p( "TmpDir." ); 00298 return p; 00299 } 00300 00301 } // namespace filesystem 00302 } // namespace zypp