TmpPath.cc
Go to the documentation of this file.00001
00002
00003
00004
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
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 bool autoCleanup() const
00086 { return( _flags & Autodelete ); }
00087
00088 void autoCleanup( bool yesno_r )
00089 { _flags = yesno_r ? CtorDefault : NoOp; }
00090
00091 private:
00092 Pathname _path;
00093 Flags _flags;
00094 };
00096
00098
00099
00100
00102
00104
00105
00106
00107
00108 TmpPath::TmpPath()
00109 :_impl( 0 )
00110 {
00111 }
00112
00114
00115
00116
00117
00118 TmpPath::TmpPath( const Pathname & tmpPath_r )
00119 :_impl( tmpPath_r.empty() ? 0 : new Impl( tmpPath_r ) )
00120 {
00121 }
00122
00124
00125
00126
00127
00128 TmpPath::~TmpPath()
00129 {
00130
00131 }
00132
00134
00135
00136
00137
00138 TmpPath::operator const void * () const
00139 {
00140 return _impl.get();
00141 }
00142
00144
00145
00146
00147
00148 Pathname
00149 TmpPath::path() const
00150 {
00151 return _impl.get() ? _impl->path() : Pathname();
00152 }
00153
00155
00156
00157
00158
00159 const Pathname &
00160 TmpPath::defaultLocation()
00161 {
00162 static Pathname p( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/var/tmp" );
00163 return p;
00164 }
00165
00166 bool TmpPath::autoCleanup() const
00167 { return _impl.get() ? _impl->autoCleanup() : false; }
00168
00169 void TmpPath::autoCleanup( bool yesno_r )
00170 { if ( _impl.get() ) _impl->autoCleanup( yesno_r ); }
00171
00173
00174
00175
00177
00178
00180
00181
00182
00183
00184 TmpFile::TmpFile( const Pathname & inParentDir_r,
00185 const std::string & prefix_r )
00186 {
00187
00188 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
00189 {
00190 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
00191 return;
00192 }
00193
00194
00195 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
00196 char * buf = ::strdup( tmpPath.asString().c_str() );
00197 if ( ! buf )
00198 {
00199 ERR << "Out of memory" << endl;
00200 return;
00201 }
00202
00203 int tmpFd = ::mkstemp( buf );
00204 if ( tmpFd != -1 )
00205 {
00206
00207 ::close( tmpFd );
00208 _impl = RW_pointer<Impl>( new Impl( buf ) );
00209 }
00210 else
00211 ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
00212
00213 ::free( buf );
00214 }
00215
00217
00218
00219
00220
00221 TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
00222 {
00223 TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
00224
00225 PathInfo p( sibling_r );
00226 if ( p.isFile() )
00227 {
00228 ::chmod( ret.path().c_str(), p.st_mode() );
00229 }
00230 return ret;
00231 }
00232
00234
00235
00236
00237
00238 const std::string &
00239 TmpFile::defaultPrefix()
00240 {
00241 static string p( "TmpFile." );
00242 return p;
00243 }
00244
00246
00247
00248
00250
00252
00253
00254
00255
00256 TmpDir::TmpDir( const Pathname & inParentDir_r,
00257 const std::string & prefix_r )
00258 {
00259
00260 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
00261 {
00262 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
00263 return;
00264 }
00265
00266
00267 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
00268 char * buf = ::strdup( tmpPath.asString().c_str() );
00269 if ( ! buf )
00270 {
00271 ERR << "Out of memory" << endl;
00272 return;
00273 }
00274
00275 char * tmp = ::mkdtemp( buf );
00276 if ( tmp )
00277
00278 _impl = RW_pointer<Impl>( new Impl( tmp ) );
00279 else
00280 ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
00281
00282 ::free( buf );
00283 }
00284
00286
00287
00288
00289
00290 TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
00291 {
00292 TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
00293
00294 PathInfo p( sibling_r );
00295 if ( p.isDir() )
00296 {
00297 ::chmod( ret.path().c_str(), p.st_mode() );
00298 }
00299 return ret;
00300 }
00301
00303
00304
00305
00306
00307 const std::string &
00308 TmpDir::defaultPrefix()
00309 {
00310 static string p( "TmpDir." );
00311 return p;
00312 }
00313
00314 }
00315 }