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 private:
00086 Pathname _path;
00087 Flags _flags;
00088 };
00090
00092
00093
00094
00096
00098
00099
00100
00101
00102 TmpPath::TmpPath()
00103 :_impl( 0 )
00104 {
00105 }
00106
00108
00109
00110
00111
00112 TmpPath::TmpPath( const Pathname & tmpPath_r )
00113 :_impl( tmpPath_r.empty() ? 0 : new Impl( tmpPath_r ) )
00114 {
00115 }
00116
00118
00119
00120
00121
00122 TmpPath::~TmpPath()
00123 {
00124
00125 }
00126
00128
00129
00130
00131
00132 TmpPath::operator const void * () const
00133 {
00134 return _impl.get();
00135 }
00136
00138
00139
00140
00141
00142 Pathname
00143 TmpPath::path() const
00144 {
00145 return _impl.get() ? _impl->path() : Pathname();
00146 }
00147
00149
00150
00151
00152
00153 const Pathname &
00154 TmpPath::defaultLocation()
00155 {
00156 static Pathname p( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/var/tmp" );
00157 return p;
00158 }
00160
00161
00162
00164
00165
00167
00168
00169
00170
00171 TmpFile::TmpFile( const Pathname & inParentDir_r,
00172 const std::string & prefix_r )
00173 {
00174
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
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
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
00206
00207
00208 TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
00209 {
00210 TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
00211
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
00223
00224
00225 const std::string &
00226 TmpFile::defaultPrefix()
00227 {
00228 static string p( "TmpFile." );
00229 return p;
00230 }
00231
00233
00234
00235
00237
00239
00240
00241
00242
00243 TmpDir::TmpDir( const Pathname & inParentDir_r,
00244 const std::string & prefix_r )
00245 {
00246
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
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
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
00275
00276
00277 TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
00278 {
00279 TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
00280
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
00292
00293
00294 const std::string &
00295 TmpDir::defaultPrefix()
00296 {
00297 static string p( "TmpDir." );
00298 return p;
00299 }
00300
00301 }
00302 }