libzypp 17.37.10

TmpPath.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
13#include <cstdlib>
14#include <cstring>
15#include <cerrno>
16
17#include <iostream>
18#include <utility>
19
20#include <zypp-core/base/ReferenceCounted.h>
21#include <zypp-core/base/NonCopyable.h>
22#include <zypp-core/base/Logger.h>
23#include <zypp-core/fs/PathInfo.h>
24#include <zypp-core/fs/TmpPath.h>
25
26 using std::endl;
27
28 namespace zypp {
29 namespace filesystem {
30
32 //
33 // CLASS NAME : TmpPath::Impl
37 class TmpPath::Impl : public base::ReferenceCounted, private base::NonCopyable
38 {
39 public:
40
41 enum Flags
42 {
43 NoOp = 0,
44 Autodelete = 1L << 0,
45 KeepTopdir = 1L << 1,
46 //
47 CtorDefault = Autodelete
48 };
49
50 public:
51 Impl(Pathname &&path_r, Flags flags_r = CtorDefault)
52 : _path(std::move(path_r)), _flags(flags_r) {
53 MIL << _path << endl;
54 }
55
56 Impl(const Impl &) = delete;
57 Impl(Impl &&) = delete;
58 Impl &operator=(const Impl &) = delete;
59 Impl &operator=(Impl &&) = delete;
60
61 ~Impl() override
62 {
63 if ( ! (_flags & Autodelete) || _path.empty() )
64 return;
65
66 PathInfo p( _path, PathInfo::LSTAT );
67 if ( ! p.isExist() )
68 return;
69
70 int res = 0;
71 if ( p.isDir() )
72 {
73 if ( _flags & KeepTopdir )
74 res = clean_dir( _path );
75 else
76 res = recursive_rmdir( _path );
77 }
78 else
79 res = unlink( _path );
80
81 if ( res )
82 INT << "TmpPath cleanup error (" << res << ") " << p << endl;
83 else
84 DBG << "TmpPath cleaned up " << p << endl;
85 }
86
87 const Pathname &
88 path() const
89 { return _path; }
90
91 bool autoCleanup() const
92 { return( _flags & Autodelete ); }
93
94 void autoCleanup( bool yesno_r )
95 { _flags = yesno_r ? CtorDefault : NoOp; }
96
97 private:
98 Pathname _path;
99 Flags _flags;
100 };
101
102
104 //
105 // CLASS NAME : TmpPath
106 //
108
110 //
111 // METHOD NAME : TmpPath::TmpPath
112 // METHOD TYPE : Constructor
113 //
114 TmpPath::TmpPath()
115 {}
116
118 //
119 // METHOD NAME : TmpPath::TmpPath
120 // METHOD TYPE : Constructor
121 //
122 TmpPath::TmpPath( Pathname tmpPath_r )
123 :_impl( tmpPath_r.empty() ? nullptr : new Impl( std::move(tmpPath_r) ) )
124 {}
125
127 //
128 // METHOD NAME : TmpPath::~TmpPath
129 // METHOD TYPE : Destructor
130 //
131 TmpPath::~TmpPath()
132 {
133 // virtual not inlined dtor.
134 }
135
137 //
138 // METHOD NAME : TmpPath::operator const void *
139 // METHOD TYPE :
140 //
141 TmpPath::operator bool() const
142 {
143 return _impl.get();
144 }
145
147 //
148 // METHOD NAME : TmpPath::path
149 // METHOD TYPE : Pathname
150 //
151 Pathname
152 TmpPath::path() const
153 {
154 return _impl.get() ? _impl->path() : Pathname();
155 }
156
158 //
159 // METHOD NAME : TmpPath::defaultLocation
160 // METHOD TYPE : const Pathname &
161 //
162 const Pathname &
163 TmpPath::defaultLocation()
164 {
165 static Pathname p( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/var/tmp" );
166 return p;
167 }
168
169 bool TmpPath::autoCleanup() const
170 { return _impl.get() ? _impl->autoCleanup() : false; }
171
172 void TmpPath::autoCleanup( bool yesno_r )
173 { if ( _impl.get() ) _impl->autoCleanup( yesno_r ); }
174
176 //
177 // CLASS NAME : TmpFile
178 //
180
181
183 //
184 // METHOD NAME : TmpFile::TmpFile
185 // METHOD TYPE : Constructor
186 //
187 TmpFile::TmpFile( const Pathname & inParentDir_r,
188 const std::string & prefix_r )
189 {
190 // parent dir must exist
191 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
192 {
193 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
194 return;
195 }
196
197 // create the temp file
198 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
199 AutoFREE<char> buf { ::strdup( tmpPath.asString().c_str() ) };
200 if ( ! buf )
201 {
202 ERR << "Out of memory" << endl;
203 return;
204 }
205
206 int tmpFd = ::mkostemp( buf, O_CLOEXEC );
207 if ( tmpFd != -1 )
208 {
209 // success; create _impl
210 ::close( tmpFd );
211 _impl = RW_pointer<Impl>( new Impl( Pathname(buf) ) );
212 }
213 else
214 ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
215 }
216
218 //
219 // METHOD NAME : TmpFile::makeSibling
220 // METHOD TYPE : TmpFile
221 //
222 TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
223 { return makeSibling( sibling_r, -1U ); }
224
225 TmpFile TmpFile::makeSibling( const Pathname & sibling_r, unsigned mode )
226 {
227 TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
228 if ( ret ) {
229 // clone mode if sibling_r exists
230 PathInfo p( sibling_r );
231 if ( p.isFile() ) {
232 ::chmod( ret.path().c_str(), p.st_mode() );
233 } else if ( mode != -1U ) {
234 ::chmod( ret.path().c_str(), applyUmaskTo( mode ) );
235 }
236 }
237 return ret;
238 }
239
240 ManagedFile TmpFile::asManagedFile()
241 {
242 return asManagedFile( defaultLocation(), defaultPrefix() );
243 }
244
245 ManagedFile TmpFile::asManagedFile(const Pathname &inParentDir_r, const std::string &prefix_r)
246 {
247 filesystem::TmpFile tmpFile( inParentDir_r, prefix_r );
248 ManagedFile mFile ( tmpFile.path(), filesystem::unlink );
249 tmpFile.autoCleanup(false); //cleaned up by ManagedFile
250 return mFile;
251 }
252
254 //
255 // METHOD NAME : TmpFile::defaultPrefix
256 // METHOD TYPE : const std::string &
257 //
258 const std::string &
259 TmpFile::defaultPrefix()
260 {
261 static std::string p( "TmpFile." );
262 return p;
263 }
264
266 //
267 // CLASS NAME : TmpDir
268 //
270
272 //
273 // METHOD NAME : TmpDir::TmpDir
274 // METHOD TYPE : Constructor
275 //
276 TmpDir::TmpDir( const Pathname & inParentDir_r,
277 const std::string & prefix_r )
278 {
279 // parent dir must exist
280 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
281 {
282 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
283 return;
284 }
285
286 // create the temp dir
287 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
288 AutoFREE<char> buf { ::strdup( tmpPath.asString().c_str() ) };
289 if ( ! buf )
290 {
291 ERR << "Out of memory" << endl;
292 return;
293 }
294
295 char * tmp = ::mkdtemp( buf );
296 if ( tmp )
297 // success; create _impl
298 _impl = RW_pointer<Impl>( new Impl( tmp ) );
299 else
300 ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
301 }
302
304 //
305 // METHOD NAME : TmpDir::makeSibling
306 // METHOD TYPE : TmpDir
307 //
308 TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
309 { return makeSibling( sibling_r, -1U ); }
310
311 TmpDir TmpDir::makeSibling( const Pathname & sibling_r, unsigned mode )
312 {
313 TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
314 if ( ret ) {
315 // clone mode if sibling_r exists
316 PathInfo p( sibling_r );
317 if ( p.isDir() ) {
318 ::chmod( ret.path().c_str(), p.st_mode() );
319 } else if ( mode != -1U ) {
320 ::chmod( ret.path().c_str(), applyUmaskTo( mode ) );
321 }
322 }
323 return ret;
324 }
325
327 //
328 // METHOD NAME : TmpDir::defaultPrefix
329 // METHOD TYPE : const std::string &
330 //
331 const std::string &
332 TmpDir::defaultPrefix()
333 {
334 static std::string p( "TmpDir." );
335 return p;
336 }
337
338 } // namespace filesystem
339
340 Pathname myTmpDir()
341 {
342 static filesystem::TmpDir _tmpdir( filesystem::TmpPath::defaultLocation(), "zypp." );
343 return _tmpdir.path();
344 }
345
346} // namespace zypp
bool
zypp::base::ReferenceCounted
Base class for reference counted objects.
Definition ReferenceCounted.h:35
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::st_mode
mode_t st_mode() const
Definition PathInfo.h:332
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition PathInfo.h:296
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition PathInfo.h:295
zypp::filesystem::PathInfo::LSTAT
@ LSTAT
Definition PathInfo.h:231
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::filesystem::Pathname::dirname
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:126
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:112
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:93
zypp::filesystem::Pathname::basename
std::string basename() const
Return the last component of this path.
Definition Pathname.h:130
zypp::filesystem::TmpDir
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition TmpPath.h:188
zypp::filesystem::TmpDir::defaultPrefix
static const std::string & defaultPrefix()
Definition TmpPath.cc:332
zypp::filesystem::TmpDir::TmpDir
TmpDir(const Pathname &inParentDir_r=defaultLocation(), const std::string &prefix_r=defaultPrefix())
Ctor.
Definition TmpPath.cc:276
zypp::filesystem::TmpDir::makeSibling
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:308
zypp::filesystem::TmpFile
Provide a new empty temporary file and delete it when no longer needed.
Definition TmpPath.h:128
zypp::filesystem::TmpFile::TmpFile
TmpFile(const Pathname &inParentDir_r=defaultLocation(), const std::string &prefix_r=defaultPrefix())
Ctor.
Definition TmpPath.cc:187
zypp::filesystem::TmpFile::makeSibling
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:222
zypp::filesystem::TmpFile::asManagedFile
static ManagedFile asManagedFile()
Create a temporary file and convert it to a automatically cleaned up ManagedFile.
Definition TmpPath.cc:240
zypp::filesystem::TmpFile::defaultPrefix
static const std::string & defaultPrefix()
Definition TmpPath.cc:259
zypp::filesystem::TmpPath::Impl
Clean or delete a directory on destruction.
Definition TmpPath.cc:38
zypp::filesystem::TmpPath::Impl::~Impl
~Impl() override
Definition TmpPath.cc:61
zypp::filesystem::TmpPath::Impl::Impl
Impl(Impl &&)=delete
zypp::filesystem::TmpPath::Impl::operator=
Impl & operator=(const Impl &)=delete
zypp::filesystem::TmpPath::Impl::autoCleanup
void autoCleanup(bool yesno_r)
Definition TmpPath.cc:94
zypp::filesystem::TmpPath::Impl::_path
Pathname _path
Definition TmpPath.cc:98
zypp::filesystem::TmpPath::Impl::_flags
Flags _flags
Definition TmpPath.cc:99
zypp::filesystem::TmpPath::Impl::Impl
Impl(Pathname &&path_r, Flags flags_r=CtorDefault)
Definition TmpPath.cc:51
zypp::filesystem::TmpPath::Impl::Flags
Flags
Definition TmpPath.cc:42
zypp::filesystem::TmpPath::Impl::NoOp
@ NoOp
Definition TmpPath.cc:43
zypp::filesystem::TmpPath::Impl::CtorDefault
@ CtorDefault
Definition TmpPath.cc:47
zypp::filesystem::TmpPath::Impl::Autodelete
@ Autodelete
Definition TmpPath.cc:44
zypp::filesystem::TmpPath::Impl::KeepTopdir
@ KeepTopdir
Definition TmpPath.cc:45
zypp::filesystem::TmpPath::Impl::autoCleanup
bool autoCleanup() const
Definition TmpPath.cc:91
zypp::filesystem::TmpPath::Impl::operator=
Impl & operator=(Impl &&)=delete
zypp::filesystem::TmpPath::Impl::Impl
Impl(const Impl &)=delete
zypp::filesystem::TmpPath::Impl::path
const Pathname & path() const
Definition TmpPath.cc:88
zypp::filesystem::TmpPath::defaultLocation
static const Pathname & defaultLocation()
Definition TmpPath.cc:163
zypp::filesystem::TmpPath::_impl
RW_pointer< Impl > _impl
Definition TmpPath.h:98
zypp::filesystem::TmpPath::~TmpPath
virtual ~TmpPath()
Dtor.
Definition TmpPath.cc:131
zypp::filesystem::TmpPath::path
Pathname path() const
Definition TmpPath.cc:152
zypp::filesystem::TmpPath::TmpPath
TmpPath()
Default Ctor.
Definition TmpPath.cc:114
zypp::filesystem::TmpPath::autoCleanup
bool autoCleanup() const
Whether path is valid and deleted when the last reference drops.
Definition TmpPath.cc:169
std
Definition Arch.h:364
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
zypp::filesystem
Types and functions for filesystem operations.
Definition Glob.cc:24
zypp::filesystem::chmod
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
Definition PathInfo.cc:1097
zypp::filesystem::applyUmaskTo
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
Definition PathInfo.h:805
zypp::filesystem::recursive_rmdir
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Definition PathInfo.cc:417
zypp::filesystem::clean_dir
int clean_dir(const Pathname &path)
Like 'rm -r DIR/ *'.
Definition PathInfo.cc:447
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
zypp::filesystem::assert_dir
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition PathInfo.cc:324
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition Application.cc:20
zypp::myTmpDir
Pathname myTmpDir()
Global access to the zypp.TMPDIR (created on demand, deleted when libzypp is unloaded)
Definition TmpPath.cc:340
zypp::ManagedFile
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition ManagedFile.h:27
zypp::AutoFREE
Definition AutoDispose.h:332
zypp::RW_pointer
Wrapper for const correct access via Smart pointer types.
Definition PtrTypes.h:293
Logger.h
DBG
#define DBG
Definition Logger.h:99
MIL
#define MIL
Definition Logger.h:100
ERR
#define ERR
Definition Logger.h:102
INT
#define INT
Definition Logger.h:104
NonCopyable.h
ReferenceCounted.h
PathInfo.h
TmpPath.h