-rw-r--r-- | library/filemanager.cpp | 167 | ||||
-rw-r--r-- | library/filemanager.h | 6 |
2 files changed, 121 insertions, 52 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp index 2b97846..cc657fa 100644 --- a/library/filemanager.cpp +++ b/library/filemanager.cpp | |||
@@ -30,2 +30,7 @@ | |||
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 | ||
@@ -58,7 +63,9 @@ bool 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 ) ) { |
63 | return FALSE; | 68 | qWarning("open failed"); |
69 | return FALSE; | ||
70 | } | ||
64 | int total_written = fl.writeBlock( data ); | 71 | int total_written = fl.writeBlock( data ); |
@@ -66,11 +73,11 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) | |||
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 | } |
@@ -88,3 +95,3 @@ bool 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 ); |
@@ -92,4 +99,4 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text ) | |||
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 | } |
@@ -101,11 +108,10 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text ) | |||
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 | } |
@@ -127,3 +133,3 @@ bool FileManager::loadFile( const DocLnk &f, QString &text ) | |||
127 | if ( !fl.open( IO_ReadOnly ) ) | 133 | if ( !fl.open( IO_ReadOnly ) ) |
128 | return FALSE; | 134 | return FALSE; |
129 | QTextStream ts( &fl ); | 135 | QTextStream ts( &fl ); |
@@ -151,6 +157,6 @@ bool FileManager::loadFile( const DocLnk &f, QByteArray &ba ) | |||
151 | if ( !fl.open( IO_ReadOnly ) ) | 157 | if ( !fl.open( IO_ReadOnly ) ) |
152 | return FALSE; | 158 | return FALSE; |
153 | ba.resize( fl.size() ); | 159 | ba.resize( fl.size() ); |
154 | if ( fl.size() > 0 ) | 160 | if ( fl.size() > 0 ) |
155 | fl.readBlock( ba.data(), fl.size() ); | 161 | fl.readBlock( ba.data(), fl.size() ); |
156 | fl.close(); | 162 | fl.close(); |
@@ -169,3 +175,3 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
169 | if ( !sf.open( IO_ReadOnly ) ) | 175 | if ( !sf.open( IO_ReadOnly ) ) |
170 | return FALSE; | 176 | return FALSE; |
171 | 177 | ||
@@ -175,3 +181,3 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
175 | if ( !df.open( IO_WriteOnly|IO_Raw ) ) | 181 | if ( !df.open( IO_WriteOnly|IO_Raw ) ) |
176 | return FALSE; | 182 | return FALSE; |
177 | 183 | ||
@@ -182,12 +188,12 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
182 | while ( ok && !sf.atEnd() ) { | 188 | while ( ok && !sf.atEnd() ) { |
183 | bytesRead = sf.readBlock( buffer, bufsize ); | 189 | bytesRead = sf.readBlock( buffer, bufsize ); |
184 | if ( bytesRead < 0 ) | 190 | if ( bytesRead < 0 ) |
185 | ok = FALSE; | 191 | ok = FALSE; |
186 | while ( ok && bytesRead > 0 ) { | 192 | while ( ok && bytesRead > 0 ) { |
187 | int bytesWritten = df.writeBlock( buffer, bytesRead ); | 193 | int bytesWritten = df.writeBlock( buffer, bytesRead ); |
188 | if ( bytesWritten < 0 ) | 194 | if ( bytesWritten < 0 ) |
189 | ok = FALSE; | 195 | ok = FALSE; |
190 | else | 196 | else |
191 | bytesRead -= bytesWritten; | 197 | bytesRead -= bytesWritten; |
192 | } | 198 | } |
193 | } | 199 | } |
@@ -195,14 +201,14 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
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 | } |
@@ -212,2 +218,63 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
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 | /*! |
@@ -223,3 +290,3 @@ QIODevice* FileManager::openFile( const DocLnk& f ) | |||
223 | if ( !fl->open( IO_ReadOnly ) ) { | 290 | if ( !fl->open( IO_ReadOnly ) ) { |
224 | delete fl; | 291 | delete fl; |
225 | fl = 0; | 292 | fl = 0; |
@@ -241,5 +308,5 @@ QIODevice* FileManager::saveFile( const DocLnk& f ) | |||
241 | if ( fl->open( IO_WriteOnly ) ) { | 308 | if ( fl->open( IO_WriteOnly ) ) { |
242 | f.writeLink(); | 309 | f.writeLink(); |
243 | } else { | 310 | } else { |
244 | delete fl; | 311 | delete fl; |
245 | fl = 0; | 312 | fl = 0; |
@@ -268,4 +335,4 @@ bool FileManager::ensurePathExists( const QString &fn ) | |||
268 | if ( !fi.exists() ) { | 335 | if ( !fi.exists() ) { |
269 | if ( system(("mkdir -p "+fi.filePath())) ) | 336 | if ( system(("mkdir -p "+fi.filePath())) ) |
270 | return FALSE; | 337 | return FALSE; |
271 | } | 338 | } |
diff --git a/library/filemanager.h b/library/filemanager.h index f8d9425..61a3341 100644 --- a/library/filemanager.h +++ b/library/filemanager.h | |||
@@ -40,4 +40,6 @@ public: | |||
40 | bool copyFile( const AppLnk &src, const AppLnk &dest ); | 40 | bool copyFile( const AppLnk &src, const AppLnk &dest ); |
41 | 41 | bool copyFile( const QString & src, const QString & dest ); | |
42 | // The caller must delete the return values. | 42 | bool renameFile( const QString &, const QString &); |
43 | |||
44 | // The caller must delete the return values. | ||
43 | QIODevice* openFile( const DocLnk& ); | 45 | QIODevice* openFile( const DocLnk& ); |