• Skip to content
  • Skip to link menu
KDE 4.3 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_PATHS_H
00036 #include <paths.h>
00037 #endif
00038 
00039 #ifndef _PATH_TMP
00040 #define _PATH_TMP "/tmp"
00041 #endif
00042 
00043 #include <QtCore/QCharRef>
00044 #include <QtCore/QDate>
00045 #include <QtCore/QFile>
00046 #include <QtCore/QDataStream>
00047 #include <QtCore/QTextIStream>
00048 
00049 #include "kglobal.h"
00050 #include "krandom.h"
00051 #include "kcomponentdata.h"
00052 #include "kstandarddirs.h"
00053 #include "kde_file.h"
00054 #include "kdebug.h"
00055 
00056 class K3TempFile::Private
00057 {
00058 public:
00059    int _Error;
00060 #define mError d->_Error
00061    QString _TmpName;
00062 #define mTmpName d->_TmpName
00063    int _Fd;
00064 #define mFd d->_Fd
00065    FILE *_Stream;
00066 #define mStream d->_Stream
00067    QFile *_File;
00068 #define mFile d->_File
00069    QTextStream *_TextStream;
00070 #define mTextStream d->_TextStream
00071    QDataStream *_DataStream;
00072 #define mDataStream d->_DataStream
00073    bool _Open;
00074 #define bOpen d->_Open
00075    bool _AutoDelete;
00076 #define bAutoDelete d->_AutoDelete
00077 };
00078 
00079 K3TempFile::K3TempFile(const QString& filePrefix,
00080                      const QString& fileExtension, int mode)
00081  : d(new Private)
00082 {
00083    bAutoDelete = false;
00084    mFd = -1;
00085    mStream = 0;
00086    mFile = 0;
00087    mTextStream = 0;
00088    mDataStream = 0;
00089    mError = 0;
00090    bOpen = false;
00091    QString extension = fileExtension;
00092    QString prefix = filePrefix;
00093    if (extension.isEmpty())
00094       extension = QLatin1String(".tmp");
00095    if (prefix.isEmpty())
00096    {
00097       prefix = KStandardDirs::locateLocal("tmp", KGlobal::mainComponent().componentName());
00098    }
00099    (void) create(prefix, extension, mode);
00100 }
00101 
00102 K3TempFile::K3TempFile(bool):d(new Private)
00103 {
00104    bAutoDelete = false;
00105    mFd = -1;
00106    mStream = 0;
00107    mFile = 0;
00108    mTextStream = 0;
00109    mDataStream = 0;
00110    mError = 0;
00111    bOpen = false;
00112 }
00113 
00114 bool
00115 K3TempFile::create(const QString &filePrefix, const QString &fileExtension,
00116           int mode)
00117 {
00118    // make sure the random seed is randomized
00119    (void) KRandom::random();
00120 
00121    QByteArray ext = QFile::encodeName(fileExtension);
00122    QByteArray nme = QFile::encodeName(filePrefix) + "XXXXXX" + ext;
00123    if((mFd = mkstemps(nme.data(), ext.length())) < 0)
00124    {
00125        // Recreate it for the warning, mkstemps emptied it
00126        nme = QFile::encodeName(filePrefix) + "XXXXXX" + ext;
00127        kWarning() << "K3TempFile: Error trying to create " << nme << ": " << strerror(errno);
00128        mError = errno;
00129        mTmpName.clear();
00130        return false;
00131    }
00132 
00133    // got a file descriptor. nme contains the name
00134    mTmpName = QFile::decodeName(nme);
00135    mode_t tmp = 0;
00136    mode_t umsk = umask(tmp);
00137    umask(umsk);
00138    fchmod(mFd, mode&(~umsk));
00139 
00140    // Success!
00141    bOpen = true;
00142 
00143    // Set uid/gid (necessary for SUID programs)
00144    fchown(mFd, getuid(), getgid());
00145 
00146 #ifndef Q_WS_WIN
00147    // Set close on exec
00148    fcntl(mFd, F_SETFD, FD_CLOEXEC);
00149 #endif
00150    return true;
00151 }
00152 
00153 K3TempFile::~K3TempFile()
00154 {
00155    close();
00156    if (bAutoDelete)
00157       unlink();
00158    delete d;
00159 }
00160 
00161 int
00162 K3TempFile::status() const
00163 {
00164    return mError;
00165 }
00166 
00167 QString
00168 K3TempFile::name() const
00169 {
00170    return mTmpName;
00171 }
00172 
00173 int
00174 K3TempFile::handle() const
00175 {
00176    return mFd;
00177 }
00178 
00179 FILE *
00180 K3TempFile::fstream()
00181 {
00182    if (mStream) return mStream;
00183    if (mFd < 0) return 0;
00184 
00185    // Create a stream
00186    mStream = KDE_fdopen(mFd, "r+");
00187    if (!mStream) {
00188      kWarning() << "K3TempFile: Error trying to open " << mTmpName << ": " << strerror(errno);
00189      mError = errno;
00190    }
00191    return mStream;
00192 }
00193 
00194 QFile *
00195 K3TempFile::file()
00196 {
00197    if (mFile) return mFile;
00198    if ( !fstream() ) return 0;
00199 
00200    mFile = new QFile();
00201    mFile->setFileName( name() );
00202    mFile->open(mStream, QIODevice::ReadWrite);
00203    return mFile;
00204 }
00205 
00206 QTextStream *
00207 K3TempFile::textStream()
00208 {
00209    if (mTextStream) return mTextStream;
00210    if ( !file() ) return 0; // Initialize mFile
00211 
00212    mTextStream = new QTextStream( mFile );
00213    return mTextStream;
00214 }
00215 
00216 QDataStream *
00217 K3TempFile::dataStream()
00218 {
00219    if (mDataStream) return mDataStream;
00220    if ( !file() ) return 0;  // Initialize mFile
00221 
00222    mDataStream = new QDataStream( mFile );
00223    return mDataStream;
00224 }
00225 
00226 void
00227 K3TempFile::unlink()
00228 {
00229    if (!mTmpName.isEmpty())
00230       QFile::remove( mTmpName );
00231    mTmpName.clear();
00232 }
00233 
00234 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
00235 #define FDATASYNC fdatasync
00236 #else
00237 #define FDATASYNC fsync
00238 #endif
00239 
00240 bool
00241 K3TempFile::sync()
00242 {
00243    int result = 0;
00244 
00245    if (mStream)
00246    {
00247       do {
00248          result = fflush(mStream); // We need to flush first otherwise fsync may not have our data
00249       }
00250       while ((result == -1) && (errno == EINTR));
00251 
00252       if (result)
00253       {
00254          kWarning() << "K3TempFile: Error trying to flush " << mTmpName << ": " << strerror(errno);
00255          mError = errno;
00256       }
00257    }
00258 
00259    if (mFd >= 0)
00260    {
00261       if( qgetenv( "KDE_EXTRA_FSYNC" ) == "1" )
00262       {
00263          result = FDATASYNC(mFd);
00264          if (result)
00265          {
00266             kWarning() << "K3TempFile: Error trying to sync " << mTmpName << ": " << strerror(errno);
00267             mError = errno;
00268          }
00269       }
00270    }
00271 
00272    return (mError == 0);
00273 }
00274 
00275 #undef FDATASYNC
00276 
00277 bool
00278 K3TempFile::close()
00279 {
00280    int result = 0;
00281    delete mTextStream; mTextStream = 0;
00282    delete mDataStream; mDataStream = 0;
00283    delete mFile; mFile = 0;
00284 
00285    if (mStream)
00286    {
00287       result = ferror(mStream);
00288       if (result)
00289          mError = ENOSPC; // Assume disk full.
00290 
00291       result = fclose(mStream);
00292       mStream = 0;
00293       mFd = -1;
00294       if (result != 0) {
00295          kWarning() << "K3TempFile: Error trying to close " << mTmpName << ": " << strerror(errno);
00296          mError = errno;
00297       }
00298    }
00299 
00300 
00301    if (mFd >= 0)
00302    {
00303       result = ::close(mFd);
00304       mFd = -1;
00305       if (result != 0) {
00306          kWarning() << "K3TempFile: Error trying to close " << mTmpName << ": " << strerror(errno);
00307          mError = errno;
00308       }
00309    }
00310 
00311    bOpen = false;
00312    return (mError == 0);
00313 }
00314 
00315 void
00316 K3TempFile::setAutoDelete(bool autoDelete)
00317 {
00318    bAutoDelete = autoDelete;
00319 }
00320 
00321 void
00322 K3TempFile::setError(int error)
00323 {
00324    mError = error;
00325 }
00326 
00327 bool
00328 K3TempFile::isOpen() const
00329 {
00330    return bOpen;
00331 }
00332 
00333 #undef mError
00334 #undef mTmpName
00335 #undef mFd
00336 #undef mStream
00337 #undef mFile
00338 #undef mTextStream
00339 #undef mDataStream
00340 #undef bOpen
00341 #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
  • 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