author | ar <ar> | 2004-06-19 14:27:36 (UTC) |
---|---|---|
committer | ar <ar> | 2004-06-19 14:27:36 (UTC) |
commit | 8beb35ab232bf3f20582cf6d1d00681b8dd8e24d (patch) (unidiff) | |
tree | 4a1eb02423a1053ec9524bb1544893d0686bfbbd | |
parent | 0689d1b607583b9b4ebf55b2180bba99d6008d90 (diff) | |
download | opie-8beb35ab232bf3f20582cf6d1d00681b8dd8e24d.zip opie-8beb35ab232bf3f20582cf6d1d00681b8dd8e24d.tar.gz opie-8beb35ab232bf3f20582cf6d1d00681b8dd8e24d.tar.bz2 |
- ignore ENOENT and EAGAIN in renameFile (bug in system?)
- replace system-call "mkdir..." with QDir::mkdir
-rw-r--r-- | library/filemanager.cpp | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp index 2e5efdd..fbfa1d9 100644 --- a/library/filemanager.cpp +++ b/library/filemanager.cpp | |||
@@ -1,327 +1,329 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #include "filemanager.h" | 21 | #include "filemanager.h" |
22 | #include "applnk.h" | 22 | #include "applnk.h" |
23 | 23 | ||
24 | /* QT */ | 24 | /* QT */ |
25 | #include <qdir.h> | 25 | #include <qdir.h> |
26 | #include <qfileinfo.h> | 26 | #include <qfileinfo.h> |
27 | #include <qtextstream.h> | 27 | #include <qtextstream.h> |
28 | 28 | ||
29 | /* STD */ | 29 | /* STD */ |
30 | #include <stdlib.h> | 30 | #include <stdlib.h> |
31 | #include <errno.h> | 31 | #include <errno.h> |
32 | #include <sys/stat.h> | 32 | #include <sys/stat.h> |
33 | 33 | ||
34 | /*! | 34 | /*! |
35 | \class FileManager | 35 | \class FileManager |
36 | \brief The FileManager class assists with AppLnk input/output. | 36 | \brief The FileManager class assists with AppLnk input/output. |
37 | */ | 37 | */ |
38 | 38 | ||
39 | /*! | 39 | /*! |
40 | Constructs a FileManager. | 40 | Constructs a FileManager. |
41 | */ | 41 | */ |
42 | FileManager::FileManager() | 42 | FileManager::FileManager() |
43 | { | 43 | { |
44 | } | 44 | } |
45 | 45 | ||
46 | /*! | 46 | /*! |
47 | Destroys a FileManager. | 47 | Destroys a FileManager. |
48 | */ | 48 | */ |
49 | FileManager::~FileManager() | 49 | FileManager::~FileManager() |
50 | { | 50 | { |
51 | } | 51 | } |
52 | 52 | ||
53 | /*! | 53 | /*! |
54 | Saves \a data as the document specified by \a f. | 54 | Saves \a data as the document specified by \a f. |
55 | 55 | ||
56 | Returns whether the operation succeeded. | 56 | Returns whether the operation succeeded. |
57 | */ | 57 | */ |
58 | bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) | 58 | bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) |
59 | { | 59 | { |
60 | QString fileName = f.file() + ".new"; | 60 | QString fileName = f.file() + ".new"; |
61 | ensurePathExists( fileName ); | 61 | ensurePathExists( fileName ); |
62 | QFile file( fileName ); | 62 | QFile file( fileName ); |
63 | 63 | ||
64 | //write data in temporary .new file | 64 | //write data in temporary .new file |
65 | if ( !file.open( IO_WriteOnly|IO_Raw ) ) | 65 | if ( !file.open( IO_WriteOnly|IO_Raw ) ) |
66 | { | 66 | { |
67 | qWarning( "open failed" ); | 67 | qWarning( "open failed" ); |
68 | return FALSE; | 68 | return FALSE; |
69 | } | 69 | } |
70 | int total_written = file.writeBlock( data ); | 70 | int total_written = file.writeBlock( data ); |
71 | file.close(); | 71 | file.close(); |
72 | //check if every was written | 72 | //check if every was written |
73 | if ( total_written != int( data.size() ) || !f.writeLink() ) | 73 | if ( total_written != int( data.size() ) || !f.writeLink() ) |
74 | { | 74 | { |
75 | QFile::remove( fileName ); | 75 | QFile::remove( fileName ); |
76 | return FALSE; | 76 | return FALSE; |
77 | } | 77 | } |
78 | qDebug( "total written %d out of %d", total_written, data.size() ); | 78 | qDebug( "total written %d out of %d", total_written, data.size() ); |
79 | 79 | ||
80 | //rename temporary .new file in original filenam | 80 | //rename temporary .new file in original filenam |
81 | if ( !renameFile( fileName, f.file() ) ) | 81 | if ( !renameFile( fileName, f.file() ) ) |
82 | QFile::remove( fileName); | 82 | QFile::remove( fileName); |
83 | return TRUE; | 83 | return TRUE; |
84 | } | 84 | } |
85 | 85 | ||
86 | /*! | 86 | /*! |
87 | Saves \a text as the document specified by \a f. | 87 | Saves \a text as the document specified by \a f. |
88 | 88 | ||
89 | The text is saved in UTF8 format. | 89 | The text is saved in UTF8 format. |
90 | 90 | ||
91 | Returns whether the operation succeeded. | 91 | Returns whether the operation succeeded. |
92 | */ | 92 | */ |
93 | bool FileManager::saveFile( const DocLnk &f, const QString &text ) | 93 | bool FileManager::saveFile( const DocLnk &f, const QString &text ) |
94 | { | 94 | { |
95 | QString fileName = f.file() + ".new"; | 95 | QString fileName = f.file() + ".new"; |
96 | ensurePathExists( fileName ); | 96 | ensurePathExists( fileName ); |
97 | QFile file( fileName ); | 97 | QFile file( fileName ); |
98 | 98 | ||
99 | //write data in temporary .new file | 99 | //write data in temporary .new file |
100 | if ( !file.open( IO_WriteOnly|IO_Raw ) ) | 100 | if ( !file.open( IO_WriteOnly|IO_Raw ) ) |
101 | { | 101 | { |
102 | qWarning( "open failed" ); | 102 | qWarning( "open failed" ); |
103 | return FALSE; | 103 | return FALSE; |
104 | } | 104 | } |
105 | 105 | ||
106 | QCString cstr = text.utf8(); | 106 | QCString cstr = text.utf8(); |
107 | int total_written; | 107 | int total_written; |
108 | total_written = file.writeBlock( cstr.data(), cstr.length() ); | 108 | total_written = file.writeBlock( cstr.data(), cstr.length() ); |
109 | file.close(); | 109 | file.close(); |
110 | if ( total_written != int( cstr.length()) || !f.writeLink() ) | 110 | if ( total_written != int( cstr.length()) || !f.writeLink() ) |
111 | { | 111 | { |
112 | QFile::remove( fileName ); | 112 | QFile::remove( fileName ); |
113 | return FALSE; | 113 | return FALSE; |
114 | } | 114 | } |
115 | 115 | ||
116 | // okay now rename the file.. | 116 | // okay now rename the file.. |
117 | if ( !renameFile( fileName, f.file() ) ) | 117 | if ( !renameFile( fileName, f.file() ) ) |
118 | QFile::remove( fileName); | 118 | QFile::remove( fileName); |
119 | return TRUE; | 119 | return TRUE; |
120 | } | 120 | } |
121 | 121 | ||
122 | 122 | ||
123 | /*! | 123 | /*! |
124 | Loads \a text from the document specified by \a f. | 124 | Loads \a text from the document specified by \a f. |
125 | 125 | ||
126 | The text is required to be in UTF8 format. | 126 | The text is required to be in UTF8 format. |
127 | 127 | ||
128 | Returns whether the operation succeeded. | 128 | Returns whether the operation succeeded. |
129 | */ | 129 | */ |
130 | bool FileManager::loadFile( const DocLnk &f, QString &text ) | 130 | bool FileManager::loadFile( const DocLnk &f, QString &text ) |
131 | { | 131 | { |
132 | QString fn = f.file(); | 132 | QString fn = f.file(); |
133 | QFile fl( fn ); | 133 | QFile fl( fn ); |
134 | if ( !fl.open( IO_ReadOnly ) ) | 134 | if ( !fl.open( IO_ReadOnly ) ) |
135 | return FALSE; | 135 | return FALSE; |
136 | QTextStream ts( &fl ); | 136 | QTextStream ts( &fl ); |
137 | #if QT_VERSION <= 230 && defined(QT_NO_CODECS) | 137 | #if QT_VERSION <= 230 && defined(QT_NO_CODECS) |
138 | // The below should work, but doesn't in Qt 2.3.0 | 138 | // The below should work, but doesn't in Qt 2.3.0 |
139 | ts.setCodec( QTextCodec::codecForMib( 106 ) ); | 139 | ts.setCodec( QTextCodec::codecForMib( 106 ) ); |
140 | #else | 140 | #else |
141 | ts.setEncoding( QTextStream::UnicodeUTF8 ); | 141 | ts.setEncoding( QTextStream::UnicodeUTF8 ); |
142 | #endif | 142 | #endif |
143 | text = ts.read(); | 143 | text = ts.read(); |
144 | fl.close(); | 144 | fl.close(); |
145 | return TRUE; | 145 | return TRUE; |
146 | } | 146 | } |
147 | 147 | ||
148 | 148 | ||
149 | /*! | 149 | /*! |
150 | Loads \a ba from the document specified by \a f. | 150 | Loads \a ba from the document specified by \a f. |
151 | 151 | ||
152 | Returns whether the operation succeeded. | 152 | Returns whether the operation succeeded. |
153 | */ | 153 | */ |
154 | bool FileManager::loadFile( const DocLnk &f, QByteArray &ba ) | 154 | bool FileManager::loadFile( const DocLnk &f, QByteArray &ba ) |
155 | { | 155 | { |
156 | QString fn = f.file(); | 156 | QString fn = f.file(); |
157 | QFile fl( fn ); | 157 | QFile fl( fn ); |
158 | if ( !fl.open( IO_ReadOnly ) ) | 158 | if ( !fl.open( IO_ReadOnly ) ) |
159 | return FALSE; | 159 | return FALSE; |
160 | ba.resize( fl.size() ); | 160 | ba.resize( fl.size() ); |
161 | if ( fl.size() > 0 ) | 161 | if ( fl.size() > 0 ) |
162 | fl.readBlock( ba.data(), fl.size() ); | 162 | fl.readBlock( ba.data(), fl.size() ); |
163 | fl.close(); | 163 | fl.close(); |
164 | return TRUE; | 164 | return TRUE; |
165 | } | 165 | } |
166 | 166 | ||
167 | /*! | 167 | /*! |
168 | Copies the document specified by \a src to the document specified | 168 | Copies the document specified by \a src to the document specified |
169 | by \a dest. | 169 | by \a dest. |
170 | 170 | ||
171 | Returns whether the operation succeeded. | 171 | Returns whether the operation succeeded. |
172 | */ | 172 | */ |
173 | bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | 173 | bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) |
174 | { | 174 | { |
175 | QFile srcFile( src.file() ); | 175 | QFile srcFile( src.file() ); |
176 | if ( !srcFile.open( IO_ReadOnly ) ) | 176 | if ( !srcFile.open( IO_ReadOnly ) ) |
177 | return FALSE; | 177 | return FALSE; |
178 | 178 | ||
179 | QString fileName = dest.file() + ".new"; | 179 | QString fileName = dest.file() + ".new"; |
180 | 180 | ||
181 | ensurePathExists( fileName ); | 181 | ensurePathExists( fileName ); |
182 | 182 | ||
183 | bool ok = TRUE; | 183 | bool ok = TRUE; |
184 | ok = copyFile( src.file(), fileName ); | 184 | ok = copyFile( src.file(), fileName ); |
185 | 185 | ||
186 | if ( ok ) | 186 | if ( ok ) |
187 | ok = dest.writeLink(); | 187 | ok = dest.writeLink(); |
188 | 188 | ||
189 | if ( ok ) | 189 | if ( ok ) |
190 | { | 190 | { |
191 | // okay now rename the file... | 191 | // okay now rename the file... |
192 | if ( !renameFile( fileName, dest.file() ) ) | 192 | if ( !renameFile( fileName, dest.file() ) ) |
193 | // remove the tmp file, otherwise, it will just lay around... | 193 | // remove the tmp file, otherwise, it will just lay around... |
194 | QFile::remove( fileName ); | 194 | QFile::remove( fileName ); |
195 | } | 195 | } |
196 | else | 196 | else |
197 | { | 197 | { |
198 | QFile::remove( fileName ); | 198 | QFile::remove( fileName ); |
199 | } | 199 | } |
200 | return ok; | 200 | return ok; |
201 | } | 201 | } |
202 | 202 | ||
203 | bool FileManager::copyFile( const QString & src, const QString & dest ) | 203 | bool FileManager::copyFile( const QString & src, const QString & dest ) |
204 | { | 204 | { |
205 | //open read file | 205 | //open read file |
206 | QFile srcFile( src ); | 206 | QFile srcFile( src ); |
207 | if( !srcFile.open( IO_ReadOnly|IO_Raw) ) | 207 | if( !srcFile.open( IO_ReadOnly|IO_Raw) ) |
208 | { | 208 | { |
209 | qWarning( "open read failed %s, %s", src.latin1(), dest.latin1() ); | 209 | qWarning( "open read failed %s, %s", src.latin1(), dest.latin1() ); |
210 | return FALSE; | 210 | return FALSE; |
211 | } | 211 | } |
212 | 212 | ||
213 | //open write file | 213 | //open write file |
214 | QFile destFile( dest ); | 214 | QFile destFile( dest ); |
215 | if( !destFile.open( IO_WriteOnly|IO_Raw ) ) | 215 | if( !destFile.open( IO_WriteOnly|IO_Raw ) ) |
216 | { | 216 | { |
217 | qWarning( "open write failed %s, %s", src.latin1(), dest.latin1() ); | 217 | qWarning( "open write failed %s, %s", src.latin1(), dest.latin1() ); |
218 | srcFile.close(); | 218 | srcFile.close(); |
219 | return FALSE; | 219 | return FALSE; |
220 | } | 220 | } |
221 | 221 | ||
222 | //copy content | 222 | //copy content |
223 | const int bufsize = 16384; | 223 | const int bufsize = 16384; |
224 | char buffer[bufsize]; | 224 | char buffer[bufsize]; |
225 | bool ok = TRUE; | 225 | bool ok = TRUE; |
226 | int bytesRead = 0; | 226 | int bytesRead = 0; |
227 | while ( ok && !srcFile.atEnd() ) | 227 | while ( ok && !srcFile.atEnd() ) |
228 | { | 228 | { |
229 | bytesRead = srcFile.readBlock( buffer, bufsize ); | 229 | bytesRead = srcFile.readBlock( buffer, bufsize ); |
230 | if ( bytesRead < 0 ) | 230 | if ( bytesRead < 0 ) |
231 | ok = FALSE; | 231 | ok = FALSE; |
232 | while ( ok && bytesRead > 0 ) | 232 | while ( ok && bytesRead > 0 ) |
233 | { | 233 | { |
234 | int bytesWritten = destFile.writeBlock( buffer, bytesRead ); | 234 | int bytesWritten = destFile.writeBlock( buffer, bytesRead ); |
235 | if ( bytesWritten < 0 ) | 235 | if ( bytesWritten < 0 ) |
236 | ok = FALSE; | 236 | ok = FALSE; |
237 | else | 237 | else |
238 | bytesRead -= bytesWritten; | 238 | bytesRead -= bytesWritten; |
239 | } | 239 | } |
240 | } | 240 | } |
241 | srcFile.close(); | 241 | srcFile.close(); |
242 | destFile.close(); | 242 | destFile.close(); |
243 | // Set file permissions | 243 | // Set file permissions |
244 | struct stat status; | 244 | struct stat status; |
245 | if( stat( QFile::encodeName( src ), &status ) == 0 ) | 245 | if( stat( QFile::encodeName( src ), &status ) == 0 ) |
246 | { | 246 | { |
247 | chmod( QFile::encodeName( dest ), status.st_mode ); | 247 | chmod( QFile::encodeName( dest ), status.st_mode ); |
248 | } | 248 | } |
249 | return ok; | 249 | return ok; |
250 | } | 250 | } |
251 | 251 | ||
252 | 252 | ||
253 | bool FileManager::renameFile( const QString & src, const QString & dest ) | 253 | bool FileManager::renameFile( const QString & src, const QString & dest ) |
254 | { | 254 | { |
255 | if( rename( QFile::encodeName( src ), QFile::encodeName( dest ) ) == -1); | 255 | if( rename( QFile::encodeName( src ), QFile::encodeName( dest ) ) == -1); |
256 | { | 256 | { |
257 | qWarning( "problem renaming file %s to %s, errno: %d", src.latin1(), dest.latin1(), errno ); | 257 | if ( errno != 2 && errno != 11 ) //ignore ENOENT and EAGAIN - bug in system? |
258 | return false; | 258 | { |
259 | qWarning( "problem renaming file %s to %s, errno: %d", src.latin1(), dest.latin1(), errno ); | ||
260 | return false; | ||
261 | } | ||
259 | } | 262 | } |
260 | return true; | 263 | return true; |
261 | } | 264 | } |
262 | 265 | ||
263 | /*! | 266 | /*! |
264 | Opens the document specified by \a f as a readable QIODevice. | 267 | Opens the document specified by \a f as a readable QIODevice. |
265 | The caller must delete the return value. | 268 | The caller must delete the return value. |
266 | 269 | ||
267 | Returns 0 if the operation fails. | 270 | Returns 0 if the operation fails. |
268 | */ | 271 | */ |
269 | QIODevice* FileManager::openFile( const DocLnk& f ) | 272 | QIODevice* FileManager::openFile( const DocLnk& f ) |
270 | { | 273 | { |
271 | QString fn = f.file(); | 274 | QString fn = f.file(); |
272 | QFile* fl = new QFile( fn ); | 275 | QFile* fl = new QFile( fn ); |
273 | if ( !fl->open( IO_ReadOnly ) ) | 276 | if ( !fl->open( IO_ReadOnly ) ) |
274 | { | 277 | { |
275 | delete fl; | 278 | delete fl; |
276 | fl = 0; | 279 | fl = 0; |
277 | } | 280 | } |
278 | return fl; | 281 | return fl; |
279 | } | 282 | } |
280 | 283 | ||
281 | /*! | 284 | /*! |
282 | Opens the document specified by \a f as a writable QIODevice. | 285 | Opens the document specified by \a f as a writable QIODevice. |
283 | The caller must delete the return value. | 286 | The caller must delete the return value. |
284 | 287 | ||
285 | Returns 0 if the operation fails. | 288 | Returns 0 if the operation fails. |
286 | */ | 289 | */ |
287 | QIODevice* FileManager::saveFile( const DocLnk& f ) | 290 | QIODevice* FileManager::saveFile( const DocLnk& f ) |
288 | { | 291 | { |
289 | QString fn = f.file(); | 292 | QString fn = f.file(); |
290 | ensurePathExists( fn ); | 293 | ensurePathExists( fn ); |
291 | QFile* fl = new QFile( fn ); | 294 | QFile* fl = new QFile( fn ); |
292 | if ( fl->open( IO_WriteOnly ) ) | 295 | if ( fl->open( IO_WriteOnly ) ) |
293 | { | 296 | { |
294 | f.writeLink(); | 297 | f.writeLink(); |
295 | } | 298 | } |
296 | else | 299 | else |
297 | { | 300 | { |
298 | delete fl; | 301 | delete fl; |
299 | fl = 0; | 302 | fl = 0; |
300 | } | 303 | } |
301 | return fl; | 304 | return fl; |
302 | } | 305 | } |
303 | 306 | ||
304 | /*! | 307 | /*! |
305 | Returns whether the document specified by \a f current exists | 308 | Returns whether the document specified by \a f current exists |
306 | as a file on disk. | 309 | as a file on disk. |
307 | */ | 310 | */ |
308 | bool FileManager::exists( const DocLnk &f ) | 311 | bool FileManager::exists( const DocLnk &f ) |
309 | { | 312 | { |
310 | return QFile::exists(f.file()); | 313 | return QFile::exists(f.file()); |
311 | } | 314 | } |
312 | 315 | ||
313 | /*! | 316 | /*! |
314 | Ensures that the path \a fn exists, by creating required directories. | 317 | Ensures that the path \a fileName exists, by creating required directories. |
315 | Returns TRUE if successful. | 318 | Returns TRUE if successful. |
316 | */ | 319 | */ |
317 | bool FileManager::ensurePathExists( const QString &fn ) | 320 | bool FileManager::ensurePathExists( const QString &fileName ) |
318 | { | 321 | { |
319 | QFileInfo fi(fn); | 322 | QDir directory = QFileInfo( fileName ).dir(); |
320 | fi.setFile( fi.dirPath(TRUE) ); | 323 | if ( !directory.exists() ) |
321 | if ( !fi.exists() ) | ||
322 | { | 324 | { |
323 | if ( system( ("mkdir -p " + QFile::encodeName( fi.filePath() ) ) ) ) | 325 | if ( !directory.mkdir( directory.absPath() ) ) |
324 | return FALSE; | 326 | return FALSE; |
325 | } | 327 | } |
326 | return TRUE; | 328 | return TRUE; |
327 | } | 329 | } |