summaryrefslogtreecommitdiffstats
path: root/tdecore/tdetempfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdecore/tdetempfile.cpp')
-rw-r--r--tdecore/tdetempfile.cpp293
1 files changed, 293 insertions, 0 deletions
diff --git a/tdecore/tdetempfile.cpp b/tdecore/tdetempfile.cpp
new file mode 100644
index 000000000..805d315a1
--- /dev/null
+++ b/tdecore/tdetempfile.cpp
@@ -0,0 +1,293 @@
+/*
+ *
+ * This file is part of the KDE libraries
+ * Copyright (c) 1999 Waldo Bastian <bastian@kde.org>
+ *
+ * $Id$
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_TEST
+#include <test.h>
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#ifndef _PATH_TMP
+#define _PATH_TMP "/tmp"
+#endif
+
+#include <tqdatetime.h>
+#include <tqfile.h>
+#include <tqdatastream.h>
+#include <tqtextstream.h>
+
+#include "tdeglobal.h"
+#include "tdeapplication.h"
+#include "kinstance.h"
+#include "tdetempfile.h"
+#include "kstandarddirs.h"
+#include "kde_file.h"
+#include "kdebug.h"
+
+/* antlarr: KDE 4: make the parameters const TQString & */
+KTempFile::KTempFile(TQString filePrefix, TQString fileExtension, int mode)
+{
+ bAutoDelete = false;
+ mFd = -1;
+ mStream = 0;
+ mFile = 0;
+ mTextStream = 0;
+ mDataStream = 0;
+ mError = 0;
+ bOpen = false;
+ if (fileExtension.isEmpty())
+ fileExtension = ".tmp";
+ if (filePrefix.isEmpty())
+ {
+ filePrefix = locateLocal("tmp", TDEGlobal::instance()->instanceName());
+ }
+ (void) create(filePrefix, fileExtension, mode);
+}
+
+KTempFile::KTempFile(bool)
+{
+ bAutoDelete = false;
+ mFd = -1;
+ mStream = 0;
+ mFile = 0;
+ mTextStream = 0;
+ mDataStream = 0;
+ mError = 0;
+ bOpen = false;
+}
+
+bool
+KTempFile::create(const TQString &filePrefix, const TQString &fileExtension,
+ int mode)
+{
+ // make sure the random seed is randomized
+ (void) TDEApplication::random();
+
+ TQCString ext = TQFile::encodeName(fileExtension);
+ TQCString nme = TQFile::encodeName(filePrefix) + "XXXXXX" + ext;
+ if((mFd = mkstemps(nme.data(), ext.length())) < 0)
+ {
+ // Recreate it for the warning, mkstemps emptied it
+ TQCString nme = TQFile::encodeName(filePrefix) + "XXXXXX" + ext;
+ kdWarning() << "KTempFile: Error trying to create " << nme << ": " << strerror(errno) << endl;
+ mError = errno;
+ mTmpName = TQString::null;
+ return false;
+ }
+
+ // got a file descriptor. nme contains the name
+ mTmpName = TQFile::decodeName(nme);
+ mode_t tmp = 0;
+ mode_t umsk = umask(tmp);
+ umask(umsk);
+ fchmod(mFd, mode&(~umsk));
+
+ // Success!
+ bOpen = true;
+
+ uid_t uid = getuid();
+ uid_t euid = geteuid();
+ if (uid != euid) {
+ // Set uid/gid (necessary for SUID programs)
+ fchown(mFd, getuid(), getgid());
+ }
+
+ // Set close on exec
+ fcntl(mFd, F_SETFD, FD_CLOEXEC);
+
+ return true;
+}
+
+KTempFile::~KTempFile()
+{
+ close();
+ if (bAutoDelete)
+ unlink();
+}
+
+int
+KTempFile::status() const
+{
+ return mError;
+}
+
+TQString
+KTempFile::name() const
+{
+ return mTmpName;
+}
+
+int
+KTempFile::handle() const
+{
+ return mFd;
+}
+
+FILE *
+KTempFile::fstream()
+{
+ if (mStream) return mStream;
+ if (mFd < 0) return 0;
+
+ // Create a stream
+ mStream = KDE_fdopen(mFd, "r+");
+ if (!mStream) {
+ kdWarning() << "KTempFile: Error trying to open " << mTmpName << ": " << strerror(errno) << endl;
+ mError = errno;
+ }
+ return mStream;
+}
+
+TQFile *
+KTempFile::file()
+{
+ if (mFile) return mFile;
+ if ( !fstream() ) return 0;
+
+ mFile = new TQFile();
+ mFile->setName( name() );
+ mFile->open(IO_ReadWrite, mStream);
+ return mFile;
+}
+
+TQTextStream *
+KTempFile::textStream()
+{
+ if (mTextStream) return mTextStream;
+ if ( !file() ) return 0; // Initialize mFile
+
+ mTextStream = new TQTextStream( mFile );
+ return mTextStream;
+}
+
+TQDataStream *
+KTempFile::dataStream()
+{
+ if (mDataStream) return mDataStream;
+ if ( !file() ) return 0; // Initialize mFile
+
+ mDataStream = new TQDataStream( mFile );
+ return mDataStream;
+}
+
+void
+KTempFile::unlink()
+{
+ if (!mTmpName.isEmpty())
+ TQFile::remove( mTmpName );
+ mTmpName = TQString::null;
+}
+
+#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
+#define FDATASYNC fdatasync
+#else
+#define FDATASYNC fsync
+#endif
+
+bool
+KTempFile::sync()
+{
+ int result = 0;
+
+ if (mStream)
+ {
+ do {
+ result = fflush(mStream); // We need to flush first otherwise fsync may not have our data
+ }
+ while ((result == -1) && (errno == EINTR));
+
+ if (result)
+ {
+ kdWarning() << "KTempFile: Error trying to flush " << mTmpName << ": " << strerror(errno) << endl;
+ mError = errno;
+ }
+ }
+
+ if (mFd >= 0)
+ {
+ if( qstrcmp( getenv( "TDE_EXTRA_FSYNC" ), "1" ) == 0 )
+ {
+ result = FDATASYNC(mFd);
+ if (result)
+ {
+ kdWarning() << "KTempFile: Error trying to sync " << mTmpName << ": " << strerror(errno) << endl;
+ mError = errno;
+ }
+ }
+ }
+
+ return (mError == 0);
+}
+
+#undef FDATASYNC
+
+bool
+KTempFile::close()
+{
+ int result = 0;
+ delete mTextStream; mTextStream = 0;
+ delete mDataStream; mDataStream = 0;
+ delete mFile; mFile = 0;
+
+ if (mStream)
+ {
+ result = ferror(mStream);
+ if (result)
+ mError = ENOSPC; // Assume disk full.
+
+ result = fclose(mStream);
+ mStream = 0;
+ mFd = -1;
+ if (result != 0) {
+ kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
+ mError = errno;
+ }
+ }
+
+
+ if (mFd >= 0)
+ {
+ result = ::close(mFd);
+ mFd = -1;
+ if (result != 0) {
+ kdWarning() << "KTempFile: Error trying to close " << mTmpName << ": " << strerror(errno) << endl;
+ mError = errno;
+ }
+ }
+
+ bOpen = false;
+ return (mError == 0);
+}
+