summaryrefslogtreecommitdiff
path: root/library/filemanager.cpp
Unidiff
Diffstat (limited to 'library/filemanager.cpp') (more/less context) (show whitespace changes)
-rw-r--r--library/filemanager.cpp85
1 files changed, 76 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
@@ -28,6 +28,11 @@
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
@@ -59,20 +64,22 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
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}
@@ -90,7 +97,7 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text )
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
@@ -102,12 +109,11 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text )
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}
@@ -197,7 +203,7 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
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...
@@ -210,6 +216,67 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
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.