• Skip to content
  • Skip to link menu
KDE 4.1 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 class KTempDir::Private
00054 {
00055 public:
00056     int error;
00057     QString tmpName;
00058     bool exists;
00059     bool autoRemove;
00060 
00061     Private()
00062     {
00063         autoRemove = true;
00064         exists = false;
00065         error=0;
00066     }
00067 };
00068 
00069 KTempDir::KTempDir(const QString &directoryPrefix, int mode) : d(new Private)
00070 {
00071     (void) create( directoryPrefix.isEmpty() ? KStandardDirs::locateLocal("tmp", KGlobal::mainComponent().componentName()) : directoryPrefix , mode);
00072 }
00073 
00074 bool KTempDir::create(const QString &directoryPrefix, int mode)
00075 {
00076    // make sure the random seed is randomized
00077    (void) KRandom::random();
00078 
00079    QByteArray nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
00080    char *realName;
00081    if((realName=mkdtemp(nme.data())) == 0)
00082    {
00083        // Recreate it for the warning, mkdtemps emptied it
00084        nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
00085        kWarning(180) << "KTempDir: Error trying to create " << nme.data()
00086               << ": " << ::strerror(errno) << endl;
00087        d->error = errno;
00088        d->tmpName.clear();
00089        return false;
00090    }
00091 
00092    // got a return value != 0
00093    QByteArray realNameStr(realName);
00094    d->tmpName = QFile::decodeName(realNameStr)+'/';
00095    kDebug(180) << "KTempDir: Temporary directory created :" << d->tmpName
00096             << endl;
00097    mode_t umsk = KGlobal::umask();
00098    chmod(nme, mode&(~umsk));
00099 
00100    // Success!
00101    d->exists = true;
00102 
00103    // Set uid/gid (necessary for SUID programs)
00104    chown(nme, getuid(), getgid());
00105    return true;
00106 }
00107 
00108 KTempDir::~KTempDir()
00109 {
00110     if (d->autoRemove) {
00111         unlink();
00112     }
00113 
00114     delete d;
00115 }
00116 
00117 int KTempDir::status() const
00118 {
00119     return d->error;
00120 }
00121 
00122 QString KTempDir::name() const
00123 {
00124     return d->tmpName;
00125 }
00126 
00127 bool KTempDir::exists() const
00128 {
00129     return d->exists;
00130 }
00131 
00132 void KTempDir::setAutoRemove(bool autoRemove)
00133 {
00134     d->autoRemove = autoRemove;
00135 }
00136 
00137 bool KTempDir::autoRemove() const
00138 {
00139     return d->autoRemove;
00140 }
00141 
00142 void KTempDir::unlink()
00143 {
00144     if (!d->exists) return;
00145     if (KTempDir::removeDir(d->tmpName))
00146         d->error=0;
00147     else
00148         d->error=errno;
00149     d->exists=false;
00150 }
00151 
00152 // Auxiliary recursive function for removeDirs
00153 static bool rmtree(const QByteArray& name)
00154 {
00155     //kDebug(180) << "Checking directory for remove " << name;
00156     KDE_struct_stat st;
00157     if ( KDE_lstat( name.data(), &st ) == -1 ) // Do not dereference symlink!
00158         return false;
00159     if ( S_ISDIR( st.st_mode ) )
00160     {
00161         // This is a directory, so process it
00162         //kDebug(180) << "File " << name << " is DIRECTORY!";
00163         KDE_struct_dirent* ep;
00164         DIR* dp = ::opendir( name.data() );
00165         if ( !dp )
00166             return false;
00167         while ( ( ep = KDE_readdir( dp ) ) )
00168         {
00169             //kDebug(180) << "CHECKING " << name << "/" << ep->d_name;
00170             if ( !qstrcmp( ep->d_name, "." ) || !qstrcmp( ep->d_name, ".." ) )
00171                 continue;
00172             QByteArray newName( name );
00173             newName += '/';
00174             newName += ep->d_name;
00175             /*
00176              * Be defensive and close the directory.
00177              *
00178              * Potential problems:
00179              * - opendir/readdir/closedir is not re-entrant
00180              * - unlink and rmdir invalidates a opendir/readdir/closedir
00181              * - limited number of file descriptors for opendir/readdir/closedir
00182              */
00183             if ( ::closedir( dp ) )
00184                 return false;
00185             // Recurse!
00186             //kDebug(180) << "RECURSE: " << newName;
00187             if ( ! rmtree( newName ) )
00188                 return false;
00189             // We have to re-open the directory before continuing
00190             dp = ::opendir( name.data() );
00191             if ( !dp )
00192                 return false;
00193         }
00194         if ( ::closedir( dp ) )
00195             return false;
00196         //kDebug(180) << "RMDIR dir " << name;
00197         return ! ::rmdir( name );
00198     }
00199     else
00200     {
00201         // This is a non-directory file, so remove it
00202         kDebug(180) << "KTempDir: unlinking file " << name;
00203         return ! ::unlink( name );
00204     }
00205 }
00206 
00207 bool KTempDir::removeDir( const QString& path )
00208 {
00209     kDebug(180) << " " << path;
00210     if ( !QFile::exists( path ) )
00211         return true; // The goal is that there is no directory
00212 
00213     const QByteArray cstr( QFile::encodeName( path ) );
00214     return rmtree( cstr );
00215 }
00216 

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
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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