summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--library/filemanager.cpp85
-rw-r--r--library/filemanager.h2
2 files changed, 78 insertions, 9 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp
index 2b97846..cc657fa 100644
--- a/library/filemanager.cpp
+++ b/library/filemanager.cpp
@@ -23,16 +23,21 @@
23#include <qdir.h> 23#include <qdir.h>
24#include <qfile.h> 24#include <qfile.h>
25#include <qfileinfo.h> 25#include <qfileinfo.h>
26#include <qtextstream.h> 26#include <qtextstream.h>
27#include <qtextcodec.h> 27#include <qtextcodec.h>
28 28
29#include <errno.h> 29#include <errno.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <unistd.h>
32#include <sys/stat.h>
33#include <dirent.h>
34#include <sys/sendfile.h>
35#include <fcntl.h>
31 36
32/*! 37/*!
33 \class FileManager 38 \class FileManager
34 \brief The FileManager class assists with AppLnk input/output. 39 \brief The FileManager class assists with AppLnk input/output.
35*/ 40*/
36 41
37/*! 42/*!
38 Constructs a FileManager. 43 Constructs a FileManager.
@@ -54,30 +59,32 @@ FileManager::~FileManager()
54 59
55 Returns whether the operation succeeded. 60 Returns whether the operation succeeded.
56*/ 61*/
57bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) 62bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
58{ 63{
59 QString fn = f.file() + ".new"; 64 QString fn = f.file() + ".new";
60 ensurePathExists( fn ); 65 ensurePathExists( fn );
61 QFile fl( fn ); 66 QFile fl( fn );
62 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) 67 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
68 qWarning("open failed");
63 return FALSE; 69 return FALSE;
70 }
64 int total_written = fl.writeBlock( data ); 71 int total_written = fl.writeBlock( data );
65 fl.close(); 72 fl.close();
66 if ( total_written != int(data.size()) || !f.writeLink() ) { 73 if ( total_written != int(data.size()) || !f.writeLink() ) {
67 QFile::remove( fn ); 74 QFile::remove( fn );
68 return FALSE; 75 return FALSE;
69 } 76 }
77 qDebug("total written %d out of %d", total_written, data.size());
70 // else rename the file... 78 // else rename the file...
71 if ( ::rename( fn.latin1(), f.file().latin1() ) < 0 ) { 79 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
72 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 80 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
73 f.file().latin1(), errno ); 81 f.file().latin1(), errno );
74 // remove the file... 82 // remove the file...
75 QFile::remove( fn );
76 } 83 }
77 return TRUE; 84 return TRUE;
78} 85}
79 86
80/*! 87/*!
81 Saves \a text as the document specified by \a f. 88 Saves \a text as the document specified by \a f.
82 89
83 The text is saved in UTF8 format. 90 The text is saved in UTF8 format.
@@ -85,34 +92,33 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
85 Returns whether the operation succeeded. 92 Returns whether the operation succeeded.
86*/ 93*/
87bool FileManager::saveFile( const DocLnk &f, const QString &text ) 94bool FileManager::saveFile( const DocLnk &f, const QString &text )
88{ 95{
89 QString fn = f.file() + ".new"; 96 QString fn = f.file() + ".new";
90 ensurePathExists( fn ); 97 ensurePathExists( fn );
91 QFile fl( fn ); 98 QFile fl( fn );
92 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 99 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
93 qDebug( "open failed: %s", fn.latin1() ); 100 qWarning("open failed");
94 return FALSE; 101 return FALSE;
95 } 102 }
96 103
97 QCString cstr = text.utf8(); 104 QCString cstr = text.utf8();
98 int total_written; 105 int total_written;
99 total_written = fl.writeBlock( cstr.data(), cstr.length() ); 106 total_written = fl.writeBlock( cstr.data(), cstr.length() );
100 fl.close(); 107 fl.close();
101 if ( total_written != int(cstr.length()) || !f.writeLink() ) { 108 if ( total_written != int(cstr.length()) || !f.writeLink() ) {
102 QFile::remove( fn ); 109 QFile::remove( fn );
103 return FALSE; 110 return FALSE;
104 } 111 }
105 // okay now rename the file... 112 // okay now rename the file..
106 if ( ::rename( fn.latin1(), f.file().latin1() ) < 0 ) { 113 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
107 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 114 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
108 f.file().latin1(), errno ); 115 f.file().latin1(), errno );
109 // remove the tmp file, otherwise, it will just lay around... 116
110 QFile::remove( fn.latin1() );
111 } 117 }
112 return TRUE; 118 return TRUE;
113} 119}
114 120
115 121
116/*! 122/*!
117 Loads \a text from the document specified by \a f. 123 Loads \a text from the document specified by \a f.
118 124
@@ -192,29 +198,90 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
192 } 198 }
193 } 199 }
194 200
195 if ( ok ) 201 if ( ok )
196 ok = dest.writeLink(); 202 ok = dest.writeLink();
197 203
198 if ( ok ) { 204 if ( ok ) {
199 // okay now rename the file... 205 // okay now rename the file...
200 if ( ::rename( fn.latin1(), dest.file().latin1() ) < 0 ) { 206 if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) {
201 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 207 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
202 dest.file().latin1(), errno ); 208 dest.file().latin1(), errno );
203 // remove the tmp file, otherwise, it will just lay around... 209 // remove the tmp file, otherwise, it will just lay around...
204 QFile::remove( fn.latin1() ); 210 QFile::remove( fn.latin1() );
205 } 211 }
206 } else { 212 } else {
207 QFile::remove( fn.latin1() ); 213 QFile::remove( fn.latin1() );
208 } 214 }
209 215
210 return ok; 216 return ok;
211} 217}
212 218
219bool FileManager::copyFile( const QString & src, const QString & dest ) {
220 bool success = true;
221 struct stat status;
222 int read_fd=0;
223 int write_fd=0;
224 struct stat stat_buf;
225 off_t offset = 0;
226 QFile srcFile(src);
227 QFile destFile(dest);
228
229 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
230 return success = false;
231 }
232 read_fd = srcFile.handle();
233 if(read_fd != -1) {
234 fstat (read_fd, &stat_buf);
235 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
236 return success = false;
237 write_fd = destFile.handle();
238 if(write_fd != -1) {
239 int err=0;
240 QString msg;
241 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
242 if( err == -1) {
243 switch(err) {
244 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
245 case EINVAL: msg = "Descriptor is not valid or locked. ";
246 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
247 case EIO: msg = "Unspecified error while reading from in_fd.";
248 };
249 success = false;
250 }
251 } else {
252 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
253 success = false;
254 }
255 } else {
256 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
257 success = false;
258 }
259 srcFile.close();
260 destFile.close();
261 // Set file permissions
262 if( stat( (const char *) src, &status ) == 0 ) {
263 chmod( (const char *) dest, status.st_mode );
264 }
265
266 return success;
267}
268
269
270bool FileManager::renameFile( const QString & src, const QString & dest ) {
271 if(copyFile( src, dest )) {
272 if(QFile::remove(src) ) {
273 return true;
274 }
275 }
276 return false;
277}
278
279
213/*! 280/*!
214 Opens the document specified by \a f as a readable QIODevice. 281 Opens the document specified by \a f as a readable QIODevice.
215 The caller must delete the return value. 282 The caller must delete the return value.
216 283
217 Returns 0 if the operation fails. 284 Returns 0 if the operation fails.
218*/ 285*/
219QIODevice* FileManager::openFile( const DocLnk& f ) 286QIODevice* FileManager::openFile( const DocLnk& f )
220{ 287{
diff --git a/library/filemanager.h b/library/filemanager.h
index f8d9425..61a3341 100644
--- a/library/filemanager.h
+++ b/library/filemanager.h
@@ -33,16 +33,18 @@ public:
33 FileManager(); 33 FileManager();
34 ~FileManager(); 34 ~FileManager();
35 35
36 bool saveFile( const DocLnk&, const QByteArray &data ); 36 bool saveFile( const DocLnk&, const QByteArray &data );
37 bool saveFile( const DocLnk&, const QString &text ); 37 bool saveFile( const DocLnk&, const QString &text );
38 bool loadFile( const DocLnk&, QByteArray &data ); 38 bool loadFile( const DocLnk&, QByteArray &data );
39 bool loadFile( const DocLnk&, QString &text ); 39 bool loadFile( const DocLnk&, QString &text );
40 bool copyFile( const AppLnk &src, const AppLnk &dest ); 40 bool copyFile( const AppLnk &src, const AppLnk &dest );
41 bool copyFile( const QString & src, const QString & dest );
42 bool renameFile( const QString &, const QString &);
41 43
42 // The caller must delete the return values. 44 // The caller must delete the return values.
43 QIODevice* openFile( const DocLnk& ); 45 QIODevice* openFile( const DocLnk& );
44 QIODevice* saveFile( const DocLnk& ); 46 QIODevice* saveFile( const DocLnk& );
45 47
46 bool exists( const DocLnk& ); 48 bool exists( const DocLnk& );
47 49
48protected: 50protected: