-rw-r--r-- | library/filemanager.cpp | 85 |
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 | ||
219 | bool 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 | |||
270 | bool 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. |