source: trunk/src/tools/qfile_pm.cpp@ 123

Last change on this file since 123 was 8, checked in by dmik, 20 years ago

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 11.4 KB
Line 
1/****************************************************************************
2** $Id: qfile_pm.cpp 8 2005-11-16 19:36:46Z dmik $
3**
4** Implementation of QFileInfo class
5**
6** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
7** Copyright (C) 2004 Norman ASA. Initial OS/2 Port.
8** Copyright (C) 2005 netlabs.org. Further OS/2 Development.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40#include "qfile.h"
41#include "qfiledefs_p.h"
42#include <limits.h>
43
44extern const char* qt_fileerr_read;
45
46bool qt_file_access( const QString& fn, int t )
47{
48 if ( fn.isEmpty() )
49 return FALSE;
50 return QT_ACCESS( QFile::encodeName( fn ), t) == 0;
51}
52
53bool isValidFile( const QString& fileName )
54{
55 // Since fopen() in many compilers simply returns ENOENT when an
56 // illegal character is used in the filename we do some validation
57 // here to produce a more informative message in QFile::open().
58 // NOTE: only HPFS limitations (which are less restrictive than FAT)
59 // are applied.
60 static const char *badChars = "|<>\"?*";
61 for ( int i = 0; i < (int) fileName.length(); i++) {
62 if ( fileName[i] < QChar( 32 ) )
63 return FALSE;
64 if ( strchr( badChars, fileName[i] ) )
65 return FALSE;
66 }
67 int findColon = fileName.findRev( ':' );
68 if ( findColon == -1 )
69 return TRUE;
70 else if ( findColon != 1 )
71 return FALSE;
72 else
73 return fileName[0].isLetter();
74}
75
76bool QFile::remove( const QString &fileName )
77{
78 if ( fileName.isEmpty() ) {
79#if defined(QT_CHECK_NULL)
80 qWarning( "QFile::remove: Empty or null file name" );
81#endif
82 return FALSE;
83 }
84 return ::remove( QFile::encodeName( fileName ) ) == 0;
85}
86
87#define HAS_TEXT_FILEMODE
88
89bool QFile::open( int m )
90{
91 if ( isOpen() ) { // file already open
92#if defined(QT_CHECK_STATE)
93 qWarning( "QFile::open: File already open" );
94#endif
95 return FALSE;
96 }
97 if ( fn.isEmpty() ) { // no file name defined
98#if defined(QT_CHECK_NULL)
99 qWarning( "QFile::open: No file name specified" );
100#endif
101 return FALSE;
102 }
103 init(); // reset params
104 setMode( m );
105 if ( !(isReadable() || isWritable()) ) {
106#if defined(QT_CHECK_RANGE)
107 qWarning( "QFile::open: File access not specified" );
108#endif
109 return FALSE;
110 }
111 if ( !isValidFile( fn ) ) {
112 qWarning( "QFile::open: Invalid filename specified" );
113 return FALSE;
114 }
115
116 bool ok = TRUE;
117 if ( isRaw() ) { // raw file I/O
118 int oflags = QT_OPEN_RDONLY;
119 if ( isReadable() && isWritable() )
120 oflags = QT_OPEN_RDWR;
121 else if ( isWritable() )
122 oflags = QT_OPEN_WRONLY;
123 if ( flags() & IO_Append ) { // append to end of file?
124 if ( flags() & IO_Truncate )
125 oflags |= (QT_OPEN_CREAT | QT_OPEN_TRUNC);
126 else
127 oflags |= (QT_OPEN_APPEND | QT_OPEN_CREAT);
128 setFlags( flags() | IO_WriteOnly ); // append implies write
129 } else if ( isWritable() ) { // create/trunc if writable
130 if ( flags() & IO_Truncate )
131 oflags |= (QT_OPEN_CREAT | QT_OPEN_TRUNC);
132 else
133 oflags |= QT_OPEN_CREAT;
134 }
135#if defined(HAS_TEXT_FILEMODE)
136 if ( isTranslated() )
137 oflags |= QT_OPEN_TEXT;
138 else
139 oflags |= QT_OPEN_BINARY;
140#endif
141#if defined(HAS_ASYNC_FILEMODE)
142 if ( isAsynchronous() )
143 oflags |= QT_OPEN_ASYNC;
144#endif
145 fd = QT_OPEN( QFile::encodeName( fn ), oflags, 0666 );
146
147 if ( fd != -1 ) { // open successful
148 QT_STATBUF st;
149 QT_FSTAT( fd, &st );
150 if ( (st.st_mode& QT_STAT_MASK) == QT_STAT_DIR ) {
151 ok = FALSE;
152 } else {
153 length = (int)st.st_size;
154 ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
155 }
156 } else {
157 ok = FALSE;
158 }
159 } else { // buffered file I/O
160 QCString perm;
161 char perm2[4];
162 bool try_create = FALSE;
163 if ( flags() & IO_Append ) { // append to end of file?
164 setFlags( flags() | IO_WriteOnly ); // append implies write
165 perm = isReadable() ? "a+" : "a";
166 } else {
167 if ( isReadWrite() ) {
168 if ( flags() & IO_Truncate ) {
169 perm = "w+";
170 } else {
171 perm = "r+";
172 try_create = TRUE; // try to create if not exists
173 }
174 } else if ( isReadable() ) {
175 perm = "r";
176 } else if ( isWritable() ) {
177 perm = "w";
178 }
179 }
180 qstrcpy( perm2, perm );
181#if defined(HAS_TEXT_FILEMODE)
182 if ( isTranslated() )
183 strcat( perm2, "t" );
184 else
185 strcat( perm2, "b" );
186#endif
187 for (;;) { // At most twice
188 fh = fopen( QFile::encodeName( fn ), perm2 );
189 if ( errno == EACCES )
190 break;
191 if ( !fh && try_create ) {
192 perm2[0] = 'w'; // try "w+" instead of "r+"
193 try_create = FALSE;
194 } else {
195 break;
196 }
197 }
198 if ( fh ) {
199 QT_STATBUF st;
200 QT_FSTAT( QT_FILENO(fh), &st );
201 if ( (st.st_mode& QT_STAT_MASK) == QT_STAT_DIR ) {
202 ok = FALSE;
203 } else {
204 length = (int)st.st_size;
205 ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
206 }
207 } else {
208 ok = FALSE;
209 }
210 }
211 if ( ok ) {
212 setState( IO_Open );
213 } else {
214 init();
215 if ( errno == EMFILE ) // no more file handles/descrs
216 setStatus( IO_ResourceError );
217 else
218 setStatus( IO_OpenError );
219 setErrorStringErrno( errno );
220 }
221 return ok;
222}
223
224
225
226bool QFile::open( int m, FILE *f )
227{
228 if ( isOpen() ) {
229#if defined(QT_CHECK_RANGE)
230 qWarning( "QFile::open: File already open" );
231#endif
232 return FALSE;
233 }
234 init();
235 setMode( m &~IO_Raw );
236 setState( IO_Open );
237 fh = f;
238 ext_f = TRUE;
239 QT_STATBUF st;
240 QT_FSTAT( QT_FILENO(fh), &st );
241 ioIndex = (int)ftell( fh );
242 if ( (st.st_mode & QT_STAT_MASK) != QT_STAT_REG ) {
243 // non-seekable
244 setType( IO_Sequential );
245 length = INT_MAX;
246 } else {
247 length = (int)st.st_size;
248 }
249 return TRUE;
250}
251
252
253bool QFile::open( int m, int f )
254{
255 if ( isOpen() ) {
256#if defined(QT_CHECK_RANGE)
257 qWarning( "QFile::open: File already open" );
258#endif
259 return FALSE;
260 }
261 init();
262 setMode( m |IO_Raw );
263 setState( IO_Open );
264 fd = f;
265 ext_f = TRUE;
266 QT_STATBUF st;
267 QT_FSTAT( fd, &st );
268 ioIndex = (int)QT_LSEEK(fd, 0, SEEK_CUR);
269 if ( (st.st_mode & QT_STAT_MASK) != QT_STAT_REG ) {
270 // non-seekable
271 setType( IO_Sequential );
272 length = INT_MAX;
273 } else {
274 length = (int)st.st_size;
275 }
276 return TRUE;
277}
278
279QIODevice::Offset QFile::size() const
280{
281 QT_STATBUF st;
282 int ret = 0;
283 if ( isOpen() ) {
284 ret = QT_FSTAT( fh ? QT_FILENO(fh) : fd, &st );
285 } else {
286 ret = QT_STAT( QFile::encodeName( fn ), &st);
287 }
288 if ( ret == -1 )
289 return 0;
290 return st.st_size;
291}
292
293bool QFile::at( Offset pos )
294{
295 if ( !isOpen() ) {
296#if defined(QT_CHECK_STATE)
297 qWarning( "QFile::at: File is not open" );
298#endif
299 return FALSE;
300 }
301 bool okay;
302 if ( isRaw() ) { // raw file
303 pos = (int)QT_LSEEK(fd, pos, SEEK_SET);
304 okay = pos != (Q_ULONG)-1;
305 } else { // buffered file
306 okay = fseek(fh, pos, SEEK_SET) == 0;
307 }
308 if ( okay )
309 ioIndex = pos;
310#if defined(QT_CHECK_RANGE)
311 else
312 qWarning( "QFile::at: Cannot set file position %lu", pos );
313#endif
314 return okay;
315}
316
317Q_LONG QFile::readBlock( char *p, Q_ULONG len )
318{
319 if ( !len ) // nothing to do
320 return 0;
321
322#if defined(QT_CHECK_NULL)
323 if ( !p )
324 qWarning( "QFile::readBlock: Null pointer error" );
325#endif
326#if defined(QT_CHECK_STATE)
327 if ( !isOpen() ) { // file not open
328 qWarning( "QFile::readBlock: File not open" );
329 return -1;
330 }
331 if ( !isReadable() ) { // reading not permitted
332 qWarning( "QFile::readBlock: Read operation not permitted" );
333 return -1;
334 }
335#endif
336 Q_ULONG nread = 0; // number of bytes read
337 if ( !ungetchBuffer.isEmpty() ) {
338 // need to add these to the returned string.
339 Q_ULONG l = ungetchBuffer.length();
340 while( nread < l ) {
341 *p = ungetchBuffer[ int(l - nread - 1) ];
342 p++;
343 nread++;
344 }
345 ungetchBuffer.truncate( l - nread );
346 }
347
348 if( nread < len ) {
349 if ( isRaw() ) { // raw file
350 nread += QT_READ( fd, p, len - nread );
351 if ( len && nread <= 0 ) {
352 nread = 0;
353 setStatus(IO_ReadError);
354 setErrorStringErrno( errno );
355 }
356 } else { // buffered file
357 nread += fread( p, 1, len - nread, fh );
358 if ( (uint)nread != len ) {
359 if ( ferror( fh ) || nread==0 ) {
360 setStatus(IO_ReadError);
361 setErrorString( qt_fileerr_read );
362 }
363 }
364 }
365 }
366 ioIndex += nread;
367 return nread;
368}
369
370Q_LONG QFile::writeBlock( const char *p, Q_ULONG len )
371{
372 if ( !len ) // nothing to do
373 return 0;
374
375#if defined(QT_CHECK_NULL)
376 if ( p == 0 && len != 0 )
377 qWarning( "QFile::writeBlock: Null pointer error" );
378#endif
379#if defined(QT_CHECK_STATE)
380 if ( !isOpen() ) { // file not open
381 qWarning( "QFile::writeBlock: File not open" );
382 return -1;
383 }
384 if ( !isWritable() ) { // writing not permitted
385 qWarning( "QFile::writeBlock: Write operation not permitted" );
386 return -1;
387 }
388#endif
389 Q_ULONG nwritten; // number of bytes written
390 if ( isRaw() ) // raw file
391 nwritten = QT_WRITE( fd, p, len );
392 else // buffered file
393 nwritten = fwrite( p, 1, len, fh );
394 if ( nwritten != len ) { // write error
395 if ( errno == ENOSPC ) // disk is full
396 setStatus( IO_ResourceError );
397 else
398 setStatus( IO_WriteError );
399 setErrorStringErrno( errno );
400 if ( isRaw() ) // recalc file position
401 ioIndex = (int)QT_LSEEK( fd, 0, SEEK_CUR );
402 else
403 ioIndex = fseek( fh, 0, SEEK_CUR );
404 } else {
405 ioIndex += nwritten;
406 }
407 if ( ioIndex > length ) // update file length
408 length = ioIndex;
409 return nwritten;
410}
411
412int QFile::handle() const
413{
414 if ( !isOpen() )
415 return -1;
416 else if ( fh )
417 return QT_FILENO( fh );
418 else
419 return fd;
420}
421
422void QFile::close()
423{
424 bool ok = FALSE;
425 if ( isOpen() ) { // file is not open
426 if ( fh ) { // buffered file
427 if ( ext_f )
428 ok = fflush( fh ) != -1; // flush instead of closing
429 else
430 ok = fclose( fh ) != -1;
431 } else { // raw file
432 if ( ext_f )
433 ok = TRUE; // cannot close
434 else
435 ok = QT_CLOSE( fd ) != -1;
436 }
437 init(); // restore internal state
438 }
439 if (!ok) {
440 setStatus (IO_UnspecifiedError);
441 setErrorStringErrno( errno );
442 }
443
444 return;
445}
Note: See TracBrowser for help on using the repository browser.