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

KDECore

ktempdir.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *  This file is part of the KDE libraries
00004  *  Copyright (c) 2003 Joseph Wenninger <jowenn@kde.org>
00005  *
00006  * $Id: ktempdir.cpp 532292 2006-04-21 15:19:53Z savernik $
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License version 2 as published by the Free Software Foundation.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Library General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Library General Public License
00018  *  along with this library; see the file COPYING.LIB.  If not, write to
00019  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  *  Boston, MA 02110-1301, USA.
00021  **/
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 <dirent.h>
00035 
00036 #ifdef HAVE_TEST
00037 #include <test.h>
00038 #endif
00039 #ifdef HAVE_PATHS_H
00040 #include <paths.h>
00041 #endif
00042 
00043 #ifndef _PATH_TMP
00044 #define _PATH_TMP "/tmp"
00045 #endif
00046 
00047 #include <qdatetime.h>
00048 #include <qdir.h>
00049 
00050 #include "kglobal.h"
00051 #include "kapplication.h"
00052 #include "kinstance.h"
00053 #include "ktempdir.h"
00054 #include "kstandarddirs.h"
00055 #include "kprocess.h"
00056 #include <kdebug.h>
00057 #include "kde_file.h"
00058 
00059 KTempDir::KTempDir(QString directoryPrefix, int mode)
00060 {
00061    bAutoDelete = false;
00062    bExisting = false;
00063    mError=0;
00064    if (directoryPrefix.isEmpty())
00065    {
00066       directoryPrefix = locateLocal("tmp", KGlobal::instance()->instanceName());
00067    }
00068    (void) create(directoryPrefix , mode);
00069 }
00070 
00071 bool
00072 KTempDir::create(const QString &directoryPrefix, int mode)
00073 {
00074    // make sure the random seed is randomized
00075    (void) KApplication::random();
00076 
00077    QCString nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
00078    char *realName;
00079    if((realName=mkdtemp(nme.data())) == 0)
00080    {
00081        // Recreate it for the warning, mkdtemps emptied it
00082        QCString nme = QFile::encodeName(directoryPrefix) + "XXXXXX";
00083        qWarning("KTempDir: Error trying to create %s: %s", nme.data(), strerror(errno));
00084        mError = errno;
00085        mTmpName = QString::null;
00086        return false;
00087    }
00088 
00089    // got a return value != 0
00090    QCString realNameStr(realName);
00091    mTmpName = QFile::decodeName(realNameStr)+"/";
00092    kdDebug(180) << "KTempDir: Temporary directory created :" << mTmpName << endl;
00093    mode_t tmp = 0;
00094    mode_t umsk = umask(tmp);
00095    umask(umsk);
00096    chmod(nme, mode&(~umsk));
00097 
00098    // Success!
00099    bExisting = true;
00100 
00101    // Set uid/gid (necessary for SUID programs)
00102    chown(nme, getuid(), getgid());
00103    return true;
00104 }
00105 
00106 KTempDir::~KTempDir()
00107 {
00108    if (bAutoDelete)
00109       unlink();
00110 
00111 // KTempDirPrivate doesn't exist, so it can't be deleted
00112 //   delete d;
00113 }
00114 
00115 int
00116 KTempDir::status() const
00117 {
00118    return mError;
00119 }
00120 
00121 QString
00122 KTempDir::name() const
00123 {
00124    return mTmpName;
00125 }
00126 
00127 bool
00128 KTempDir::existing() const
00129 {
00130    return bExisting;
00131 }
00132 
00133 QDir *
00134 KTempDir::qDir()
00135 {
00136    if (bExisting) return new QDir(mTmpName);
00137    return 0;
00138 }
00139 
00140 void
00141 KTempDir::unlink()
00142 {
00143    if (!bExisting) return;
00144    if (KTempDir::removeDir(mTmpName))
00145       mError=0;
00146    else
00147       mError=errno;
00148    bExisting=false;
00149 }
00150 
00151 // Auxiliary recursive function for removeDirs
00152 static bool
00153 rmtree(const QCString& name)
00154 {
00155     kdDebug() << "Checking directory for remove " << name << endl;
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         kdDebug() << "File " << name << " is DIRECTORY!" << endl;
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             kdDebug() << "CHECKING " << name << "/" << ep->d_name << endl;
00170             if ( !qstrcmp( ep->d_name, "." ) || !qstrcmp( ep->d_name, ".." ) )
00171                 continue;
00172             QCString newName( name );
00173             newName += "/"; // Careful: do not add '/' instead or you get problems with Qt3.
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             kdDebug() << "RECURSE: " << newName << endl;
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         kdDebug() << "RMDIR dir " << name << endl;
00197         return ! ::rmdir( name );
00198     }
00199     else
00200     {
00201          // This is a non-directory file, so remove it
00202          kdDebug() << "UNLINKING file " << name << endl;
00203          return ! ::unlink( name );
00204     }
00205 }
00206 
00207 bool
00208 KTempDir::removeDir(const QString& path)
00209 {
00210     kdDebug() << k_funcinfo << " " << path << endl;
00211     if ( !QFile::exists( path ) )
00212         return true; // The goal is that there is no directory
00213 
00214     const QCString cstr( QFile::encodeName( path ) );
00215     return rmtree( cstr );
00216 }
00217 
00218 

KDECore

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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