tdecore
tdetempfile.cpp
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 <tqdatetime.h>
00047 #include <tqfile.h>
00048 #include <tqdatastream.h>
00049 #include <tqtextstream.h>
00050
00051 #include "tdeglobal.h"
00052 #include "tdeapplication.h"
00053 #include "kinstance.h"
00054 #include "tdetempfile.h"
00055 #include "kstandarddirs.h"
00056 #include "kde_file.h"
00057 #include "kdebug.h"
00058
00059
00060 KTempFile::KTempFile(TQString filePrefix, TQString 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", TDEGlobal::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 TQString &filePrefix, const TQString &fileExtension,
00093 int mode)
00094 {
00095
00096 (void) TDEApplication::random();
00097
00098 TQCString ext = TQFile::encodeName(fileExtension);
00099 TQCString nme = TQFile::encodeName(filePrefix) + "XXXXXX" + ext;
00100 if((mFd = mkstemps(nme.data(), ext.length())) < 0)
00101 {
00102
00103 TQCString nme = TQFile::encodeName(filePrefix) + "XXXXXX" + ext;
00104 kdWarning() << "KTempFile: Error trying to create " << nme << ": " << strerror(errno) << endl;
00105 mError = errno;
00106 mTmpName = TQString::null;
00107 return false;
00108 }
00109
00110
00111 mTmpName = TQFile::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 uid_t uid = getuid();
00121 uid_t euid = geteuid();
00122 if (uid != euid) {
00123
00124 fchown(mFd, getuid(), getgid());
00125 }
00126
00127
00128 fcntl(mFd, F_SETFD, FD_CLOEXEC);
00129
00130 return true;
00131 }
00132
00133 KTempFile::~KTempFile()
00134 {
00135 close();
00136 if (bAutoDelete)
00137 unlink();
00138 }
00139
00140 int
00141 KTempFile::status() const
00142 {
00143 return mError;
00144 }
00145
00146 TQString
00147 KTempFile::name() const
00148 {
00149 return mTmpName;
00150 }
00151
00152 int
00153 KTempFile::handle() const
00154 {
00155 return mFd;
00156 }
00157
00158 FILE *
00159 KTempFile::fstream()
00160 {
00161 if (mStream) return mStream;
00162 if (mFd < 0) return 0;
00163
00164
00165 mStream = KDE_fdopen(mFd, "r+");
00166 if (!mStream) {
00167 kdWarning() << "KTempFile: Error trying to open " << mTmpName << ": " << strerror(errno) << endl;
00168 mError = errno;
00169 }
00170 return mStream;
00171 }
00172
00173 TQFile *
00174 KTempFile::file()
00175 {
00176 if (mFile) return mFile;
00177 if ( !fstream() ) return 0;
00178
00179 mFile = new TQFile();
00180 mFile->setName( name() );
00181 mFile->open(IO_ReadWrite, mStream);
00182 return mFile;
00183 }
00184
00185 TQTextStream *
00186 KTempFile::textStream()
00187 {
00188 if (mTextStream) return mTextStream;
00189 if ( !file() ) return 0;
00190
00191 mTextStream = new TQTextStream( mFile );
00192 return mTextStream;
00193 }
00194
00195 TQDataStream *
00196 KTempFile::dataStream()
00197 {
00198 if (mDataStream) return mDataStream;
00199 if ( !file() ) return 0;
00200
00201 mDataStream = new TQDataStream( mFile );
00202 return mDataStream;
00203 }
00204
00205 void
00206 KTempFile::unlink()
00207 {
00208 if (!mTmpName.isEmpty())
00209 TQFile::remove( mTmpName );
00210 mTmpName = TQString::null;
00211 }
00212
00213 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
00214 #define FDATASYNC fdatasync
00215 #else
00216 #define FDATASYNC fsync
00217 #endif
00218
00219 bool
00220 KTempFile::sync()
00221 {
00222 int result = 0;
00223
00224 if (mStream)
00225 {
00226 do {
00227 result = fflush(mStream);
00228 }
00229 while ((result == -1) && (errno == EINTR));
00230
00231 if (result)
00232 {
00233 kdWarning() << "KTempFile: Error trying to flush " << mTmpName << ": " << strerror(errno) << endl;
00234 mError = errno;
00235 }
00236 }
00237
00238 if (mFd >= 0)
00239 {
00240 if( qstrcmp( getenv( "TDE_EXTRA_FSYNC" ), "1" ) == 0 )
00241 {
00242 result = FDATASYNC(mFd);
00243 if (result)
00244 {
00245 kdWarning() << "KTempFile: Error trying to sync " << mTmpName << ": " << strerror(errno) << endl;
00246 mError = errno;
00247 }
00248 }
00249 }
00250
00251 return (mError == 0);
00252 }
00253
00254 #undef FDATASYNC
00255
00256 bool
00257 KTempFile::close()
00258 {
00259 int result = 0;
00260 delete mTextStream; mTextStream = 0;
00261 delete mDataStream; mDataStream = 0;
00262 delete mFile; mFile = 0;
00263
00264 if (mStream)
00265 {
00266 result = ferror(mStream);
00267 if (result)
00268 mError = ENOSPC;
00269
00270 result = fclose(mStream);
00271 mStream = 0;
00272 mFd = -1;
00273 if (result != 0) {
00274 kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
00275 mError = errno;
00276 }
00277 }
00278
00279
00280 if (mFd >= 0)
00281 {
00282 result = ::close(mFd);
00283 mFd = -1;
00284 if (result != 0) {
00285 kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
00286 mError = errno;
00287 }
00288 }
00289
00290 bOpen = false;
00291 return (mError == 0);
00292 }
00293