1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/TmpPath.cc
19 #include "zypp/base/ReferenceCounted.h"
20 #include "zypp/base/NonCopyable.h"
21 #include "zypp/base/Logger.h"
22 #include "zypp/PathInfo.h"
23 #include "zypp/TmpPath.h"
28 namespace filesystem {
30 ///////////////////////////////////////////////////////////////////
32 // CLASS NAME : TmpPath::Impl
34 * Clean or delete a directory on destruction.
36 class TmpPath::Impl : public base::ReferenceCounted, private base::NonCopyable
46 CtorDefault = Autodelete
51 Impl( const Pathname & path_r, Flags flags_r = CtorDefault )
52 : _path( path_r ), _flags( flags_r )
57 if ( ! (_flags & Autodelete) || _path.empty() )
60 PathInfo p( _path, PathInfo::LSTAT );
67 if ( _flags & KeepTopdir )
68 res = clean_dir( _path );
70 res = recursive_rmdir( _path );
73 res = unlink( _path );
76 INT << "TmpPath cleanup error (" << res << ") " << p << endl;
78 DBG << "TmpPath cleaned up " << p << endl;
89 ///////////////////////////////////////////////////////////////////
91 ///////////////////////////////////////////////////////////////////
93 // CLASS NAME : TmpPath
95 ///////////////////////////////////////////////////////////////////
97 ///////////////////////////////////////////////////////////////////
99 // METHOD NAME : TmpPath::TmpPath
100 // METHOD TYPE : Constructor
103 :_impl( 0 ) // empty Pathname
107 ///////////////////////////////////////////////////////////////////
109 // METHOD NAME : TmpPath::TmpPath
110 // METHOD TYPE : Constructor
112 TmpPath::TmpPath( const Pathname & tmpPath_r )
113 :_impl( tmpPath_r.empty() ? 0 : new Impl( tmpPath_r ) )
117 ///////////////////////////////////////////////////////////////////
119 // METHOD NAME : TmpPath::~TmpPath
120 // METHOD TYPE : Destructor
124 // virtual not inlined dtor.
127 ///////////////////////////////////////////////////////////////////
129 // METHOD NAME : TmpPath::operator const void *
132 TmpPath::operator const void * () const
137 ///////////////////////////////////////////////////////////////////
139 // METHOD NAME : TmpPath::path
140 // METHOD TYPE : Pathname
143 TmpPath::path() const
145 return _impl.get() ? _impl->path() : Pathname();
148 ///////////////////////////////////////////////////////////////////
150 // METHOD NAME : TmpPath::defaultLocation
151 // METHOD TYPE : const Pathname &
154 TmpPath::defaultLocation()
156 static Pathname p( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/var/tmp" );
159 ///////////////////////////////////////////////////////////////////
161 // CLASS NAME : TmpFile
163 ///////////////////////////////////////////////////////////////////
166 ///////////////////////////////////////////////////////////////////
168 // METHOD NAME : TmpFile::TmpFile
169 // METHOD TYPE : Constructor
171 TmpFile::TmpFile( const Pathname & inParentDir_r,
172 const std::string & prefix_r )
174 // parent dir must exist
175 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
177 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
181 // create the temp file
182 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
183 char * buf = ::strdup( tmpPath.asString().c_str() );
186 ERR << "Out of memory" << endl;
190 int tmpFd = ::mkstemp( buf );
193 // success; create _impl
195 _impl = RW_pointer<Impl>( new Impl( buf ) );
198 ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
203 ///////////////////////////////////////////////////////////////////
205 // METHOD NAME : TmpFile::makeSibling
206 // METHOD TYPE : TmpFile
208 TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
210 TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
211 // clone mode if sibling_r exists
212 PathInfo p( sibling_r );
215 ::chmod( ret.path().c_str(), p.st_mode() );
220 ///////////////////////////////////////////////////////////////////
222 // METHOD NAME : TmpFile::defaultPrefix
223 // METHOD TYPE : const std::string &
226 TmpFile::defaultPrefix()
228 static string p( "TmpFile." );
232 ///////////////////////////////////////////////////////////////////
234 // CLASS NAME : TmpDir
236 ///////////////////////////////////////////////////////////////////
238 ///////////////////////////////////////////////////////////////////
240 // METHOD NAME : TmpDir::TmpDir
241 // METHOD TYPE : Constructor
243 TmpDir::TmpDir( const Pathname & inParentDir_r,
244 const std::string & prefix_r )
246 // parent dir must exist
247 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
249 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
253 // create the temp dir
254 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
255 char * buf = ::strdup( tmpPath.asString().c_str() );
258 ERR << "Out of memory" << endl;
262 char * tmp = ::mkdtemp( buf );
264 // success; create _impl
265 _impl = RW_pointer<Impl>( new Impl( tmp ) );
267 ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
272 ///////////////////////////////////////////////////////////////////
274 // METHOD NAME : TmpDir::makeSibling
275 // METHOD TYPE : TmpDir
277 TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
279 TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
280 // clone mode if sibling_r exists
281 PathInfo p( sibling_r );
284 ::chmod( ret.path().c_str(), p.st_mode() );
289 ///////////////////////////////////////////////////////////////////
291 // METHOD NAME : TmpDir::defaultPrefix
292 // METHOD TYPE : const std::string &
295 TmpDir::defaultPrefix()
297 static string p( "TmpDir." );
301 } // namespace filesystem