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

KDE3Support

k3tempfile.cpp

Go to the documentation of this file.
00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (c) 1999 Waldo Bastian <bastian@kde.org>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License version 2 as published by the Free Software Foundation.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Library General Public License
00015  *  along with this library; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  *  Boston, MA 02110-1301, USA.
00018  **/
00019 
00020 #include "k3tempfile.h"
00021 
00022 #include <config.h>
00023 
00024 #include <sys/types.h>
00025 
00026 #ifdef HAVE_SYS_STAT_H
00027 #include <sys/stat.h>
00028 #endif
00029 
00030 #include <fcntl.h>
00031 #include <stdlib.h>
00032 #include <unistd.h>
00033 #include <errno.h>
00034 
00035 #ifdef HAVE_TEST
00036 #include <test.h>
00037 #endif
00038 #ifdef HAVE_PATHS_H
00039 #include <paths.h>
00040 #endif
00041 
00042 #ifndef _PATH_TMP
00043 #define _PATH_TMP "/tmp"
00044 #endif
00045 
00046 #include <QtCore/QCharRef>
00047 #include <QtCore/QDate>
00048 #include <QtCore/QFile>
00049 #include <QtCore/QDataStream>
00050 #include <QtCore/QTextIStream>
00051 
00052 #include "kglobal.h"
00053 #include "krandom.h"
00054 #include "kcomponentdata.h"
00055 #include "kstandarddirs.h"
00056 #include "kde_file.h"
00057 #include "kdebug.h"
00058 
00059 class K3TempFile::Private
00060 {
00061 public:
00062    int _Error;
00063 #define mError d->_Error
00064    QString _TmpName;
00065 #define mTmpName d->_TmpName
00066    int _Fd;
00067 #define mFd d->_Fd
00068    FILE *_Stream;
00069 #define mStream d->_Stream
00070    QFile *_File;
00071 #define mFile d->_File
00072    QTextStream *_TextStream;
00073 #define mTextStream d->_TextStream
00074    QDataStream *_DataStream;
00075 #define mDataStream d->_DataStream
00076    bool _Open;
00077 #define bOpen d->_Open
00078    bool _AutoDelete;
00079 #define bAutoDelete d->_AutoDelete
00080 };
00081 
00082 K3TempFile::K3TempFile(const QString& filePrefix,
00083                      const QString& fileExtension, int mode)
00084  : d(new Private)
00085 {
00086    bAutoDelete = false;
00087    mFd = -1;
00088    mStream = 0;
00089    mFile = 0;
00090    mTextStream = 0;
00091    mDataStream = 0;
00092    mError = 0;
00093    bOpen = false;
00094    QString extension = fileExtension;
00095    QString prefix = filePrefix;
00096    if (extension.isEmpty())
00097       extension = QLatin1String(".tmp");
00098    if (prefix.isEmpty())
00099    {
00100       prefix = KStandardDirs::locateLocal("tmp", KGlobal::mainComponent().componentName());
00101    }
00102    (void) create(prefix, extension, mode);
00103 }
00104 
00105 K3TempFile::K3TempFile(bool):d(new Private)
00106 {
00107    bAutoDelete = false;
00108    mFd = -1;
00109    mStream = 0;
00110    mFile = 0;
00111    mTextStream = 0;
00112    mDataStream = 0;
00113    mError = 0;
00114    bOpen = false;
00115 }
00116 
00117 bool
00118 K3TempFile::create(const QString &filePrefix, const QString &fileExtension,
00119           int mode)
00120 {
00121    // make sure the random seed is randomized
00122    (void) KRandom::random();
00123 
00124    QByteArray ext = QFile::encodeName(fileExtension);
00125    QByteArray nme = QFile::encodeName(filePrefix) + "XXXXXX" + ext;
00126    if((mFd = mkstemps(nme.data(), ext.length())) < 0)
00127    {
00128        // Recreate it for the warning, mkstemps emptied it
00129        nme = QFile::encodeName(filePrefix) + "XXXXXX" + ext;
00130        kWarning() << "K3TempFile: Error trying to create " << nme << ": " << strerror(errno);
00131        mError = errno;
00132        mTmpName.clear();
00133        return false;
00134    }
00135 
00136    // got a file descriptor. nme contains the name
00137    mTmpName = QFile::decodeName(nme);
00138    mode_t tmp = 0;
00139    mode_t umsk = umask(tmp);
00140    umask(umsk);
00141    fchmod(mFd, mode&(~umsk));
00142 
00143    // Success!
00144    bOpen = true;
00145 
00146    // Set uid/gid (necessary for SUID programs)
00147    fchown(mFd, getuid(), getgid());
00148 
00149 #ifndef Q_WS_WIN
00150    // Set close on exec
00151    fcntl(mFd, F_SETFD, FD_CLOEXEC);
00152 #endif
00153    return true;
00154 }
00155 
00156 K3TempFile::~K3TempFile()
00157 {
00158    close();
00159    if (bAutoDelete)
00160       unlink();
00161    delete d;
00162 }
00163 
00164 int
00165 K3TempFile::status() const
00166 {
00167    return mError;
00168 }
00169 
00170 QString
00171 K3TempFile::name() const
00172 {
00173    return mTmpName;
00174 }
00175 
00176 int
00177 K3TempFile::handle() const
00178 {
00179    return mFd;
00180 }
00181 
00182 FILE *
00183 K3TempFile::fstream()
00184 {
00185    if (mStream) return mStream;
00186    if (mFd < 0) return 0;
00187 
00188    // Create a stream
00189    mStream = KDE_fdopen(mFd, "r+");
00190    if (!mStream) {
00191      kWarning() << "K3TempFile: Error trying to open " << mTmpName << ": " << strerror(errno);
00192      mError = errno;
00193    }
00194    return mStream;
00195 }
00196 
00197 QFile *
00198 K3TempFile::file()
00199 {
00200    if (mFile) return mFile;
00201    if ( !fstream() ) return 0;
00202 
00203    mFile = new QFile();
00204    mFile->setFileName( name() );
00205    mFile->open(mStream, QIODevice::ReadWrite);
00206    return mFile;
00207 }
00208 
00209 QTextStream *
00210 K3TempFile::textStream()
00211 {
00212    if (mTextStream) return mTextStream;
00213    if ( !file() ) return 0; // Initialize mFile
00214 
00215    mTextStream = new QTextStream( mFile );
00216    return mTextStream;
00217 }
00218 
00219 QDataStream *
00220 K3TempFile::dataStream()
00221 {
00222    if (mDataStream) return mDataStream;
00223    if ( !file() ) return 0;  // Initialize mFile
00224 
00225    mDataStream = new QDataStream( mFile );
00226    return mDataStream;
00227 }
00228 
00229 void
00230 K3TempFile::unlink()
00231 {
00232    if (!mTmpName.isEmpty())
00233       QFile::remove( mTmpName );
00234    mTmpName.clear();
00235 }
00236 
00237 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
00238 #define FDATASYNC fdatasync
00239 #else
00240 #define FDATASYNC fsync
00241 #endif
00242 
00243 bool
00244 K3TempFile::sync()
00245 {
00246    int result = 0;
00247 
00248    if (mStream)
00249    {
00250       do {
00251          result = fflush(mStream); // We need to flush first otherwise fsync may not have our data
00252       }
00253       while ((result == -1) && (errno == EINTR));
00254 
00255       if (result)
00256       {
00257          kWarning() << "K3TempFile: Error trying to flush " << mTmpName << ": " << strerror(errno);
00258          mError = errno;
00259       }
00260    }
00261 
00262    if (mFd >= 0)
00263    {
00264       if( qgetenv( "KDE_EXTRA_FSYNC" ) == "1" )
00265       {
00266          result = FDATASYNC(mFd);
00267          if (result)
00268          {
00269             kWarning() << "K3TempFile: Error trying to sync " << mTmpName << ": " << strerror(errno);
00270             mError = errno;
00271          }
00272       }
00273    }
00274 
00275    return (mError == 0);
00276 }
00277 
00278 #undef FDATASYNC
00279 
00280 bool
00281 K3TempFile::close()
00282 {
00283    int result = 0;
00284    delete mTextStream; mTextStream = 0;
00285    delete mDataStream; mDataStream = 0;
00286    delete mFile; mFile = 0;
00287 
00288    if (mStream)
00289    {
00290       result = ferror(mStream);
00291       if (result)
00292          mError = ENOSPC; // Assume disk full.
00293 
00294       result = fclose(mStream);
00295       mStream = 0;
00296       mFd = -1;
00297       if (result != 0) {
00298          kWarning() << "K3TempFile: Error trying to close " << mTmpName << ": " << strerror(errno);
00299          mError = errno;
00300       }
00301    }
00302 
00303 
00304    if (mFd >= 0)
00305    {
00306       result = ::close(mFd);
00307       mFd = -1;
00308       if (result != 0) {
00309          kWarning() << "K3TempFile: Error trying to close " << mTmpName << ": " << strerror(errno);
00310          mError = errno;
00311       }
00312    }
00313 
00314    bOpen = false;
00315    return (mError == 0);
00316 }
00317 
00318 void
00319 K3TempFile::setAutoDelete(bool autoDelete)
00320 {
00321    bAutoDelete = autoDelete;
00322 }
00323 
00324 void
00325 K3TempFile::setError(int error)
00326 {
00327    mError = error;
00328 }
00329 
00330 bool
00331 K3TempFile::isOpen() const
00332 {
00333    return bOpen;
00334 }
00335 
00336 #undef mError
00337 #undef mTmpName
00338 #undef mFd
00339 #undef mStream
00340 #undef mFile
00341 #undef mTextStream
00342 #undef mDataStream
00343 #undef bOpen
00344 #undef bAutoDelete

KDE3Support

Skip menu "KDE3Support"
  • Main Page
  • 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