• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • io
ktempdir.cpp
Go to the documentation of this file.
1/* kate: tab-indents off; replace-tabs on; tab-width 4; remove-trailing-space on; encoding utf-8;*/
2/*
3 * This file is part of the KDE libraries
4 * Copyright (c) 2003 Joseph Wenninger <jowenn@kde.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License version 2 as published by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 **/
20
21#include "ktempdir.h"
22
23#include <config.h>
24
25#include <sys/types.h>
26
27#ifdef HAVE_SYS_STAT_H
28#include <sys/stat.h>
29#endif
30
31#include <fcntl.h>
32#include <stdlib.h>
33#include <unistd.h>
34#include <errno.h>
35#include <dirent.h>
36
37#ifdef HAVE_TEST
38#include <test.h>
39#endif
40#ifdef HAVE_PATHS_H
41#include <paths.h>
42#endif
43
44#include <QtCore/QDir>
45
46#include "kglobal.h"
47#include "krandom.h"
48#include "kcomponentdata.h"
49#include "kstandarddirs.h"
50#include <kdebug.h>
51#include "kde_file.h"
52
53#ifdef Q_WS_WIN
54#include <QtCore/QVarLengthArray>
55#include <windows.h>
56#include <shellapi.h>
57extern QString mkdtemp_QString (const QString &_template);
58#endif
59
60#ifdef _WIN32_WCE
61#include <shellapi.h>
62#endif
63
64class KTempDir::Private
65{
66public:
67 int error;
68 QString tmpName;
69 bool exists;
70 bool autoRemove;
71
72 Private()
73 {
74 autoRemove = true;
75 exists = false;
76 error=0;
77 }
78};
79
80KTempDir::KTempDir(const QString &directoryPrefix, int mode) : d(new Private)
81{
82 (void) create( directoryPrefix.isEmpty() ? KStandardDirs::locateLocal("tmp", KGlobal::mainComponent().componentName()) : directoryPrefix , mode);
83}
84
85bool KTempDir::create(const QString &directoryPrefix, int mode)
86{
87 (void) KRandom::random();
88
89#ifdef Q_WS_WIN
90 const QString nme = directoryPrefix + QLatin1String("XXXXXX");
91 const QString realName = mkdtemp_QString(nme);
92 if(realName.isEmpty())
93 {
94 kWarning(180) << "KTempDir: Error trying to create " << nme
95 << ": " << ::strerror(errno) << endl;
96 d->error = errno;
97 d->tmpName.clear();
98 return false;
99 }
100
101 // got a return value != 0
102 d->tmpName = realName + QLatin1Char('/');
103 kDebug(180) << "KTempDir: Temporary directory created :" << d->tmpName
104 << endl;
105 mode_t umsk = KGlobal::umask();
106 KDE::chmod(nme, mode&(~umsk));
107
108 // Success!
109 d->exists = true;
110#else
111 QByteArray nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
112 char *realName;
113 if((realName=mkdtemp(nme.data())) == 0)
114 {
115 // Recreate it for the warning, mkdtemps emptied it
116 nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
117 kWarning(180) << "KTempDir: Error trying to create " << nme.data()
118 << ": " << ::strerror(errno) << endl;
119 d->error = errno;
120 d->tmpName.clear();
121 return false;
122 }
123
124 // got a return value != 0
125 QByteArray realNameStr(realName);
126 d->tmpName = QFile::decodeName(realNameStr)+QLatin1Char('/');
127 kDebug(180) << "KTempDir: Temporary directory created :" << d->tmpName
128 << endl;
129
130 mode_t umsk = KGlobal::umask();
131 if(chmod(nme, mode&(~umsk)) < 0) {
132 kWarning(180) << "KTempDir: Unable to change permissions on" << d->tmpName
133 << ":" << ::strerror(errno);
134 d->error = errno;
135 d->tmpName.clear();
136 (void) ::rmdir(realName); // Cleanup created directory
137 return false;
138 }
139
140 // Success!
141 d->exists = true;
142
143 // Set uid/gid (necessary for SUID programs)
144 if(chown(nme, getuid(), getgid()) < 0) {
145 // Just warn, but don't failover yet
146 kWarning(180) << "KTempDir: Unable to change owner on" << d->tmpName
147 << ":" << ::strerror(errno);
148 }
149
150#endif
151 return true;
152}
153
154KTempDir::~KTempDir()
155{
156 if (d->autoRemove) {
157 unlink();
158 }
159
160 delete d;
161}
162
163int KTempDir::status() const
164{
165 return d->error;
166}
167
168QString KTempDir::name() const
169{
170 return d->tmpName;
171}
172
173bool KTempDir::exists() const
174{
175 return d->exists;
176}
177
178void KTempDir::setAutoRemove(bool autoRemove)
179{
180 d->autoRemove = autoRemove;
181}
182
183bool KTempDir::autoRemove() const
184{
185 return d->autoRemove;
186}
187
188void KTempDir::unlink()
189{
190 if (!d->exists) return;
191 if (KTempDir::removeDir(d->tmpName))
192 d->error=0;
193 else
194 d->error=errno;
195 d->exists=false;
196}
197
198#ifndef Q_WS_WIN
199// Auxiliary recursive function for removeDirs
200static bool rmtree(const QByteArray& name)
201{
202 //kDebug(180) << "Checking directory for remove" << name;
203 KDE_struct_stat st;
204 if ( KDE_lstat( name.data(), &st ) == -1 ) // Do not dereference symlink!
205 return false;
206 if ( S_ISDIR( st.st_mode ) )
207 {
208 // This is a directory, so process it
209 //kDebug(180) << "File" << name << "is DIRECTORY!";
210 KDE_struct_dirent* ep;
211 DIR* dp = ::opendir( name.data() );
212 if ( !dp )
213 return false;
214 while ( ( ep = KDE_readdir( dp ) ) )
215 {
216 //kDebug(180) << "CHECKING" << name << "/" << ep->d_name;
217 if ( !qstrcmp( ep->d_name, "." ) || !qstrcmp( ep->d_name, ".." ) )
218 continue;
219 QByteArray newName( name );
220 newName += '/';
221 newName += ep->d_name;
222 /*
223 * Be defensive and close the directory.
224 *
225 * Potential problems:
226 * - opendir/readdir/closedir is not re-entrant
227 * - unlink and rmdir invalidates a opendir/readdir/closedir
228 * - limited number of file descriptors for opendir/readdir/closedir
229 */
230 if ( ::closedir( dp ) ) {
231 kDebug(180) << "Error closing" << name;
232 return false;
233 }
234 // Recurse!
235 //kDebug(180) << "RECURSE: " << newName;
236 if ( ! rmtree( newName ) )
237 return false;
238 // We have to re-open the directory before continuing
239 dp = ::opendir( name.data() );
240 if ( !dp )
241 return false;
242 }
243 if ( ::closedir( dp ) ) {
244 kDebug(180) << "Error closing" << name;
245 return false;
246 }
247 //kDebug(180) << "RMDIR dir " << name;
248 return ! ::rmdir( name );
249 }
250 else
251 {
252 // This is a non-directory file, so remove it
253 //kDebug(180) << "KTempDir: unlinking file" << name;
254 return ! ::unlink( name );
255 }
256}
257#endif
258
259bool KTempDir::removeDir( const QString& path )
260{
261 //kDebug(180) << path;
262 if ( !QFile::exists( path ) )
263 return true; // The goal is that there is no directory
264
265#ifdef Q_WS_WIN
266 QVarLengthArray<WCHAR, MAX_PATH> name;
267 name.resize( path.length() + 2 ); // double null terminated!
268 memcpy( name.data(), path.utf16(), path.length() * sizeof(WCHAR) );
269 name[path.length() ] = 0;
270 name[path.length() + 1 ] = 0;
271 if(path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\')))
272 name[path.length() - 1 ] = 0;
273 SHFILEOPSTRUCTW fileOp;
274 memset(&fileOp, 0, sizeof(SHFILEOPSTRUCTW) );
275 fileOp.wFunc = FO_DELETE;
276 fileOp.pFrom = (LPCWSTR)name.constData();
277 fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
278#ifdef _WIN32_WCE
279 // FOF_NOERRORUI is not defined in wince
280#else
281 fileOp.fFlags |= FOF_NOERRORUI;
282#endif
283 errno = SHFileOperationW( &fileOp );
284 return (errno == 0);
285#else
286 const QByteArray cstr( QFile::encodeName( path ) );
287 return rmtree( cstr );
288#endif
289}
290
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is much like locate.
Definition: kstandarddirs.cpp:2097
KTempDir::exists
bool exists() const
Returns true if a temporary directory has successfully been created and has not been unlinked yet.
Definition: ktempdir.cpp:173
KTempDir::name
QString name() const
Returns the full path and name of the directory, including a trailing '/'.
Definition: ktempdir.cpp:168
KTempDir::KTempDir
KTempDir(const QString &directoryPrefix=QString(), int mode=0700)
Creates a temporary directory with the name: <directoryPrefix><six letters>
Definition: ktempdir.cpp:80
KTempDir::removeDir
static bool removeDir(const QString &path)
Remove a directory and all its contents.
Definition: ktempdir.cpp:259
KTempDir::unlink
void unlink()
Deletes the directory recursively.
Definition: ktempdir.cpp:188
KTempDir::setAutoRemove
void setAutoRemove(bool autoRemove)
Turn automatic deletion of the directory on or off.
Definition: ktempdir.cpp:178
KTempDir::status
int status() const
Returns the status of the directory creation based on errno.
Definition: ktempdir.cpp:163
KTempDir::~KTempDir
~KTempDir()
The destructor deletes the directory and its contents if autoRemove is set to true.
Definition: ktempdir.cpp:154
KTempDir::create
bool create(const QString &directoryPrefix, int mode)
Creates a "random" directory with specified mode.
Definition: ktempdir.cpp:85
KTempDir::autoRemove
bool autoRemove() const
Definition: ktempdir.cpp:183
QString
kDebug
#define kDebug
Definition: kdebug.h:316
kWarning
#define kWarning
Definition: kdebug.h:322
kcomponentdata.h
kdebug.h
kglobal.h
krandom.h
kstandarddirs.h
mkdtemp_QString
QString mkdtemp_QString(const QString &_template)
Definition: kde_file_win.cpp:79
ktempdir.h
KDE::chmod
int chmod(const QString &path, mode_t mode)
Definition: kde_file_win.cpp:138
KGlobal::mainComponent
const KComponentData & mainComponent()
Returns the global component data.
Definition: kglobal.cpp:145
KGlobal::umask
mode_t umask()
Returns the umask of the process.
Definition: kglobal.cpp:224
KRandom::random
int random()
Generates a uniform random number.
Definition: krandom.cpp:32
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal