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() 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( "/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 PathInfo p( inParentDir_r );
00176 if ( ! p.isDir() )
00177 {
00178 ERR << "Parent directory does not exist: " << p << endl;
00179 return;
00180 }
00181
00182
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
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
00207
00208
00209 const std::string &
00210 TmpFile::defaultPrefix()
00211 {
00212 static string p( "TmpFile." );
00213 return p;
00214 }
00215
00217
00218
00219
00221
00223
00224
00225
00226
00227 TmpDir::TmpDir( const Pathname & inParentDir_r,
00228 const std::string & prefix_r )
00229 {
00230
00231 PathInfo p( inParentDir_r );
00232 if ( ! p.isDir() )
00233 {
00234 ERR << "Parent directory does not exist: " << p << endl;
00235 return;
00236 }
00237
00238
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
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
00260
00261
00262 const std::string &
00263 TmpDir::defaultPrefix()
00264 {
00265 static string p( "TmpDir." );
00266 return p;
00267 }
00268
00269 }
00270 }