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;
85 bool autoCleanup() const
86 { return( _flags & Autodelete ); }
88 void autoCleanup( bool yesno_r )
89 { _flags = yesno_r ? CtorDefault : NoOp; }
95 ///////////////////////////////////////////////////////////////////
97 ///////////////////////////////////////////////////////////////////
99 // CLASS NAME : TmpPath
101 ///////////////////////////////////////////////////////////////////
103 ///////////////////////////////////////////////////////////////////
105 // METHOD NAME : TmpPath::TmpPath
106 // METHOD TYPE : Constructor
111 ///////////////////////////////////////////////////////////////////
113 // METHOD NAME : TmpPath::TmpPath
114 // METHOD TYPE : Constructor
116 TmpPath::TmpPath( const Pathname & tmpPath_r )
117 :_impl( tmpPath_r.empty() ? nullptr : new Impl( tmpPath_r ) )
120 ///////////////////////////////////////////////////////////////////
122 // METHOD NAME : TmpPath::~TmpPath
123 // METHOD TYPE : Destructor
127 // virtual not inlined dtor.
130 ///////////////////////////////////////////////////////////////////
132 // METHOD NAME : TmpPath::operator const void *
135 TmpPath::operator bool() const
140 ///////////////////////////////////////////////////////////////////
142 // METHOD NAME : TmpPath::path
143 // METHOD TYPE : Pathname
146 TmpPath::path() const
148 return _impl.get() ? _impl->path() : Pathname();
151 ///////////////////////////////////////////////////////////////////
153 // METHOD NAME : TmpPath::defaultLocation
154 // METHOD TYPE : const Pathname &
157 TmpPath::defaultLocation()
159 static Pathname p( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/var/tmp" );
163 bool TmpPath::autoCleanup() const
164 { return _impl.get() ? _impl->autoCleanup() : false; }
166 void TmpPath::autoCleanup( bool yesno_r )
167 { if ( _impl.get() ) _impl->autoCleanup( yesno_r ); }
169 ///////////////////////////////////////////////////////////////////
171 // CLASS NAME : TmpFile
173 ///////////////////////////////////////////////////////////////////
176 ///////////////////////////////////////////////////////////////////
178 // METHOD NAME : TmpFile::TmpFile
179 // METHOD TYPE : Constructor
181 TmpFile::TmpFile( const Pathname & inParentDir_r,
182 const std::string & prefix_r )
184 // parent dir must exist
185 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
187 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
191 // create the temp file
192 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
193 char * buf = ::strdup( tmpPath.asString().c_str() );
196 ERR << "Out of memory" << endl;
200 int tmpFd = ::mkostemp( buf, O_CLOEXEC );
203 // success; create _impl
205 _impl = RW_pointer<Impl>( new Impl( buf ) );
208 ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
213 ///////////////////////////////////////////////////////////////////
215 // METHOD NAME : TmpFile::makeSibling
216 // METHOD TYPE : TmpFile
218 TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
220 TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
221 // clone mode if sibling_r exists
222 PathInfo p( sibling_r );
225 ::chmod( ret.path().c_str(), p.st_mode() );
230 ///////////////////////////////////////////////////////////////////
232 // METHOD NAME : TmpFile::defaultPrefix
233 // METHOD TYPE : const std::string &
236 TmpFile::defaultPrefix()
238 static string p( "TmpFile." );
242 ///////////////////////////////////////////////////////////////////
244 // CLASS NAME : TmpDir
246 ///////////////////////////////////////////////////////////////////
248 ///////////////////////////////////////////////////////////////////
250 // METHOD NAME : TmpDir::TmpDir
251 // METHOD TYPE : Constructor
253 TmpDir::TmpDir( const Pathname & inParentDir_r,
254 const std::string & prefix_r )
256 // parent dir must exist
257 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
259 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
263 // create the temp dir
264 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
265 char * buf = ::strdup( tmpPath.asString().c_str() );
268 ERR << "Out of memory" << endl;
272 char * tmp = ::mkdtemp( buf );
274 // success; create _impl
275 _impl = RW_pointer<Impl>( new Impl( tmp ) );
277 ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
282 ///////////////////////////////////////////////////////////////////
284 // METHOD NAME : TmpDir::makeSibling
285 // METHOD TYPE : TmpDir
287 TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
289 TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
290 // clone mode if sibling_r exists
291 PathInfo p( sibling_r );
294 ::chmod( ret.path().c_str(), p.st_mode() );
299 ///////////////////////////////////////////////////////////////////
301 // METHOD NAME : TmpDir::defaultPrefix
302 // METHOD TYPE : const std::string &
305 TmpDir::defaultPrefix()
307 static string p( "TmpDir." );
311 } // namespace filesystem