KDECore
ktempfile.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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 <qdatetime.h>
00047 #include <qfile.h>
00048 #include <qdatastream.h>
00049 #include <qtextstream.h>
00050
00051 #include "kglobal.h"
00052 #include "kapplication.h"
00053 #include "kinstance.h"
00054 #include "ktempfile.h"
00055 #include "kstandarddirs.h"
00056 #include "kde_file.h"
00057 #include "kdebug.h"
00058
00059
00060 KTempFile::KTempFile(QString filePrefix, QString fileExtension, int mode)
00061 {
00062 bAutoDelete = false;
00063 mFd = -1;
00064 mStream = 0;
00065 mFile = 0;
00066 mTextStream = 0;
00067 mDataStream = 0;
00068 mError = 0;
00069 bOpen = false;
00070 if (fileExtension.isEmpty())
00071 fileExtension = ".tmp";
00072 if (filePrefix.isEmpty())
00073 {
00074 filePrefix = locateLocal("tmp", KGlobal::instance()->instanceName());
00075 }
00076 (void) create(filePrefix, fileExtension, mode);
00077 }
00078
00079 KTempFile::KTempFile(bool)
00080 {
00081 bAutoDelete = false;
00082 mFd = -1;
00083 mStream = 0;
00084 mFile = 0;
00085 mTextStream = 0;
00086 mDataStream = 0;
00087 mError = 0;
00088 bOpen = false;
00089 }
00090
00091 bool
00092 KTempFile::create(const QString &filePrefix, const QString &fileExtension,
00093 int mode)
00094 {
00095
00096 (void) KApplication::random();
00097
00098 QCString ext = QFile::encodeName(fileExtension);
00099 QCString nme = QFile::encodeName(filePrefix) + "XXXXXX" + ext;
00100 if((mFd = mkstemps(nme.data(), ext.length())) < 0)
00101 {
00102
00103 QCString nme = QFile::encodeName(filePrefix) + "XXXXXX" + ext;
00104 kdWarning() << "KTempFile: Error trying to create " << nme << ": " << strerror(errno) << endl;
00105 mError = errno;
00106 mTmpName = QString::null;
00107 return false;
00108 }
00109
00110
00111 mTmpName = QFile::decodeName(nme);
00112 mode_t tmp = 0;
00113 mode_t umsk = umask(tmp);
00114 umask(umsk);
00115 fchmod(mFd, mode&(~umsk));
00116
00117
00118 bOpen = true;
00119
00120
00121 fchown(mFd, getuid(), getgid());
00122
00123
00124 fcntl(mFd, F_SETFD, FD_CLOEXEC);
00125
00126 return true;
00127 }
00128
00129 KTempFile::~KTempFile()
00130 {
00131 close();
00132 if (bAutoDelete)
00133 unlink();
00134 }
00135
00136 int
00137 KTempFile::status() const
00138 {
00139 return mError;
00140 }
00141
00142 QString
00143 KTempFile::name() const
00144 {
00145 return mTmpName;
00146 }
00147
00148 int
00149 KTempFile::handle() const
00150 {
00151 return mFd;
00152 }
00153
00154 FILE *
00155 KTempFile::fstream()
00156 {
00157 if (mStream) return mStream;
00158 if (mFd < 0) return 0;
00159
00160
00161 mStream = KDE_fdopen(mFd, "r+");
00162 if (!mStream) {
00163 kdWarning() << "KTempFile: Error trying to open " << mTmpName << ": " << strerror(errno) << endl;
00164 mError = errno;
00165 }
00166 return mStream;
00167 }
00168
00169 QFile *
00170 KTempFile::file()
00171 {
00172 if (mFile) return mFile;
00173 if ( !fstream() ) return 0;
00174
00175 mFile = new QFile();
00176 mFile->setName( name() );
00177 mFile->open(IO_ReadWrite, mStream);
00178 return mFile;
00179 }
00180
00181 QTextStream *
00182 KTempFile::textStream()
00183 {
00184 if (mTextStream) return mTextStream;
00185 if ( !file() ) return 0;
00186
00187 mTextStream = new QTextStream( mFile );
00188 return mTextStream;
00189 }
00190
00191 QDataStream *
00192 KTempFile::dataStream()
00193 {
00194 if (mDataStream) return mDataStream;
00195 if ( !file() ) return 0;
00196
00197 mDataStream = new QDataStream( mFile );
00198 return mDataStream;
00199 }
00200
00201 void
00202 KTempFile::unlink()
00203 {
00204 if (!mTmpName.isEmpty())
00205 QFile::remove( mTmpName );
00206 mTmpName = QString::null;
00207 }
00208
00209 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
00210 #define FDATASYNC fdatasync
00211 #else
00212 #define FDATASYNC fsync
00213 #endif
00214
00215 bool
00216 KTempFile::sync()
00217 {
00218 int result = 0;
00219
00220 if (mStream)
00221 {
00222 do {
00223 result = fflush(mStream);
00224 }
00225 while ((result == -1) && (errno == EINTR));
00226
00227 if (result)
00228 {
00229 kdWarning() << "KTempFile: Error trying to flush " << mTmpName << ": " << strerror(errno) << endl;
00230 mError = errno;
00231 }
00232 }
00233
00234 if (mFd >= 0)
00235 {
00236 if( qstrcmp( getenv( "KDE_EXTRA_FSYNC" ), "1" ) == 0 )
00237 {
00238 result = FDATASYNC(mFd);
00239 if (result)
00240 {
00241 kdWarning() << "KTempFile: Error trying to sync " << mTmpName << ": " << strerror(errno) << endl;
00242 mError = errno;
00243 }
00244 }
00245 }
00246
00247 return (mError == 0);
00248 }
00249
00250 #undef FDATASYNC
00251
00252 bool
00253 KTempFile::close()
00254 {
00255 int result = 0;
00256 delete mTextStream; mTextStream = 0;
00257 delete mDataStream; mDataStream = 0;
00258 delete mFile; mFile = 0;
00259
00260 if (mStream)
00261 {
00262 result = ferror(mStream);
00263 if (result)
00264 mError = ENOSPC;
00265
00266 result = fclose(mStream);
00267 mStream = 0;
00268 mFd = -1;
00269 if (result != 0) {
00270 kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
00271 mError = errno;
00272 }
00273 }
00274
00275
00276 if (mFd >= 0)
00277 {
00278 result = ::close(mFd);
00279 mFd = -1;
00280 if (result != 0) {
00281 kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
00282 mError = errno;
00283 }
00284 }
00285
00286 bOpen = false;
00287 return (mError == 0);
00288 }
00289