summaryrefslogtreecommitdiff
path: root/qmake/tools/qfile_unix.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qfile_unix.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qfile_unix.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/qmake/tools/qfile_unix.cpp b/qmake/tools/qfile_unix.cpp
index 2d5a856..460bf06 100644
--- a/qmake/tools/qfile_unix.cpp
+++ b/qmake/tools/qfile_unix.cpp
@@ -390,101 +390,104 @@ bool QFile::open( int m, FILE *f )
390 390
391bool QFile::open( int m, int f ) 391bool QFile::open( int m, int f )
392{ 392{
393 if ( isOpen() ) { 393 if ( isOpen() ) {
394#if defined(QT_CHECK_RANGE) 394#if defined(QT_CHECK_RANGE)
395 qWarning( "QFile::open: File already open" ); 395 qWarning( "QFile::open: File already open" );
396#endif 396#endif
397 return FALSE; 397 return FALSE;
398 } 398 }
399 init(); 399 init();
400 setMode( m |IO_Raw ); 400 setMode( m |IO_Raw );
401 setState( IO_Open ); 401 setState( IO_Open );
402 fd = f; 402 fd = f;
403 ext_f = TRUE; 403 ext_f = TRUE;
404 struct stat st; 404 struct stat st;
405 ::fstat( fd, &st ); 405 ::fstat( fd, &st );
406 ioIndex = (Offset)::lseek(fd, 0, SEEK_CUR); 406 ioIndex = (Offset)::lseek(fd, 0, SEEK_CUR);
407 if ( (st.st_mode & S_IFMT) != S_IFREG || f == 0 ) { // stdin is not seekable... 407 if ( (st.st_mode & S_IFMT) != S_IFREG || f == 0 ) { // stdin is not seekable...
408 // non-seekable 408 // non-seekable
409 setType( IO_Sequential ); 409 setType( IO_Sequential );
410 length = INT_MAX; 410 length = INT_MAX;
411 ioIndex = 0; 411 ioIndex = 0;
412 } else { 412 } else {
413 length = (Offset)st.st_size; 413 length = (Offset)st.st_size;
414 if ( length == 0 && isReadable() ) { 414 if ( length == 0 && isReadable() ) {
415 // try if you can read from it (if you can, it's a sequential 415 // try if you can read from it (if you can, it's a sequential
416 // device; e.g. a file in the /proc filesystem) 416 // device; e.g. a file in the /proc filesystem)
417 int c = getch(); 417 int c = getch();
418 if ( c != -1 ) { 418 if ( c != -1 ) {
419 ungetch(c); 419 ungetch(c);
420 setType( IO_Sequential ); 420 setType( IO_Sequential );
421 length = INT_MAX; 421 length = INT_MAX;
422 ioIndex = 0; 422 ioIndex = 0;
423 } 423 }
424 resetStatus(); 424 resetStatus();
425 } 425 }
426 } 426 }
427 return TRUE; 427 return TRUE;
428} 428}
429 429
430/*! 430/*!
431 Returns the file size. 431 Returns the file size.
432 \sa at() 432 \sa at()
433*/ 433*/
434 434
435QIODevice::Offset QFile::size() const 435QIODevice::Offset QFile::size() const
436{ 436{
437 struct stat st; 437 struct stat st;
438 int ret = 0;
438 if ( isOpen() ) { 439 if ( isOpen() ) {
439 ::fstat( fh ? fileno(fh) : fd, &st ); 440 ret = ::fstat( fh ? fileno(fh) : fd, &st );
440 } else { 441 } else {
441 ::stat( QFile::encodeName(fn), &st ); 442 ret = ::stat( QFile::encodeName(fn), &st );
442 } 443 }
444 if ( ret == -1 )
445 return 0;
443#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET) 446#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_64BITOFFSET)
444 return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size; 447 return (uint)st.st_size > UINT_MAX ? UINT_MAX : (QIODevice::Offset)st.st_size;
445#else 448#else
446 return st.st_size; 449 return st.st_size;
447#endif 450#endif
448} 451}
449 452
450 453
451/*! 454/*!
452 \overload 455 \overload
453 456
454 Sets the file index to \a pos. Returns TRUE if successful; 457 Sets the file index to \a pos. Returns TRUE if successful;
455 otherwise returns FALSE. 458 otherwise returns FALSE.
456 459
457 Example: 460 Example:
458 \code 461 \code
459 QFile f( "data.bin" ); 462 QFile f( "data.bin" );
460 f.open( IO_ReadOnly ); // index set to 0 463 f.open( IO_ReadOnly ); // index set to 0
461 f.at( 100 ); // set index to 100 464 f.at( 100 ); // set index to 100
462 f.at( f.at()+50 ); // set index to 150 465 f.at( f.at()+50 ); // set index to 150
463 f.at( f.size()-80 ); // set index to 80 before EOF 466 f.at( f.size()-80 ); // set index to 80 before EOF
464 f.close(); 467 f.close();
465 \endcode 468 \endcode
466 469
467 Use \c at() without arguments to retrieve the file offset. 470 Use \c at() without arguments to retrieve the file offset.
468 471
469 \warning The result is undefined if the file was open()'ed using 472 \warning The result is undefined if the file was open()'ed using
470 the \c IO_Append specifier. 473 the \c IO_Append specifier.
471 474
472 \sa size(), open() 475 \sa size(), open()
473*/ 476*/
474 477
475bool QFile::at( Offset pos ) 478bool QFile::at( Offset pos )
476{ 479{
477 if ( !isOpen() ) { 480 if ( !isOpen() ) {
478#if defined(QT_CHECK_STATE) 481#if defined(QT_CHECK_STATE)
479 qWarning( "QFile::at: File is not open" ); 482 qWarning( "QFile::at: File is not open" );
480#endif 483#endif
481 return FALSE; 484 return FALSE;
482 } 485 }
483 if ( isSequentialAccess() ) 486 if ( isSequentialAccess() )
484 return FALSE; 487 return FALSE;
485 bool ok; 488 bool ok;
486 if ( isRaw() ) { 489 if ( isRaw() ) {
487 off_t l = ::lseek( fd, pos, SEEK_SET ); 490 off_t l = ::lseek( fd, pos, SEEK_SET );
488 ok = ( l != -1 ); 491 ok = ( l != -1 );
489 pos = (Offset)l; 492 pos = (Offset)l;
490 } else { // buffered file 493 } else { // buffered file
@@ -493,188 +496,190 @@ bool QFile::at( Offset pos )
493#else 496#else
494 ok = ( ::fseek(fh, pos, SEEK_SET) == 0 ); 497 ok = ( ::fseek(fh, pos, SEEK_SET) == 0 );
495#endif 498#endif
496 } 499 }
497 if ( ok ) 500 if ( ok )
498 ioIndex = pos; 501 ioIndex = pos;
499#if defined(QT_CHECK_RANGE) 502#if defined(QT_CHECK_RANGE)
500 else 503 else
501#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET) 504#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
502 qWarning( "QFile::at: Cannot set file position %llu", pos ); 505 qWarning( "QFile::at: Cannot set file position %llu", pos );
503#else 506#else
504 qWarning( "QFile::at: Cannot set file position %lu", pos ); 507 qWarning( "QFile::at: Cannot set file position %lu", pos );
505#endif 508#endif
506#endif 509#endif
507 return ok; 510 return ok;
508} 511}
509 512
510/*! 513/*!
511 \reimp 514 \reimp
512 515
513 \warning We have experienced problems with some C libraries when a buffered 516 \warning We have experienced problems with some C libraries when a buffered
514 file is opened for both reading and writing. If a read operation takes place 517 file is opened for both reading and writing. If a read operation takes place
515 immediately after a write operation, the read buffer contains garbage data. 518 immediately after a write operation, the read buffer contains garbage data.
516 Worse, the same garbage is written to the file. Calling flush() before 519 Worse, the same garbage is written to the file. Calling flush() before
517 readBlock() solved this problem. 520 readBlock() solved this problem.
518*/ 521*/
519 522
520Q_LONG QFile::readBlock( char *p, Q_ULONG len ) 523Q_LONG QFile::readBlock( char *p, Q_ULONG len )
521{ 524{
522#if defined(QT_CHECK_NULL) 525#if defined(QT_CHECK_NULL)
523 if ( !p ) 526 if ( !p )
524 qWarning( "QFile::readBlock: Null pointer error" ); 527 qWarning( "QFile::readBlock: Null pointer error" );
525#endif 528#endif
526#if defined(QT_CHECK_STATE) 529#if defined(QT_CHECK_STATE)
527 if ( !isOpen() ) { 530 if ( !isOpen() ) {
528 qWarning( "QFile::readBlock: File not open" ); 531 qWarning( "QFile::readBlock: File not open" );
529 return -1; 532 return -1;
530 } 533 }
531 if ( !isReadable() ) { 534 if ( !isReadable() ) {
532 qWarning( "QFile::readBlock: Read operation not permitted" ); 535 qWarning( "QFile::readBlock: Read operation not permitted" );
533 return -1; 536 return -1;
534 } 537 }
535#endif 538#endif
536 Q_ULONG nread = 0; // number of bytes read 539 Q_ULONG nread = 0; // number of bytes read
537 if ( !ungetchBuffer.isEmpty() ) { 540 if ( !ungetchBuffer.isEmpty() ) {
538 // need to add these to the returned string. 541 // need to add these to the returned string.
539 uint l = ungetchBuffer.length(); 542 uint l = ungetchBuffer.length();
540 while( nread < l ) { 543 while( nread < l ) {
541 *p = ungetchBuffer[ l - nread - 1 ]; 544 *p = ungetchBuffer.at( l - nread - 1 );
542 p++; 545 p++;
543 nread++; 546 nread++;
544 } 547 }
545 ungetchBuffer.truncate( l - nread ); 548 ungetchBuffer.truncate( l - nread );
546 } 549 }
547 550
548 if ( nread < len ) { 551 if ( nread < len ) {
549 if ( isRaw() ) { // raw file 552 if ( isRaw() ) { // raw file
550 nread += ::read( fd, p, len-nread ); 553 nread += ::read( fd, p, len-nread );
551 if ( len && nread <= 0 ) { 554 if ( len && nread <= 0 ) {
552 nread = 0; 555 nread = 0;
553 setStatus(IO_ReadError); 556 setStatus(IO_ReadError);
554 } 557 }
555 } else { // buffered file 558 } else { // buffered file
556 nread += fread( p, 1, len-nread, fh ); 559 nread += fread( p, 1, len-nread, fh );
557 if ( (uint)nread != len ) { 560 if ( (uint)nread != len ) {
558 if ( ferror( fh ) || nread==0 ) 561 if ( ferror( fh ) || nread==0 )
559 setStatus(IO_ReadError); 562 setStatus(IO_ReadError);
560 } 563 }
561 } 564 }
562 } 565 }
563 if ( !isSequentialAccess() ) 566 if ( !isSequentialAccess() )
564 ioIndex += nread; 567 ioIndex += nread;
565 return nread; 568 return nread;
566} 569}
567 570
568 571
569/*! \reimp 572/*! \reimp
570 573
571 Writes \a len bytes from \a p to the file and returns the number of 574 Writes \a len bytes from \a p to the file and returns the number of
572 bytes actually written. 575 bytes actually written.
573 576
574 Returns -1 if a serious error occurred. 577 Returns -1 if a serious error occurred.
575 578
576 \warning When working with buffered files, data may not be written 579 \warning When working with buffered files, data may not be written
577 to the file at once. Call flush() to make sure the data is really 580 to the file at once. Call flush() to make sure the data is really
578 written. 581 written.
579 582
580 \sa readBlock() 583 \sa readBlock()
581*/ 584*/
582 585
583Q_LONG QFile::writeBlock( const char *p, Q_ULONG len ) 586Q_LONG QFile::writeBlock( const char *p, Q_ULONG len )
584{ 587{
585#if defined(QT_CHECK_NULL) 588#if defined(QT_CHECK_NULL)
586 if ( p == 0 && len != 0 ) 589 if ( p == 0 && len != 0 )
587 qWarning( "QFile::writeBlock: Null pointer error" ); 590 qWarning( "QFile::writeBlock: Null pointer error" );
588#endif 591#endif
589#if defined(QT_CHECK_STATE) 592#if defined(QT_CHECK_STATE)
590 if ( !isOpen() ) { // file not open 593 if ( !isOpen() ) { // file not open
591 qWarning( "QFile::writeBlock: File not open" ); 594 qWarning( "QFile::writeBlock: File not open" );
592 return -1; 595 return -1;
593 } 596 }
594 if ( !isWritable() ) { // writing not permitted 597 if ( !isWritable() ) { // writing not permitted
595 qWarning( "QFile::writeBlock: Write operation not permitted" ); 598 qWarning( "QFile::writeBlock: Write operation not permitted" );
596 return -1; 599 return -1;
597 } 600 }
598#endif 601#endif
599 Q_ULONG nwritten; // number of bytes written 602 Q_ULONG nwritten; // number of bytes written
600 if ( isRaw() ) // raw file 603 if ( isRaw() ) // raw file
601 nwritten = ::write( fd, (void *)p, len ); 604 nwritten = ::write( fd, (void *)p, len );
602 else // buffered file 605 else // buffered file
603 nwritten = fwrite( p, 1, len, fh ); 606 nwritten = fwrite( p, 1, len, fh );
604 if ( nwritten != len ) { // write error 607 if ( nwritten != len ) { // write error
605 if ( errno == ENOSPC ) // disk is full 608 if ( errno == ENOSPC ) // disk is full
606 setStatus( IO_ResourceError ); 609 setStatus( IO_ResourceError );
607 else 610 else
608 setStatus( IO_WriteError ); 611 setStatus( IO_WriteError );
609 if ( !isSequentialAccess() ) { 612 if ( !isSequentialAccess() ) {
610 if ( isRaw() ) // recalc file position 613 if ( isRaw() ) // recalc file position
611 ioIndex = (Offset)::lseek( fd, 0, SEEK_CUR ); 614 ioIndex = (Offset)::lseek( fd, 0, SEEK_CUR );
612 else 615 else
613#if defined(QT_LARGEFILE_SUPPORT) 616#if defined(QT_LARGEFILE_SUPPORT)
614 ioIndex = (Offset)::fseeko( fh, 0, SEEK_CUR ); 617 ioIndex = (Offset)::fseeko( fh, 0, SEEK_CUR );
615#else 618#else
616 ioIndex = (Offset)::fseek( fh, 0, SEEK_CUR ); 619 ioIndex = (Offset)::fseek( fh, 0, SEEK_CUR );
617#endif 620#endif
618 } 621 }
619 } else { 622 } else {
620 if ( !isSequentialAccess() ) 623 if ( !isSequentialAccess() )
621 ioIndex += nwritten; 624 ioIndex += nwritten;
622 } 625 }
623 if ( ioIndex > length ) // update file length 626 if ( ioIndex > length ) // update file length
624 length = ioIndex; 627 length = ioIndex;
625 return nwritten; 628 return nwritten;
626} 629}
627 630
628/*! 631/*!
629 Returns the file handle of the file. 632 Returns the file handle of the file.
630 633
631 This is a small positive integer, suitable for use with C library 634 This is a small positive integer, suitable for use with C library
632 functions such as fdopen() and fcntl(), as well as with QSocketNotifier. 635 functions such as fdopen() and fcntl(). On systems that use file
636 descriptors for sockets (ie. Unix systems, but not Windows) the handle
637 can be used with QSocketNotifier as well.
633 638
634 If the file is not open or there is an error, handle() returns -1. 639 If the file is not open or there is an error, handle() returns -1.
635 640
636 \sa QSocketNotifier 641 \sa QSocketNotifier
637*/ 642*/
638 643
639int QFile::handle() const 644int QFile::handle() const
640{ 645{
641 if ( !isOpen() ) 646 if ( !isOpen() )
642 return -1; 647 return -1;
643 else if ( fh ) 648 else if ( fh )
644 return fileno( fh ); 649 return fileno( fh );
645 else 650 else
646 return fd; 651 return fd;
647} 652}
648 653
649/*! 654/*!
650 Closes an open file. 655 Closes an open file.
651 656
652 The file is not closed if it was opened with an existing file handle. 657 The file is not closed if it was opened with an existing file handle.
653 If the existing file handle is a \c FILE*, the file is flushed. 658 If the existing file handle is a \c FILE*, the file is flushed.
654 If the existing file handle is an \c int file descriptor, nothing 659 If the existing file handle is an \c int file descriptor, nothing
655 is done to the file. 660 is done to the file.
656 661
657 Some "write-behind" filesystems may report an unspecified error on 662 Some "write-behind" filesystems may report an unspecified error on
658 closing the file. These errors only indicate that something may 663 closing the file. These errors only indicate that something may
659 have gone wrong since the previous open(). In such a case status() 664 have gone wrong since the previous open(). In such a case status()
660 reports IO_UnspecifiedError after close(), otherwise IO_Ok. 665 reports IO_UnspecifiedError after close(), otherwise IO_Ok.
661 666
662 \sa open(), flush() 667 \sa open(), flush()
663*/ 668*/
664 669
665 670
666void QFile::close() 671void QFile::close()
667{ 672{
668 bool ok = FALSE; 673 bool ok = FALSE;
669 if ( isOpen() ) { // file is not open 674 if ( isOpen() ) { // file is not open
670 if ( fh ) { // buffered file 675 if ( fh ) { // buffered file
671 if ( ext_f ) 676 if ( ext_f )
672 ok = fflush( fh ) != -1;// flush instead of closing 677 ok = fflush( fh ) != -1;// flush instead of closing
673 else 678 else
674 ok = fclose( fh ) != -1; 679 ok = fclose( fh ) != -1;
675 } else { // raw file 680 } else { // raw file
676 if ( ext_f ) 681 if ( ext_f )
677 ok = TRUE; // cannot close 682 ok = TRUE; // cannot close
678 else 683 else
679 ok = ::close( fd ) != -1; 684 ok = ::close( fd ) != -1;
680 } 685 }