ksavefile.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <sys/types.h>
00023
00024 #ifdef HAVE_SYS_STAT_H
00025 #include <sys/stat.h>
00026 #endif
00027
00028 #include <unistd.h>
00029 #include <fcntl.h>
00030
00031 #ifdef HAVE_TEST
00032 #include <test.h>
00033 #endif
00034
00035 #include <qdatetime.h>
00036 #include <qdir.h>
00037
00038 #include "kapplication.h"
00039 #include "ksavefile.h"
00040
00041 KSaveFile::KSaveFile(const QString &filename, int mode)
00042 : mTempFile(true)
00043 {
00044
00045
00046
00047 if (!checkAccess(filename, W_OK))
00048 {
00049 mTempFile.setError(EACCES);
00050 return;
00051 }
00052
00053 if (mTempFile.create(filename, QString::fromLatin1(".new"), mode))
00054 {
00055 mFileName = filename;
00056 }
00057 return;
00058 }
00059
00060 KSaveFile::~KSaveFile()
00061 {
00062 close();
00063 }
00064
00065 QString
00066 KSaveFile::name() const
00067 {
00068 return mFileName;
00069 }
00070
00071 void
00072 KSaveFile::abort()
00073 {
00074 mTempFile.unlink();
00075 mTempFile.close();
00076 }
00077
00078 bool
00079 KSaveFile::close()
00080 {
00081 if (mTempFile.name().isEmpty())
00082 return false;
00083 if (mTempFile.close())
00084 {
00085 QDir dir;
00086 bool result = dir.rename( mTempFile.name(), mFileName);
00087 if ( result )
00088 {
00089 return true;
00090 }
00091 mTempFile.setError(errno);
00092 }
00093
00094
00095 mTempFile.unlink();
00096 return false;
00097 }
00098
00099 static int
00100 write_all(int fd, const char *buf, size_t len)
00101 {
00102 while (len > 0)
00103 {
00104 int written = write(fd, buf, len);
00105 if (written < 0)
00106 {
00107 if (errno == EINTR)
00108 continue;
00109 return -1;
00110 }
00111 buf += written;
00112 len -= written;
00113 }
00114 return 0;
00115 }
00116
00117 bool KSaveFile::backupFile( const QString& qFilename, const QString& backupDir,
00118 const QString& backupExtension)
00119 {
00120 QCString cFilename = QFile::encodeName(qFilename);
00121 const char *filename = cFilename.data();
00122
00123 int fd = open( filename, O_RDONLY);
00124 if (fd < 0)
00125 return false;
00126
00127 struct stat buff;
00128 if ( fstat( fd, &buff) < 0 )
00129 {
00130 ::close( fd );
00131 return false;
00132 }
00133
00134 QCString cBackup;
00135 if ( backupDir.isEmpty() )
00136 cBackup = cFilename;
00137 else
00138 {
00139 QCString nameOnly;
00140 int slash = cFilename.findRev('/');
00141 if (slash < 0)
00142 nameOnly = cFilename;
00143 else
00144 nameOnly = cFilename.mid(slash + 1);
00145 cBackup = QFile::encodeName(backupDir);
00146 if ( backupDir[backupDir.length()-1] != '/' )
00147 cBackup += '/';
00148 cBackup += nameOnly;
00149 }
00150 cBackup += QFile::encodeName(backupExtension);
00151 const char *backup = cBackup.data();
00152 int permissions = buff.st_mode & 07777;
00153
00154 if ( stat( backup, &buff) == 0)
00155 {
00156 if ( unlink( backup ) != 0 )
00157 {
00158 ::close(fd);
00159 return false;
00160 }
00161 }
00162
00163 mode_t old_umask = umask(0);
00164 int fd2 = open( backup, O_WRONLY | O_CREAT | O_EXCL, permissions | S_IWUSR);
00165 umask(old_umask);
00166
00167 if ( fd2 < 0 )
00168 {
00169 ::close(fd);
00170 return false;
00171 }
00172
00173 char buffer[ 32*1024 ];
00174
00175 while( 1 )
00176 {
00177 int n = ::read( fd, buffer, 32*1024 );
00178 if (n == -1)
00179 {
00180 if (errno == EINTR)
00181 continue;
00182 ::close(fd);
00183 ::close(fd2);
00184 return false;
00185 }
00186 if (n == 0)
00187 break;
00188
00189 if (write_all( fd2, buffer, n))
00190 {
00191 ::close(fd);
00192 ::close(fd2);
00193 return false;
00194 }
00195 }
00196
00197 ::close( fd );
00198
00199 if (::close(fd2))
00200 return false;
00201 return true;
00202 }
This file is part of the documentation for kdecore Library Version 3.2.0.