libzypp 17.38.1
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
25
26using std::endl;
27
28namespace zypp {
29 namespace filesystem {
30
32 //
33 // CLASS NAME : TmpPath::Impl
34 //
39 {
40 public:
41
42 enum Flags
43 {
44 NoOp = 0,
45 Autodelete = 1L << 0,
46 KeepTopdir = 1L << 1,
47 //
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
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:
100 };
101
102
104 // CLASS NAME : TmpPath
106
109
111 :_impl( tmpPath_r.empty() ? nullptr : new Impl( std::move(tmpPath_r) ) )
112 {}
113
115 {
116 // virtual not inlined dtor.
117 }
118
119 TmpPath::operator bool() const
120 {
121 return _impl.get();
122 }
123
125 {
126 return _impl.get() ? _impl->path() : Pathname();
127 }
128
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
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
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
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
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
277 {
278 static filesystem::TmpDir _tmpdir( filesystem::TmpPath::defaultLocation(), "zypp." );
279 return _tmpdir.path();
280 }
281
282} // namespace zypp
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define INT
Definition Logger.h:104
Base class for reference counted objects.
Wrapper class for stat/lstat.
Definition PathInfo.h:226
mode_t st_mode() const
Definition PathInfo.h:332
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
Pathname dirname() const
Return all but the last component od this path.
Definition Pathname.h:133
const char * c_str() const
String representation.
Definition Pathname.h:113
const std::string & asString() const
String representation.
Definition Pathname.h:94
std::string basename() const
Return the last component of this path.
Definition Pathname.h:137
Provide a new empty temporary directory and recursively delete it when no longer needed.
Definition TmpPath.h:173
static const std::string & defaultPrefix()
Definition TmpPath.cc:268
TmpDir(const Pathname &inParentDir_r=defaultLocation(), const std::string &prefix_r=defaultPrefix())
Ctor.
Definition TmpPath.cc:223
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:250
Provide a new empty temporary file and delete it when no longer needed.
Definition TmpPath.h:118
TmpFile(const Pathname &inParentDir_r=defaultLocation(), const std::string &prefix_r=defaultPrefix())
Ctor.
Definition TmpPath.cc:152
static TmpFile makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Definition TmpPath.cc:182
static ManagedFile asManagedFile()
Create a temporary file and convert it to a automatically cleaned up ManagedFile.
Definition TmpPath.cc:200
static const std::string & defaultPrefix()
Definition TmpPath.cc:213
Clean or delete a directory on destruction.
Definition TmpPath.cc:39
Impl & operator=(const Impl &)=delete
void autoCleanup(bool yesno_r)
Definition TmpPath.cc:94
Impl(Pathname &&path_r, Flags flags_r=CtorDefault)
Definition TmpPath.cc:52
Impl & operator=(Impl &&)=delete
Impl(const Impl &)=delete
const Pathname & path() const
Definition TmpPath.cc:88
static const Pathname & defaultLocation()
Definition TmpPath.cc:129
RW_pointer< Impl > _impl
Definition TmpPath.h:93
virtual ~TmpPath()
Dtor.
Definition TmpPath.cc:114
Pathname path() const
Definition TmpPath.cc:124
TmpPath()
Default Ctor.
Definition TmpPath.cc:107
bool autoCleanup() const
Whether path is valid and deleted when the last reference drops.
Definition TmpPath.cc:142
Definition ansi.h:855
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
Types and functions for filesystem operations.
Definition PathInfo.cc:41
int chmod(const Pathname &path, mode_t mode)
Like 'chmod'.
Definition PathInfo.cc:1097
mode_t applyUmaskTo(mode_t mode_r)
Modify mode_r according to the current umask ( mode_r & ~getUmask() ).
Definition PathInfo.h:805
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
Definition PathInfo.cc:417
int clean_dir(const Pathname &path)
Like 'rm -r DIR/ *'.
Definition PathInfo.cc:447
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
Definition PathInfo.cc:324
Pathname myTmpDir()
Global access to the zypp.TMPDIR (created on demand, deleted when libzypp is unloaded).
Definition TmpPath.cc:276
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition ManagedFile.h:27
Wrapper for const correct access via Smart pointer types.
Definition PtrTypes.h:293