ktempfile.cpp00001
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(), (uid_t) -1);
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 result = FDATASYNC(mFd);
00237 if (result)
00238 {
00239 kdWarning() << "KTempFile: Error trying to sync " << mTmpName << ": " << strerror(errno) << endl;
00240 mError = errno;
00241 }
00242 }
00243
00244 return (mError == 0);
00245 }
00246
00247 #undef FDATASYNC
00248
00249 bool
00250 KTempFile::close()
00251 {
00252 int result = 0;
00253 delete mTextStream; mTextStream = 0;
00254 delete mDataStream; mDataStream = 0;
00255 delete mFile; mFile = 0;
00256
00257 if (mStream)
00258 {
00259 result = ferror(mStream);
00260 if (result)
00261 mError = ENOSPC;
00262
00263 result = fclose(mStream);
00264 mStream = 0;
00265 mFd = -1;
00266 if (result != 0) {
00267 kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
00268 mError = errno;
00269 }
00270 }
00271
00272
00273 if (mFd >= 0)
00274 {
00275 result = ::close(mFd);
00276 mFd = -1;
00277 if (result != 0) {
00278 kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
00279 mError = errno;
00280 }
00281 }
00282
00283 bOpen = false;
00284 return (mError == 0);
00285 }
00286
|