Blame qtools/qfile_unix.cpp

Packit Service 50c9f2
/****************************************************************************
Packit Service 50c9f2
** 
Packit Service 50c9f2
**
Packit Service 50c9f2
** Implementation of QFileInfo class
Packit Service 50c9f2
**
Packit Service 50c9f2
** Created : 950628
Packit Service 50c9f2
**
Packit Service 50c9f2
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is part of the tools module of the Qt GUI Toolkit.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed under the terms of the Q Public License
Packit Service 50c9f2
** as defined by Trolltech AS of Norway and appearing in the file
Packit Service 50c9f2
** LICENSE.QPL included in the packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed and/or modified under the terms of the
Packit Service 50c9f2
** GNU General Public License version 2 as published by the Free Software
Packit Service 50c9f2
** Foundation and appearing in the file LICENSE.GPL included in the
Packit Service 50c9f2
** packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
Packit Service 50c9f2
** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
Packit Service 50c9f2
** with the Qt Commercial License Agreement provided with the Software.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
Packit Service 50c9f2
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Packit Service 50c9f2
**
Packit Service 50c9f2
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
Packit Service 50c9f2
**   information about Qt Commercial License Agreements.
Packit Service 50c9f2
** See http://www.trolltech.com/qpl/ for QPL licensing information.
Packit Service 50c9f2
** See http://www.trolltech.com/gpl/ for GPL licensing information.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Contact info@trolltech.com if any conditions of this licensing are
Packit Service 50c9f2
** not clear to you.
Packit Service 50c9f2
**
Packit Service 50c9f2
**********************************************************************/
Packit Service 50c9f2
Packit Service 50c9f2
#include "qglobal.h"
Packit Service 50c9f2
Packit Service 50c9f2
#include "qfile.h"
Packit Service 50c9f2
#include "qfiledefs_p.h"
Packit Service 50c9f2
Packit Service 50c9f2
#if (defined(_OS_MAC_) && (!defined(_OS_UNIX_))) || defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_) || defined(_OS_CYGWIN_)
Packit Service 50c9f2
# define HAS_TEXT_FILEMODE			// has translate/text filemode
Packit Service 50c9f2
#endif
Packit Service 50c9f2
#if defined(O_NONBLOCK)
Packit Service 50c9f2
# define HAS_ASYNC_FILEMODE
Packit Service 50c9f2
# define OPEN_ASYNC O_NONBLOCK
Packit Service 50c9f2
#elif defined(O_NDELAY)
Packit Service 50c9f2
# define HAS_ASYNC_FILEMODE
Packit Service 50c9f2
# define OPEN_ASYNC O_NDELAY
Packit Service 50c9f2
#endif
Packit Service 50c9f2
Packit Service 50c9f2
bool qt_file_access( const QString& fn, int t )
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( fn.isEmpty() )
Packit Service 50c9f2
	return FALSE;
Packit Service 50c9f2
    return ACCESS( QFile::encodeName(fn), t ) == 0;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Removes the file \a fileName.
Packit Service 50c9f2
  Returns TRUE if successful, otherwise FALSE.
