• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

ktempdir.cpp

Go to the documentation of this file.
00001 /* kate: tab-indents off; replace-tabs on; tab-width 4; remove-trailing-space on; encoding utf-8;*/
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (c) 2003 Joseph Wenninger <jowenn@kde.org>
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Library General Public
00008  *  License version 2 as published by the Free Software Foundation.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
00019  **/
00020 
00021 #include "ktempdir.h"
00022 
00023 #include <config.h>
00024 
00025 #include <sys/types.h>
00026 
00027 #ifdef HAVE_SYS_STAT_H
00028 #include <sys/stat.h>
00029 #endif
00030 
00031 #include <fcntl.h>
00032 #include <stdlib.h>
00033 #include <unistd.h>
00034 #include <errno.h>
00035 #include <dirent.h>
00036 
00037 #ifdef HAVE_TEST
00038 #include <test.h>
00039 #endif
00040 #ifdef HAVE_PATHS_H
00041 #include <paths.h>
00042 #endif
00043 
00044 #include <QtCore/QDir>
00045 
00046 #include "kglobal.h"
00047 #include "krandom.h"
00048 #include "kcomponentdata.h"
00049 #include "kstandarddirs.h"
00050 #include <kdebug.h>
00051 #include "kde_file.h"
00052 
00053 #ifdef Q_WS_WIN
00054 #include <QtCore/QVarLengthArray>
00055 #include <windows.h>
00056 #include <shellapi.h>
00057 extern QString mkdtemp_QString (const QString &_template);
00058 #endif
00059 
00060 class KTempDir::Private
00061 {
00062 public:
00063     int error;
00064     QString tmpName;
00065     bool exists;
00066     bool autoRemove;
00067 
00068     Private()
00069     {
00070         autoRemove = true;
00071         exists = false;
00072         error=0;
00073     }
00074 };
00075 
00076 KTempDir::KTempDir(const QString &directoryPrefix, int mode) : d(new Private)
00077 {
00078     (void) create( directoryPrefix.isEmpty() ? KStandardDirs::locateLocal("tmp", KGlobal::mainComponent().componentName()) : directoryPrefix , mode);
00079 }
00080 
00081 bool KTempDir::create(const QString &directoryPrefix, int mode)
00082 {
00083    (void) KRandom::random();
00084 
00085 #ifdef Q_WS_WIN
00086    const QString nme = directoryPrefix + "XXXXXX";
00087    const QString realName = mkdtemp_QString(nme);
00088    if(realName.isEmpty())
00089    {
00090        kWarning(180) << "KTempDir: Error trying to create " << nme
00091               << ": " << ::strerror(errno) << endl;
00092        d->error = errno;
00093        d->tmpName.clear();
00094        return false;
00095    }
00096 
00097    // got a return value != 0
00098    d->tmpName = realName + '/';
00099    kDebug(180) << "KTempDir: Temporary directory created :" << d->tmpName
00100             << endl;
00101    mode_t umsk = KGlobal::umask();
00102    KDE::chmod(nme, mode&(~umsk));
00103 
00104    // Success!
00105    d->exists = true;
00106 #else
00107    QByteArray nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
00108    char *realName;
00109    if((realName=mkdtemp(nme.data())) == 0)
00110    {
00111        // Recreate it for the warning, mkdtemps emptied it
00112        nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
00113        kWarning(180) << "KTempDir: Error trying to create " << nme.data()
00114               << ": " << ::strerror(errno) << endl;
00115        d->error = errno;
00116        d->tmpName.clear();
00117        return false;
00118    }
00119 
00120    // got a return value != 0
00121    QByteArray realNameStr(realName);
00122    d->tmpName = QFile::decodeName(realNameStr)+'/';
00123    kDebug(180) << "KTempDir: Temporary directory created :" << d->tmpName
00124             << endl;
00125    mode_t umsk = KGlobal::umask();
00126    chmod(nme, mode&(~umsk));
00127 
00128    // Success!
00129    d->exists = true;
00130 
00131    // Set uid/gid (necessary for SUID programs)
00132    chown(nme, getuid(), getgid());
00133 #endif
00134    return true;
00135 }
00136 
00137 KTempDir::~KTempDir()
00138 {
00139     if (d->autoRemove) {
00140         unlink();
00141     }
00142 
00143     delete d;
00144 }
00145 
00146 int KTempDir::status() const
00147 {
00148     return d->error;
00149 }
00150 
00151 QString KTempDir::name() const
00152 {
00153     return d->tmpName;
00154 }
00155 
00156 bool KTempDir::exists() const
00157 {
00158     return d->exists;
00159 }
00160 
00161 void KTempDir::setAutoRemove(bool autoRemove)
00162 {
00163     d->autoRemove = autoRemove;
00164 }
00165 
00166 bool KTempDir::autoRemove() const
00167 {
00168     return d->autoRemove;
00169 }
00170 
00171 void KTempDir::unlink()
00172 {
00173     if (!d->exists) return;
00174     if (KTempDir::removeDir(d->tmpName))
00175         d->error=0;
00176     else
00177         d->error=errno;
00178     d->exists=false;
00179 }
00180 
00181 #ifndef Q_WS_WIN
00182 // Auxiliary recursive function for removeDirs
00183 static bool rmtree(const QByteArray& name)
00184 {
00185     //kDebug(180) << "Checking directory for remove " << name;
00186     KDE_struct_stat st;
00187     if ( KDE_lstat( name.data(), &st ) == -1 ) // Do not dereference symlink!
00188         return false;
00189     if ( S_ISDIR( st.st_mode ) )
00190     {
00191         // This is a directory, so process it
00192         //kDebug(180) << "File " << name << " is DIRECTORY!";
00193         KDE_struct_dirent* ep;
00194         DIR* dp = ::opendir( name.data() );
00195         if ( !dp )
00196             return false;
00197         while ( ( ep = KDE_readdir( dp ) ) )
00198         {
00199             //kDebug(180) << "CHECKING " << name << "/" << ep->d_name;
00200             if ( !qstrcmp( ep->d_name, "." ) || !qstrcmp( ep->d_name, ".." ) )
00201                 continue;
00202             QByteArray newName( name );
00203             newName += '/';
00204             newName += ep->d_name;
00205             /*
00206              * Be defensive and close the directory.
00207              *
00208              * Potential problems:
00209              * - opendir/readdir/closedir is not re-entrant
00210              * - unlink and rmdir invalidates a opendir/readdir/closedir
00211              * - limited number of file descriptors for opendir/readdir/closedir
00212              */
00213             if ( ::closedir( dp ) )
00214                 return false;
00215             // Recurse!
00216             //kDebug(180) << "RECURSE: " << newName;
00217             if ( ! rmtree( newName ) )
00218                 return false;
00219             // We have to re-open the directory before continuing
00220             dp = ::opendir( name.data() );
00221             if ( !dp )
00222                 return false;
00223         }
00224         if ( ::closedir( dp ) )
00225             return false;
00226         //kDebug(180) << "RMDIR dir " << name;
00227         return ! ::rmdir( name );
00228     }
00229     else
00230     {
00231         // This is a non-directory file, so remove it
00232         kDebug(180) << "KTempDir: unlinking file " << name;
00233         return ! ::unlink( name );
00234     }
00235 }
00236 #endif
00237 
00238 bool KTempDir::removeDir( const QString& path )
00239 {
00240     kDebug(180) << " " << path;
00241     if ( !QFile::exists( path ) )
00242         return true; // The goal is that there is no directory
00243 
00244 #ifdef Q_WS_WIN
00245     QVarLengthArray<WCHAR, MAX_PATH> name;
00246     name.resize( path.length() + 2 ); // double null terminated!
00247     memcpy( name.data(), path.utf16(), path.length() * sizeof(WCHAR) );
00248     name[path.length()     ] = 0;
00249     name[path.length() + 1 ] = 0;
00250     if(path.endsWith('/') || path.endsWith('\\'))
00251       name[path.length() - 1 ] = 0;
00252     SHFILEOPSTRUCTW fileOp;
00253     memset(&fileOp, 0, sizeof(SHFILEOPSTRUCTW) );
00254     fileOp.wFunc = FO_DELETE;
00255     fileOp.pFrom = (LPCWSTR)name.constData();
00256     fileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
00257     errno = SHFileOperationW( &fileOp );
00258     return (errno == 0);
00259 #else
00260     const QByteArray cstr( QFile::encodeName( path ) );
00261     return rmtree( cstr );
00262 #endif
00263 }
00264 

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal