libzypp 17.38.5

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
34 //
38 class TmpPath::Impl : public base::ReferenceCounted, private base::NonCopyable
39 {
40 public:
41
42 enum Flags
43 {
44 NoOp = 0,
45 Autodelete = 1L << 0,
46 KeepTopdir = 1L << 1,
47 //
48 CtorDefault = Autodelete
49 };
50
51 public:
52 Impl(Pathname &&path_r, Flags flags_r = CtorDefault)
53 : _path(std::move(path_r)), _flags(flags_r) {
54 MIL << _path << endl;
55 }
56
57 Impl(const Impl &) = delete;
58 Impl(Impl &&) = delete;
59 Impl &operator=(const Impl &) = delete;
60 Impl &operator=(Impl &&) = delete;
61
62 ~Impl() override
63 {
64 if ( ! (_flags & Autodelete) || _path.empty() )
65 return;
66
67 PathInfo p( _path, PathInfo::LSTAT );
68 if ( ! p.isExist() )
69 return;
70
71 int res = 0;
72 if ( p.isDir() )
73 {
74 if ( _flags & KeepTopdir )
75 res = clean_dir( _path );
76 else
77 res = recursive_rmdir( _path );
78 }
79 else
80 res = unlink( _path );
81
82 if ( res )
83 INT << "TmpPath cleanup error (" << res << ") " << p << endl;
84 else
85 DBG << "TmpPath cleaned up " << p << endl;
86 }
87
88 const Pathname & 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 // CLASS NAME : TmpPath
106
107 TmpPath::TmpPath()
108 {}
109
110 TmpPath::TmpPath( Pathname tmpPath_r )
111 :_impl( tmpPath_r.empty() ? nullptr : new Impl( std::move(tmpPath_r) ) )
112 {}
113
114 TmpPath::~TmpPath()
115 {
116 // virtual not inlined dtor.
117 }
118
119 TmpPath::operator bool() const
120 {
121 return _impl.get();
122 }
123
124 Pathname TmpPath::path() const
125 {
126 return _impl.get() ? _impl->path() : Pathname();
127 }
128
129 const Pathname & TmpPath::defaultLocation()
130 {
131 // bsc#1249435: We use 'zypp.tmp' as a fix directory
132 // component to ease setting up SELinux policies.
133 static Pathname p = []() {
134 Pathname ret = Pathname( getenv("ZYPPTMPDIR") ? getenv("ZYPPTMPDIR") : "/var/tmp" );
135 if ( geteuid() == 0 )
136 ret /= "zypp.tmp";
137 return ret;
138 }();
139 return p;
140 }
141
142 bool TmpPath::autoCleanup() const
143 { return _impl.get() ? _impl->autoCleanup() : false; }
144
145 void TmpPath::autoCleanup( bool yesno_r )
146 { if ( _impl.get() ) _impl->autoCleanup( yesno_r ); }
147
149 // CLASS NAME : TmpFile
151
152 TmpFile::TmpFile( const Pathname & inParentDir_r,
153 const std::string & prefix_r )
154 {
155 // parent dir must exist
156 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
157 {
158 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
159 return;
160 }
161
162 // create the temp file
163 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
164 AutoFREE<char> buf { ::strdup( tmpPath.asString().c_str() ) };
165 if ( ! buf )
166 {
167 ERR << "Out of memory" << endl;
168 return;
169 }
170
171 int tmpFd = ::mkostemp( buf, O_CLOEXEC );
172 if ( tmpFd != -1 )
173 {
174 // success; create _impl
175 ::close( tmpFd );
176 _impl = RW_pointer<Impl>( new Impl( Pathname(buf) ) );
177 }
178 else
179 ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
180 }
181
182 TmpFile TmpFile::makeSibling( const Pathname & sibling_r )
183 { return makeSibling( sibling_r, -1U ); }
184
185 TmpFile TmpFile::makeSibling( const Pathname & sibling_r, unsigned mode )
186 {
187 TmpFile ret( sibling_r.dirname(), sibling_r.basename() );
188 if ( ret ) {
189 // clone mode if sibling_r exists
190 PathInfo p( sibling_r );
191 if ( p.isFile() ) {
192 ::chmod( ret.path().c_str(), p.st_mode() );
193 } else if ( mode != -1U ) {
194 ::chmod( ret.path().c_str(), applyUmaskTo( mode ) );
195 }
196 }
197 return ret;
198 }
199
200 ManagedFile TmpFile::asManagedFile()
201 {
202 return asManagedFile( defaultLocation(), defaultPrefix() );
203 }
204
205 ManagedFile TmpFile::asManagedFile(const Pathname &inParentDir_r, const std::string &prefix_r)
206 {
207 filesystem::TmpFile tmpFile( inParentDir_r, prefix_r );
208 ManagedFile mFile ( tmpFile.path(), filesystem::unlink );
209 tmpFile.autoCleanup(false); //cleaned up by ManagedFile
210 return mFile;
211 }
212
213 const std::string & TmpFile::defaultPrefix()
214 {
215 static std::string p( "TmpFile." );
216 return p;
217 }
218
220 // CLASS NAME : TmpDir
222
223 TmpDir::TmpDir( const Pathname & inParentDir_r,
224 const std::string & prefix_r )
225 {
226 // parent dir must exist
227 if ( filesystem::assert_dir( inParentDir_r ) != 0 )
228 {
229 ERR << "Parent directory '" << inParentDir_r << "' can't be created." << endl;
230 return;
231 }
232
233 // create the temp dir
234 Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
235 AutoFREE<char> buf { ::strdup( tmpPath.asString().c_str() ) };
236 if ( ! buf )
237 {
238 ERR << "Out of memory" << endl;
239 return;
240 }
241
242 char * tmp = ::mkdtemp( buf );
243 if ( tmp )
244 // success; create _impl
245 _impl = RW_pointer<Impl>( new Impl( tmp ) );
246 else
247 ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
248 }
249
250 TmpDir TmpDir::makeSibling( const Pathname & sibling_r )
251 { return makeSibling( sibling_r, -1U ); }
252
253 TmpDir TmpDir::makeSibling( const Pathname & sibling_r, unsigned mode )
254 {
255 TmpDir ret( sibling_r.dirname(), sibling_r.basename() );
256 if ( ret ) {
257 // clone mode if sibling_r exists
258 PathInfo p( sibling_r );
259 if ( p.isDir() ) {
260 ::chmod( ret.path().c_str(), p.st_mode() );
261 } else if ( mode != -1U ) {
262 ::chmod( ret.path().c_str(), applyUmaskTo( mode ) );
263 }
264 }
265 return ret;
266 }
267
268 const std::string & TmpDir::defaultPrefix()
269 {
270 static std::string p( "TmpDir." );
271 return p;
272 }
273
274 } // namespace filesystem
275
276 Pathname myTmpDir()
277 {
278 static filesystem::TmpDir _tmpdir( filesystem::TmpPath::defaultLocation(), "zypp." );
279 return _tmpdir.path();
280 }
281
282} // namespace zypp
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
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:48
zypp::filesystem::Pathname::dirname
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:133
zypp::filesystem::Pathname::c_str
const char * c_str() const
String representation.
Definition Pathname.h:113
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:94
zypp::filesystem::Pathname::basename
std::string basename() const
Return the last component of this path.
Definition Pathname.h:137
zypp::filesystem::TmpDir
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition TmpPath.h:173
zypp::filesystem::TmpDir::defaultPrefix
static const std::string & defaultPrefix()
Definition TmpPath.cc:268
zypp::filesystem::TmpDir::TmpDir
TmpDir(const Pathname &inParentDir_r=defaultLocation(), const std::string &prefix_r=defaultPrefix())
Ctor.
Definition TmpPath.cc:223
zypp::filesystem::TmpDir::makeSibling
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:250
zypp::filesystem::TmpFile
Provide a new empty temporary file and delete it when no longer needed.
Definition TmpPath.h:118
zypp::filesystem::TmpFile::TmpFile
TmpFile(const Pathname &inParentDir_r=defaultLocation(), const std::string &prefix_r=defaultPrefix())
Ctor.
Definition TmpPath.cc:152
zypp::filesystem::TmpFile::makeSibling
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:182
zypp::filesystem::TmpFile::asManagedFile
static ManagedFile asManagedFile()
Create a temporary file and convert it to a automatically cleaned up ManagedFile.
Definition TmpPath.cc:200
zypp::filesystem::TmpFile::defaultPrefix
static const std::string & defaultPrefix()
Definition TmpPath.cc:213
zypp::filesystem::TmpPath::Impl
Clean or delete a directory on destruction.
Definition TmpPath.cc:39
zypp::filesystem::TmpPath::Impl::~Impl
~Impl() override
Definition TmpPath.cc:62
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:52
zypp::filesystem::TmpPath::Impl::Flags
Flags
Definition TmpPath.cc:43
zypp::filesystem::TmpPath::Impl::NoOp
@ NoOp
Definition TmpPath.cc:44
zypp::filesystem::TmpPath::Impl::CtorDefault
@ CtorDefault
Definition TmpPath.cc:48
zypp::filesystem::TmpPath::Impl::Autodelete
@ Autodelete
Definition TmpPath.cc:45
zypp::filesystem::TmpPath::Impl::KeepTopdir
@ KeepTopdir
Definition TmpPath.cc:46
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:129
zypp::filesystem::TmpPath::_impl
RW_pointer< Impl > _impl
Definition TmpPath.h:93
zypp::filesystem::TmpPath::~TmpPath
virtual ~TmpPath()
Dtor.
Definition TmpPath.cc:114
zypp::filesystem::TmpPath::path
Pathname path() const
Definition TmpPath.cc:124
zypp::filesystem::TmpPath::TmpPath
TmpPath()
Default Ctor.
Definition TmpPath.cc:107
zypp::filesystem::TmpPath::autoCleanup
bool autoCleanup() const
Whether path is valid and deleted when the last reference drops.
Definition TmpPath.cc:142
std
Definition ansi.h:855
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:1111
zypp::filesystem::applyUmaskTo
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
Definition PathInfo.h:813
zypp::filesystem::recursive_rmdir
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Definition PathInfo.cc:431
zypp::filesystem::clean_dir
int clean_dir(const Pathname &path)
Like 'rm -r DIR/ *'.
Definition PathInfo.cc:461
zypp::filesystem::unlink
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:719
zypp::filesystem::assert_dir
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition PathInfo.cc:338
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::myTmpDir
Pathname myTmpDir()
Global access to the zypp.TMPDIR (created on demand, deleted when libzypp is unloaded).
Definition TmpPath.cc:276
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
ReferenceCounted.h
PathInfo.h
TmpPath.h