Packit Service 50c9f2
*/
Packit Service 50c9f2
Packit Service 50c9f2
bool QFile::remove( const QString &fileName )
Packit Service 50c9f2
{
Packit Service 50c9f2
    if ( fileName.isEmpty() ) {
Packit Service 50c9f2
#if defined(CHECK_NULL)
Packit Service 50c9f2
	qWarning( "QFile::remove: Empty or null file name" );
Packit Service 50c9f2
#endif
Packit Service 50c9f2
	return FALSE;
Packit Service 50c9f2
    }
Packit Service 50c9f2
    return unlink( QFile::encodeName(fileName) ) == 0;	
Packit Service 50c9f2
    // unlink more common in UNIX
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
#if defined(O_NONBLOCK)
Packit Service 50c9f2
# define HAS_ASYNC_FILEMODE
Packit Service 50c9f2
# define OPEN_ASYNC O_NONBLOCK
Packit Service 50c9f2
#elif defined(O_NDELAY)
Packit Service 50c9f2
# define HAS_ASYNC_FILEMODE
Packit Service 50c9f2
# define OPEN_ASYNC O_NDELAY
Packit Service 50c9f2
#endif
Packit Service 50c9f2
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  Opens the file specified by the file name currently set, using the mode \e m.
Packit Service 50c9f2
  Returns TRUE if successful, otherwise FALSE.
Packit Service 50c9f2
Packit Service 50c9f2
  The mode parameter \e m must be a combination of the following flags:
Packit Service 50c9f2
  
    Packit Service 50c9f2
      
  • \c IO_Raw specified raw (non-buffered) file access.
  • Packit Service 50c9f2
      
  • \c IO_ReadOnly opens the file in read-only mode.
  • Packit Service 50c9f2
      
  • \c IO_WriteOnly opens the file in write-only mode (and truncates).
  • Packit Service 50c9f2
      
  • \c IO_ReadWrite opens the file in read/write mode, equivalent to
  • Packit Service 50c9f2
      \c (IO_ReadOnly|IO_WriteOnly).
    Packit Service 50c9f2
      
  • \c IO_Append opens the file in append mode. This mode is very useful
  • Packit Service 50c9f2
      when you want to write something to a log file. The file index is set to
    Packit Service 50c9f2
      the end of the file. Note that the result is undefined if you position the
    Packit Service 50c9f2
      file index manually using at() in append mode.
    Packit Service 50c9f2
      
  • \c IO_Truncate truncates the file.
  • Packit Service 50c9f2
      
  • \c IO_Translate enables carriage returns and linefeed translation
  • Packit Service 50c9f2
      for text files under MS-DOS, Windows and OS/2.
    Packit Service 50c9f2
      
    Packit Service 50c9f2
    Packit Service 50c9f2
      The raw access mode is best when I/O is block-operated using 4kB block size
    Packit Service 50c9f2
      or greater. Buffered access works better when reading small portions of
    Packit Service 50c9f2
      data at a time.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Important: When working with buffered files, data may
    Packit Service 50c9f2
      not be written to the file at once. Call \link flush() flush\endlink
    Packit Service 50c9f2
      to make sure the data is really written.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \warning We have experienced problems with some C libraries when a buffered
    Packit Service 50c9f2
      file is opened for both reading and writing. If a read operation takes place
    Packit Service 50c9f2
      immediately after a write operation, the read buffer contains garbage data.
    Packit Service 50c9f2
      Worse, the same garbage is written to the file. Calling flush() before
    Packit Service 50c9f2
      readBlock() solved this problem.
    Packit Service 50c9f2
    Packit Service 50c9f2
      If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite is
    Packit Service 50c9f2
      specified, it is created.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Example:
    Packit Service 50c9f2
      \code
    Packit Service 50c9f2
        QFile f1( "/tmp/data.bin" );
    Packit Service 50c9f2
        QFile f2( "readme.txt" );
    Packit Service 50c9f2
        f1.open( IO_Raw | IO_ReadWrite | IO_Append );
    Packit Service 50c9f2
        f2.open( IO_ReadOnly | IO_Translate );
    Packit Service 50c9f2
      \endcode
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa name(), close(), isOpen(), flush()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    bool QFile::open( int m )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        if ( isOpen() ) {				// file already open
    Packit Service 50c9f2
    #if defined(CHECK_STATE)
    Packit Service 50c9f2
    	qWarning( "QFile::open: File already open" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	return FALSE;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if ( fn.isNull() ) {			// no file name defined
    Packit Service 50c9f2
    #if defined(CHECK_NULL)
    Packit Service 50c9f2
    	qWarning( "QFile::open: No file name specified" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	return FALSE;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        init();					// reset params
    Packit Service 50c9f2
        setMode( m );
    Packit Service 50c9f2
        if ( !(isReadable() || isWritable()) ) {
    Packit Service 50c9f2
    #if defined(CHECK_RANGE)
    Packit Service 50c9f2
    	qWarning( "QFile::open: File access not specified" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	return FALSE;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        bool ok = TRUE;
    Packit Service 50c9f2
        STATBUF st;
    Packit Service 50c9f2
        if ( isRaw() ) {				// raw file I/O
    Packit Service 50c9f2
    	int oflags = OPEN_RDONLY;
    Packit Service 50c9f2
    	if ( isReadable() && isWritable() )
    Packit Service 50c9f2
    	    oflags = OPEN_RDWR;
    Packit Service 50c9f2
    	else if ( isWritable() )
    Packit Service 50c9f2
    	    oflags = OPEN_WRONLY;
    Packit Service 50c9f2
    	if ( flags() & IO_Append ) {		// append to end of file?
    Packit Service 50c9f2
    	    if ( flags() & IO_Truncate )
    Packit Service 50c9f2
    		oflags |= (OPEN_CREAT | OPEN_TRUNC);
    Packit Service 50c9f2
    	    else
    Packit Service 50c9f2
    		oflags |= (OPEN_APPEND | OPEN_CREAT);
    Packit Service 50c9f2
    	    setFlags( flags() | IO_WriteOnly ); // append implies write
    Packit Service 50c9f2
    	} else if ( isWritable() ) {		// create/trunc if writable
    Packit Service 50c9f2
    	    if ( flags() & IO_Truncate )
    Packit Service 50c9f2
    		oflags |= (OPEN_CREAT | OPEN_TRUNC);
    Packit Service 50c9f2
    	    else
    Packit Service 50c9f2
    		oflags |= OPEN_CREAT;
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
    #if defined(HAS_TEXT_FILEMODE)
    Packit Service 50c9f2
    	if ( isTranslated() )
    Packit Service 50c9f2
    #ifdef __CYGWIN__
    Packit Service 50c9f2
              /* Do nothing, allowing the Cygwin mount mode to take effect. */;
    Packit Service 50c9f2
    #else
    Packit Service 50c9f2
    	    oflags |= OPEN_TEXT;
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	else
    Packit Service 50c9f2
    	    oflags |= OPEN_BINARY;
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    #if defined(HAS_ASYNC_FILEMODE)
    Packit Service 50c9f2
    	if ( isAsynchronous() )
    Packit Service 50c9f2
    	    oflags |= OPEN_ASYNC;
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	fd = OPEN( QFile::encodeName(fn), oflags, 0666 );
    Packit Service 50c9f2
    Packit Service 50c9f2
    	if ( fd != -1 ) {			// open successful
    Packit Service 50c9f2
    	    FSTAT( fd, &st ); // get the stat for later usage
    Packit Service 50c9f2
    	} else {
    Packit Service 50c9f2
    	    ok = FALSE;
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
        } else {					// buffered file I/O
    Packit Service 50c9f2
    	QCString perm;
    Packit Service 50c9f2
    	char perm2[4];
    Packit Service 50c9f2
    	bool try_create = FALSE;
    Packit Service 50c9f2
    	if ( flags() & IO_Append ) {		// append to end of file?
    Packit Service 50c9f2
    	    setFlags( flags() | IO_WriteOnly ); // append implies write
    Packit Service 50c9f2
    	    perm = isReadable() ? "a+" : "a";
    Packit Service 50c9f2
    	} else {
    Packit Service 50c9f2
    	    if ( isReadWrite() ) {
    Packit Service 50c9f2
    		if ( flags() & IO_Truncate ) {
    Packit Service 50c9f2
    		    perm = "w+";
    Packit Service 50c9f2
    		} else {
    Packit Service 50c9f2
    		    perm = "r+";
    Packit Service 50c9f2
    		    try_create = TRUE;		// try to create if not exists
    Packit Service 50c9f2
    		}
    Packit Service 50c9f2
    	    } else if ( isReadable() ) {
    Packit Service 50c9f2
    		perm = "r";
    Packit Service 50c9f2
    	    } else if ( isWritable() ) {
    Packit Service 50c9f2
    		perm = "w";
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
    	qstrcpy( perm2, perm );
    Packit Service 50c9f2
    #if defined(HAS_TEXT_FILEMODE)
    Packit Service 50c9f2
    	if ( isTranslated() )
    Packit Service 50c9f2
    #ifdef __CYGWIN__
    Packit Service 50c9f2
                /* Do nothing, allowing the Cygwin mount mode to take effect. */;
    Packit Service 50c9f2
    #else
    Packit Service 50c9f2
    	    strcat( perm2, "t" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	else
    Packit Service 50c9f2
    	    strcat( perm2, "b" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	while (1) { // At most twice
    Packit Service 50c9f2
    Packit Service 50c9f2
    	    fh = fopen( QFile::encodeName(fn), perm2 );
    Packit Service 50c9f2
    Packit Service 50c9f2
    	    if ( !fh && try_create ) {
    Packit Service 50c9f2
    		perm2[0] = 'w';			// try "w+" instead of "r+"
    Packit Service 50c9f2
    		try_create = FALSE;
    Packit Service 50c9f2
    	    } else {
    Packit Service 50c9f2
    		break;
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
    	if ( fh ) {
    Packit Service 50c9f2
    	    FSTAT( FILENO(fh), &st ); // get the stat for later usage
    Packit Service 50c9f2
    	} else {
    Packit Service 50c9f2
    	    ok = FALSE;
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if ( ok ) {
    Packit Service 50c9f2
    	setState( IO_Open );
    Packit Service 50c9f2
    	// on successful open the file stat was got; now test what type
    Packit Service 50c9f2
    	// of file we have
    Packit Service 50c9f2
    	if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
    Packit Service 50c9f2
    	    // non-seekable
    Packit Service 50c9f2
    	    setType( IO_Sequential );
    Packit Service 50c9f2
    	    length = INT_MAX;
    Packit Service 50c9f2
    	    ioIndex  = (flags() & IO_Append) == 0 ? 0 : length;
    Packit Service 50c9f2
    	} else {
    Packit Service 50c9f2
    	    length = (int)st.st_size;
    Packit Service 50c9f2
    	    ioIndex  = (flags() & IO_Append) == 0 ? 0 : length;
    Packit Service 50c9f2
    	    if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
    Packit Service 50c9f2
    		// try if you can read from it (if you can, it's a sequential
    Packit Service 50c9f2
    		// device; e.g. a file in the /proc filesystem)
    Packit Service 50c9f2
    		int c = getch();
    Packit Service 50c9f2
    		if ( c != -1 ) {
    Packit Service 50c9f2
    		    ungetch(c);
    Packit Service 50c9f2
    		    setType( IO_Sequential );
    Packit Service 50c9f2
    		    length = INT_MAX;
    Packit Service 50c9f2
    		}
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
        } else {
    Packit Service 50c9f2
    	init();
    Packit Service 50c9f2
    	if ( errno == EMFILE )			// no more file handles/descrs
    Packit Service 50c9f2
    	    setStatus( IO_ResourceError );
    Packit Service 50c9f2
    	else
    Packit Service 50c9f2
    	    setStatus( IO_OpenError );
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        return ok;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Opens a file in the mode \e m using an existing file handle \e f.
    Packit Service 50c9f2
      Returns TRUE if successful, otherwise FALSE.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Example:
    Packit Service 50c9f2
      \code
    Packit Service 50c9f2
        #include <stdio.h>
    Packit Service 50c9f2
    Packit Service 50c9f2
        void printError( const char* msg )
    Packit Service 50c9f2
        {
    Packit Service 50c9f2
    	QFile f;
    Packit Service 50c9f2
    	f.open( IO_WriteOnly, stderr );
    Packit Service 50c9f2
    	f.writeBlock( msg, qstrlen(msg) );	// write to stderr
    Packit Service 50c9f2
    	f.close();
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
      \endcode
    Packit Service 50c9f2
    Packit Service 50c9f2
      When a QFile is opened using this function, close() does not actually
    Packit Service 50c9f2
      close the file, only flushes it.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \warning If \e f is \c stdin, \c stdout, \c stderr, you may not
    Packit Service 50c9f2
      be able to seek.  See QIODevice::isSequentialAccess() for more
    Packit Service 50c9f2
      information.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa close()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    bool QFile::open( int m, FILE *f )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        if ( isOpen() ) {
    Packit Service 50c9f2
    #if defined(CHECK_RANGE)
    Packit Service 50c9f2
    	qWarning( "QFile::open: File already open" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	return FALSE;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        init();
    Packit Service 50c9f2
        setMode( m &~IO_Raw );
    Packit Service 50c9f2
        setState( IO_Open );
    Packit Service 50c9f2
        fh = f;
    Packit Service 50c9f2
        ext_f = TRUE;
    Packit Service 50c9f2
        STATBUF st;
    Packit Service 50c9f2
        FSTAT( FILENO(fh), &st );
    Packit Service 50c9f2
        ioIndex = (int)ftell( fh );
    Packit Service 50c9f2
        if ( (st.st_mode & STAT_MASK) != STAT_REG || f == stdin ) { //stdin is non seekable
    Packit Service 50c9f2
    	// non-seekable
    Packit Service 50c9f2
    	setType( IO_Sequential );
    Packit Service 50c9f2
    	length = INT_MAX;
    Packit Service 50c9f2
        } else {
    Packit Service 50c9f2
    	length = (int)st.st_size;
    Packit Service 50c9f2
    	if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
    Packit Service 50c9f2
    	    // try if you can read from it (if you can, it's a sequential
    Packit Service 50c9f2
    	    // device; e.g. a file in the /proc filesystem)
    Packit Service 50c9f2
    	    int c = getch();
    Packit Service 50c9f2
    	    if ( c != -1 ) {
    Packit Service 50c9f2
    		ungetch(c);
    Packit Service 50c9f2
    		setType( IO_Sequential );
    Packit Service 50c9f2
    		length = INT_MAX;
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        return TRUE;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Opens a file in the mode \e m using an existing file descriptor \e f.
    Packit Service 50c9f2
      Returns TRUE if successful, otherwise FALSE.
    Packit Service 50c9f2
    Packit Service 50c9f2
      When a QFile is opened using this function, close() does not actually
    Packit Service 50c9f2
      close the file.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \warning If \e f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
    Packit Service 50c9f2
      be able to seek. size() is set to \c INT_MAX (in limits.h).
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa close()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    Packit Service 50c9f2
    bool QFile::open( int m, int f )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        if ( isOpen() ) {
    Packit Service 50c9f2
    #if defined(CHECK_RANGE)
    Packit Service 50c9f2
    	qWarning( "QFile::open: File already open" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	return FALSE;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        init();
    Packit Service 50c9f2
        setMode( m |IO_Raw );
    Packit Service 50c9f2
        setState( IO_Open );
    Packit Service 50c9f2
        fd = f;
    Packit Service 50c9f2
        ext_f = TRUE;
    Packit Service 50c9f2
        STATBUF st;
    Packit Service 50c9f2
        FSTAT( fd, &st );
    Packit Service 50c9f2
        ioIndex  = (int)LSEEK(fd, 0, SEEK_CUR);
    Packit Service 50c9f2
        if ( (st.st_mode & STAT_MASK) != STAT_REG || f == 0 ) { // stdin is not seekable...
    Packit Service 50c9f2
    	// non-seekable
    Packit Service 50c9f2
    	setType( IO_Sequential );
    Packit Service 50c9f2
    	length = INT_MAX;
    Packit Service 50c9f2
        } else {
    Packit Service 50c9f2
    	length = (int)st.st_size;
    Packit Service 50c9f2
    	if ( length == 0 && isReadable() ) {
    Packit Service 50c9f2
    	    // try if you can read from it (if you can, it's a sequential
    Packit Service 50c9f2
    	    // device; e.g. a file in the /proc filesystem)
    Packit Service 50c9f2
    	    int c = getch();
    Packit Service 50c9f2
    	    if ( c != -1 ) {
    Packit Service 50c9f2
    		ungetch(c);
    Packit Service 50c9f2
    		setType( IO_Sequential );
    Packit Service 50c9f2
    		length = INT_MAX;
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	    resetStatus();
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        return TRUE;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Returns the file size.
    Packit Service 50c9f2
      \sa at()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    uint QFile::size() const
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        STATBUF st;
    Packit Service 50c9f2
        if ( isOpen() ) {
    Packit Service 50c9f2
    	FSTAT( fh ? FILENO(fh) : fd, &st );
    Packit Service 50c9f2
        } else {
    Packit Service 50c9f2
    	STAT( QFile::encodeName(fn), &st );
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        return (uint)st.st_size;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      \fn int QFile::at() const
    Packit Service 50c9f2
      Returns the file index.
    Packit Service 50c9f2
      \sa size()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Sets the file index to \e pos. Returns TRUE if successful, otherwise FALSE.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Example:
    Packit Service 50c9f2
      \code
    Packit Service 50c9f2
        QFile f( "data.bin" );
    Packit Service 50c9f2
        f.open( IO_ReadOnly );			// index set to 0
    Packit Service 50c9f2
        f.at( 100 );				// set index to 100
    Packit Service 50c9f2
        f.at( f.at()+50 );				// set index to 150
    Packit Service 50c9f2
        f.at( f.size()-80 );			// set index to 80 before EOF
    Packit Service 50c9f2
        f.close();
    Packit Service 50c9f2
      \endcode
    Packit Service 50c9f2
    Packit Service 50c9f2
      \warning The result is undefined if the file was \link open() opened\endlink
    Packit Service 50c9f2
      using the \c IO_Append specifier.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa size(), open()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    bool QFile::at( int pos )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        if ( !isOpen() ) {
    Packit Service 50c9f2
    #if defined(CHECK_STATE)
    Packit Service 50c9f2
    	qWarning( "QFile::at: File is not open" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    	return FALSE;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        bool ok;
    Packit Service 50c9f2
        if ( isRaw() ) {				// raw file
    Packit Service 50c9f2
    	pos = (int)LSEEK(fd, pos, SEEK_SET);
    Packit Service 50c9f2
    	ok = pos != -1;
    Packit Service 50c9f2
        } else {					// buffered file
    Packit Service 50c9f2
    	ok = fseek(fh, pos, SEEK_SET) == 0;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if ( ok )
    Packit Service 50c9f2
    	ioIndex = pos;
    Packit Service 50c9f2
    #if defined(CHECK_RANGE)
    Packit Service 50c9f2
        else
    Packit Service 50c9f2
    	qWarning( "QFile::at: Cannot set file position %d", pos );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
        return ok;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Reads at most \e len bytes from the file into \e p and returns the
    Packit Service 50c9f2
      number of bytes actually read.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Returns -1 if a serious error occurred.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \warning We have experienced problems with some C libraries when a buffered
    Packit Service 50c9f2
      file is opened for both reading and writing. If a read operation takes place
    Packit Service 50c9f2
      immediately after a write operation, the read buffer contains garbage data.
    Packit Service 50c9f2
      Worse, the same garbage is written to the file. Calling flush() before
    Packit Service 50c9f2
      readBlock() solved this problem.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa writeBlock()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    int QFile::readBlock( char *p, uint len )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
    #if defined(CHECK_NULL)
    Packit Service 50c9f2
        if ( !p )
    Packit Service 50c9f2
    	qWarning( "QFile::readBlock: Null pointer error" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    #if defined(CHECK_STATE)
    Packit Service 50c9f2
        if ( !isOpen() ) {				// file not open
    Packit Service 50c9f2
    	qWarning( "QFile::readBlock: File not open" );
    Packit Service 50c9f2
    	return -1;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if ( !isReadable() ) {			// reading not permitted
    Packit Service 50c9f2
    	qWarning( "QFile::readBlock: Read operation not permitted" );
    Packit Service 50c9f2
    	return -1;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
        int nread = 0;					// number of bytes read
    Packit Service 50c9f2
        if ( !ungetchBuffer.isEmpty() ) {
    Packit Service 50c9f2
    	// need to add these to the returned string.
    Packit Service 50c9f2
    	int l = ungetchBuffer.length();
    Packit Service 50c9f2
    	while( nread < l ) {
    Packit Service 50c9f2
    	    *p = ungetchBuffer[ l - nread - 1 ];
    Packit Service 50c9f2
    	    p++;
    Packit Service 50c9f2
    	    nread++;
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
    	ungetchBuffer.truncate( l - nread );
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        
    Packit Service 50c9f2
        if ( nread < (int)len ) {
    Packit Service 50c9f2
    	if ( isRaw() ) {				// raw file
    Packit Service 50c9f2
    	    nread += (int)READ( fd, p, len-nread );
    Packit Service 50c9f2
    	    if ( len && nread <= 0 ) {
    Packit Service 50c9f2
    		nread = 0;
    Packit Service 50c9f2
    		setStatus(IO_ReadError);
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	} else {					// buffered file
    Packit Service 50c9f2
    	    nread += (int)fread( p, 1, len-nread, fh );
    Packit Service 50c9f2
    	    if ( (uint)nread != len ) {
    Packit Service 50c9f2
    		if ( ferror( fh ) || nread==0 )
    Packit Service 50c9f2
    		    setStatus(IO_ReadError);
    Packit Service 50c9f2
    	    }
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        ioIndex += nread;
    Packit Service 50c9f2
        return nread;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*! \overload int writeBlock( const QByteArray& data )
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*! \reimp
    Packit Service 50c9f2
    Packit Service 50c9f2
      Writes \e len bytes from \e p to the file and returns the number of
    Packit Service 50c9f2
      bytes actually written.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Returns -1 if a serious error occurred.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \warning When working with buffered files, data may not be written
    Packit Service 50c9f2
      to the file at once. Call flush() to make sure the data is really
    Packit Service 50c9f2
      written.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa readBlock()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    int QFile::writeBlock( const char *p, uint len )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
    #if defined(CHECK_NULL)
    Packit Service 50c9f2
        if ( p == 0 && len != 0 )
    Packit Service 50c9f2
    	qWarning( "QFile::writeBlock: Null pointer error" );
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
    #if defined(CHECK_STATE)
    Packit Service 50c9f2
        if ( !isOpen() ) {				// file not open
    Packit Service 50c9f2
    	qWarning( "QFile::writeBlock: File not open" );
    Packit Service 50c9f2
    	return -1;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if ( !isWritable() ) {			// writing not permitted
    Packit Service 50c9f2
    	qWarning( "QFile::writeBlock: Write operation not permitted" );
    Packit Service 50c9f2
    	return -1;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
    #endif
    Packit Service 50c9f2
        if (p==0) return 0;
    Packit Service 50c9f2
        int nwritten;				// number of bytes written
    Packit Service 50c9f2
        if ( isRaw() )				// raw file
    Packit Service 50c9f2
    	nwritten = (int)WRITE( fd, p, len );
    Packit Service 50c9f2
        else					// buffered file
    Packit Service 50c9f2
    	nwritten = (int)fwrite( p, 1, len, fh );
    Packit Service 50c9f2
        if ( nwritten != (int)len ) {		// write error
    Packit Service 50c9f2
    	if ( errno == ENOSPC )			// disk is full
    Packit Service 50c9f2
    	    setStatus( IO_ResourceError );
    Packit Service 50c9f2
    	else
    Packit Service 50c9f2
    	    setStatus( IO_WriteError );
    Packit Service 50c9f2
    	if ( isRaw() )				// recalc file position
    Packit Service 50c9f2
    	    ioIndex = (int)LSEEK( fd, 0, SEEK_CUR );
    Packit Service 50c9f2
    	else
    Packit Service 50c9f2
    	    ioIndex = fseek( fh, 0, SEEK_CUR );
    Packit Service 50c9f2
        } else {
    Packit Service 50c9f2
    	ioIndex += nwritten;
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if ( ioIndex > length )			// update file length
    Packit Service 50c9f2
    	length = ioIndex;
    Packit Service 50c9f2
        return nwritten;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Returns the file handle of the file.
    Packit Service 50c9f2
    Packit Service 50c9f2
      This is a small positive integer, suitable for use with C library
    Packit Service 50c9f2
      functions such as fdopen() and fcntl(), as well as with QSocketNotifier.
    Packit Service 50c9f2
    Packit Service 50c9f2
      If the file is not open or there is an error, handle() returns -1.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa QSocketNotifier
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    int QFile::handle() const
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        if ( !isOpen() )
    Packit Service 50c9f2
    	return -1;
    Packit Service 50c9f2
        else if ( fh )
    Packit Service 50c9f2
    	return FILENO( fh );
    Packit Service 50c9f2
        else
    Packit Service 50c9f2
    	return fd;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    /*!
    Packit Service 50c9f2
      Closes an open file.
    Packit Service 50c9f2
    Packit Service 50c9f2
      The file is not closed if it was opened with an existing file handle.
    Packit Service 50c9f2
      If the existing file handle is a \c FILE*, the file is flushed.
    Packit Service 50c9f2
      If the existing file handle is an \c int file descriptor, nothing
    Packit Service 50c9f2
      is done to the file.
    Packit Service 50c9f2
    Packit Service 50c9f2
      Some "write-behind" filesystems may report an unspecified error on
    Packit Service 50c9f2
      closing the file. These errors only indicate that something may
    Packit Service 50c9f2
      have gone wrong since the previous open(). In such a case status()
    Packit Service 50c9f2
      reports IO_UnspecifiedError after close(), otherwise IO_Ok.
    Packit Service 50c9f2
    Packit Service 50c9f2
      \sa open(), flush()
    Packit Service 50c9f2
    */
    Packit Service 50c9f2
    Packit Service 50c9f2
    Packit Service 50c9f2
    void QFile::close()
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
        bool ok = FALSE;
    Packit Service 50c9f2
        if ( isOpen() ) {				// file is not open
    Packit Service 50c9f2
    	if ( fh ) {				// buffered file
    Packit Service 50c9f2
    	    if ( ext_f )
    Packit Service 50c9f2
    		ok = fflush( fh ) != -1;	// flush instead of closing
    Packit Service 50c9f2
    	    else
    Packit Service 50c9f2
    		ok = fclose( fh ) != -1;
    Packit Service 50c9f2
    	} else {				// raw file
    Packit Service 50c9f2
    	    if ( ext_f )
    Packit Service 50c9f2
    		ok = TRUE;			// cannot close
    Packit Service 50c9f2
    	    else
    Packit Service 50c9f2
    		ok = CLOSE( fd ) != -1;
    Packit Service 50c9f2
    	}
    Packit Service 50c9f2
    	init();					// restore internal state
    Packit Service 50c9f2
        }
    Packit Service 50c9f2
        if (!ok)
    Packit Service 50c9f2
    	setStatus (IO_UnspecifiedError);
    Packit Service 50c9f2
    Packit Service 50c9f2
        return;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    int64 QFile::pos() const
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
      if (isOpen())
    Packit Service 50c9f2
      {
    Packit Service 50c9f2
        // TODO: support 64 bit size
    Packit Service 50c9f2
        return ftell( fh );
    Packit Service 50c9f2
      }
    Packit Service 50c9f2
      return -1;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    int64 QFile::toEnd() 
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
      if (isOpen())
    Packit Service 50c9f2
      {
    Packit Service 50c9f2
         // TODO: support 64 bit size
    Packit Service 50c9f2
         if (fseek( fh, 0, SEEK_END )!=-1)
    Packit Service 50c9f2
         {
    Packit Service 50c9f2
           return ftell( fh );
    Packit Service 50c9f2
         }
    Packit Service 50c9f2
      }
    Packit Service 50c9f2
      return -1;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2
    Packit Service 50c9f2
    bool QFile::seek( int64 pos )
    Packit Service 50c9f2
    {
    Packit Service 50c9f2
      if (isOpen())
    Packit Service 50c9f2
      {
    Packit Service 50c9f2
        // TODO: support 64 bit size
    Packit Service 50c9f2
        return fseek( fh, (long)pos, SEEK_SET )!=-1;
    Packit Service 50c9f2
      }
    Packit Service 50c9f2
      return FALSE;
    Packit Service 50c9f2
    }
    Packit Service 50c9f2