LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/tools/source/stream - strmunx.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 150 248 60.5 %
Date: 2013-07-09 Functions: 20 25 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <stdio.h>
      21             : #include <string.h>
      22             : #include <sys/stat.h>
      23             : #include <fcntl.h>
      24             : #include <errno.h>
      25             : #include <unistd.h>
      26             : #include <limits.h>
      27             : 
      28             : #include <tools/debug.hxx>
      29             : #include <tools/stream.hxx>
      30             : #include <vector>
      31             : 
      32             : #include <osl/mutex.hxx>
      33             : #include <osl/thread.h> // osl_getThreadTextEncoding
      34             : 
      35             : // class FileBase
      36             : #include <osl/file.hxx>
      37             : #include <osl/detail/file.h>
      38             : #include <rtl/instance.hxx>
      39             : #include <rtl/strbuf.hxx>
      40             : 
      41             : using namespace osl;
      42             : 
      43             : // InternalLock ----------------------------------------------------------------
      44             : 
      45             : namespace { struct LockMutex : public rtl::Static< osl::Mutex, LockMutex > {}; }
      46             : 
      47             : class InternalStreamLock
      48             : {
      49             :     sal_Size           m_nStartPos;
      50             :     sal_Size           m_nEndPos;
      51             :     SvFileStream*      m_pStream;
      52             :     osl::DirectoryItem m_aItem;
      53             : 
      54             :     InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
      55             :     ~InternalStreamLock();
      56             : public:
      57             :     static bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
      58             :     static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
      59             : };
      60             : 
      61             : typedef ::std::vector< InternalStreamLock* > InternalStreamLockList;
      62             : 
      63             : namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; }
      64             : 
      65           0 : InternalStreamLock::InternalStreamLock(
      66             :     sal_Size nStart,
      67             :     sal_Size nEnd,
      68             :     SvFileStream* pStream ) :
      69             :         m_nStartPos( nStart ),
      70             :         m_nEndPos( nEnd ),
      71           0 :         m_pStream( pStream )
      72             : {
      73           0 :     osl::DirectoryItem::get( m_pStream->GetFileName(), m_aItem );
      74           0 :     LockList::get().push_back( this );
      75             : #if OSL_DEBUG_LEVEL > 1
      76             :     OString aFileName(OUStringToOString(m_pStream->GetFileName(),
      77             :                                                   osl_getThreadTextEncoding()));
      78             :     fprintf( stderr, "locked %s", aFileName.getStr() );
      79             :     if( m_nStartPos || m_nEndPos )
      80             :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
      81             :     fprintf( stderr, "\n" );
      82             : #endif
      83           0 : }
      84             : 
      85           0 : InternalStreamLock::~InternalStreamLock()
      86             : {
      87           0 :     for ( InternalStreamLockList::iterator it = LockList::get().begin();
      88           0 :           it != LockList::get().end();
      89             :           ++it
      90             :     ) {
      91           0 :         if ( this == *it ) {
      92           0 :             LockList::get().erase( it );
      93           0 :             break;
      94             :         }
      95             :     }
      96             : #if OSL_DEBUG_LEVEL > 1
      97             :     OString aFileName(OUStringToOString(m_pStream->GetFileName(),
      98             :                                                   osl_getThreadTextEncoding()));
      99             :     fprintf( stderr, "unlocked %s", aFileName.getStr() );
     100             :     if( m_nStartPos || m_nEndPos )
     101             :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
     102             :     fprintf( stderr, "\n" );
     103             : #endif
     104           0 : }
     105             : 
     106         144 : bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     107             : {
     108         144 :     osl::MutexGuard aGuard( LockMutex::get() );
     109         288 :     osl::DirectoryItem aItem;
     110         144 :     if (osl::DirectoryItem::get( pStream->GetFileName(), aItem) != osl::FileBase::E_None )
     111             :     {
     112             :         SAL_INFO("tools.stream", "Failed to lookup stream for locking");
     113         144 :         return true;
     114             :     }
     115             : 
     116           0 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
     117           0 :     if ( aItem.getFileStatus( aStatus ) != osl::FileBase::E_None )
     118             :     {
     119             :         SAL_INFO("tools.stream", "Failed to stat stream for locking");
     120           0 :         return true;
     121             :     }
     122           0 :     if( aStatus.getFileType() == osl::FileStatus::Directory )
     123           0 :         return true;
     124             : 
     125           0 :     InternalStreamLock* pLock = NULL;
     126           0 :     InternalStreamLockList &rLockList = LockList::get();
     127           0 :     for( size_t i = 0; i < rLockList.size(); ++i )
     128             :     {
     129           0 :         pLock = rLockList[ i ];
     130           0 :         if( aItem.isIdenticalTo( pLock->m_aItem ) )
     131             :         {
     132           0 :             bool bDenyByOptions = false;
     133           0 :             StreamMode nLockMode = pLock->m_pStream->GetStreamMode();
     134           0 :             StreamMode nNewMode = pStream->GetStreamMode();
     135             : 
     136           0 :             if( nLockMode & STREAM_SHARE_DENYALL )
     137           0 :                 bDenyByOptions = true;
     138           0 :             else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
     139           0 :                      ( nNewMode & STREAM_WRITE ) )
     140           0 :                 bDenyByOptions = true;
     141           0 :             else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
     142           0 :                      ( nNewMode & STREAM_READ ) )
     143           0 :                 bDenyByOptions = true;
     144             : 
     145           0 :             if( bDenyByOptions )
     146             :             {
     147           0 :                 if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked
     148           0 :                     return false;
     149           0 :                 if( nStart == 0 && nEnd == 0) // cannot lock whole file
     150           0 :                     return false;
     151             : 
     152           0 :                 if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) ||
     153           0 :                     ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) )
     154           0 :                     return false;
     155             :             }
     156             :         }
     157             :     }
     158             :     // hint: new InternalStreamLock() adds the entry to the global list
     159           0 :     pLock  = new InternalStreamLock( nStart, nEnd, pStream );
     160         144 :     return true;
     161             : }
     162             : 
     163        5514 : void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     164             : {
     165        5514 :     osl::MutexGuard aGuard( LockMutex::get() );
     166        5514 :     InternalStreamLock* pLock = NULL;
     167        5514 :     InternalStreamLockList &rLockList = LockList::get();
     168        5514 :     if( nStart == 0 && nEnd == 0 )
     169             :     {
     170             :         // nStart & nEnd = 0, so delete all locks
     171        5514 :         for( size_t i = 0; i < rLockList.size(); ++i )
     172             :         {
     173           0 :             if( ( pLock = rLockList[ i ] )->m_pStream == pStream )
     174             :             {
     175             :                 // hint: delete will remove pLock from the global list
     176           0 :                 delete pLock;
     177           0 :                 i--;
     178             :             }
     179             :         }
     180        5514 :         return;
     181             :     }
     182           0 :     for( size_t i = 0; i < rLockList.size(); ++i )
     183             :     {
     184           0 :         if (  ( pLock = rLockList[ i ] )->m_pStream == pStream
     185           0 :            && nStart == pLock->m_nStartPos
     186           0 :            && nEnd == pLock->m_nEndPos
     187             :         ) {
     188             :             // hint: delete will remove pLock from the global list
     189           0 :             delete pLock;
     190           0 :             return;
     191             :         }
     192           0 :     }
     193             : }
     194             : 
     195             : // StreamData ------------------------------------------------------------------
     196             : 
     197             : class StreamData
     198             : {
     199             : public:
     200             :     oslFileHandle rHandle;
     201             : 
     202        3592 :     StreamData() : rHandle( 0 ) { }
     203             : };
     204             : 
     205           0 : static sal_uInt32 GetSvError( int nErrno )
     206             : {
     207             :     static struct { int nErr; sal_uInt32 sv; } errArr[] =
     208             :     {
     209             :         { 0,            SVSTREAM_OK },
     210             :         { EACCES,       SVSTREAM_ACCESS_DENIED },
     211             :         { EBADF,        SVSTREAM_INVALID_HANDLE },
     212             : #if defined(RS6000) || defined(NETBSD) || \
     213             :     defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
     214             :     defined(__FreeBSD_kernel__) || defined (AIX) || defined(DRAGONFLY) || \
     215             :     defined(IOS)
     216             :         { EDEADLK,      SVSTREAM_LOCKING_VIOLATION },
     217             : #else
     218             :         { EDEADLOCK,    SVSTREAM_LOCKING_VIOLATION },
     219             : #endif
     220             :         { EINVAL,       SVSTREAM_INVALID_PARAMETER },
     221             :         { EMFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     222             :         { ENFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     223             :         { ENOENT,       SVSTREAM_FILE_NOT_FOUND },
     224             :         { EPERM,        SVSTREAM_ACCESS_DENIED },
     225             :         { EROFS,        SVSTREAM_ACCESS_DENIED },
     226             :         { EAGAIN,       SVSTREAM_LOCKING_VIOLATION },
     227             :         { EISDIR,       SVSTREAM_PATH_NOT_FOUND },
     228             :         { ELOOP,        SVSTREAM_PATH_NOT_FOUND },
     229             : #if !defined(RS6000) && !defined(NETBSD) && !defined (FREEBSD) && \
     230             :     !defined(MACOSX) && !defined(OPENBSD) && !defined(__FreeBSD_kernel__) && \
     231             :     !defined(DRAGONFLY)
     232             :         { EMULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     233             :         { ENOLINK,      SVSTREAM_PATH_NOT_FOUND },
     234             : #endif
     235             :         { ENOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     236             :         { ETXTBSY,      SVSTREAM_ACCESS_DENIED  },
     237             :         { EEXIST,       SVSTREAM_CANNOT_MAKE    },
     238             :         { ENOSPC,       SVSTREAM_DISK_FULL      },
     239             :         { (int)0xFFFF,  SVSTREAM_GENERALERROR }
     240             :     };
     241             : 
     242           0 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     243           0 :     int i=0;
     244           0 :     do
     245             :     {
     246           0 :         if ( errArr[i].nErr == nErrno )
     247             :         {
     248           0 :             nRetVal = errArr[i].sv;
     249           0 :             break;
     250             :         }
     251           0 :         ++i;
     252             :     }
     253           0 :     while( errArr[i].nErr != 0xFFFF );
     254           0 :     return nRetVal;
     255             : }
     256             : 
     257         804 : static sal_uInt32 GetSvError( oslFileError nErrno )
     258             : {
     259             :     static struct { oslFileError nErr; sal_uInt32 sv; } errArr[] =
     260             :     {
     261             :         { osl_File_E_None,        SVSTREAM_OK },
     262             :         { osl_File_E_ACCES,       SVSTREAM_ACCESS_DENIED },
     263             :         { osl_File_E_BADF,        SVSTREAM_INVALID_HANDLE },
     264             :         { osl_File_E_DEADLK,      SVSTREAM_LOCKING_VIOLATION },
     265             :         { osl_File_E_INVAL,       SVSTREAM_INVALID_PARAMETER },
     266             :         { osl_File_E_MFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     267             :         { osl_File_E_NFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     268             :         { osl_File_E_NOENT,       SVSTREAM_FILE_NOT_FOUND },
     269             :         { osl_File_E_PERM,        SVSTREAM_ACCESS_DENIED },
     270             :         { osl_File_E_ROFS,        SVSTREAM_ACCESS_DENIED },
     271             :         { osl_File_E_AGAIN,       SVSTREAM_LOCKING_VIOLATION },
     272             :         { osl_File_E_ISDIR,       SVSTREAM_PATH_NOT_FOUND },
     273             :         { osl_File_E_LOOP,        SVSTREAM_PATH_NOT_FOUND },
     274             :         { osl_File_E_MULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     275             :         { osl_File_E_NOLINK,      SVSTREAM_PATH_NOT_FOUND },
     276             :         { osl_File_E_NOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     277             :         { osl_File_E_EXIST,       SVSTREAM_CANNOT_MAKE    },
     278             :         { osl_File_E_NOSPC,       SVSTREAM_DISK_FULL      },
     279             :         { (oslFileError)0xFFFF,   SVSTREAM_GENERALERROR }
     280             :     };
     281             : 
     282         804 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     283         804 :     int i=0;
     284        5628 :     do
     285             :     {
     286        6432 :         if ( errArr[i].nErr == nErrno )
     287             :         {
     288         804 :             nRetVal = errArr[i].sv;
     289         804 :             break;
     290             :         }
     291        5628 :         ++i;
     292             :     }
     293        5628 :     while( errArr[i].nErr != (oslFileError)0xFFFF );
     294         804 :     return nRetVal;
     295             : }
     296             : 
     297        3318 : SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nOpenMode )
     298             : {
     299        3318 :     bIsOpen             = false;
     300        3318 :     nLockCounter        = 0;
     301        3318 :     bIsWritable         = false;
     302        3318 :     pInstanceData       = new StreamData;
     303             : 
     304        3318 :     SetBufferSize( 1024 );
     305             :     // convert URL to SystemPath, if necessary
     306        3318 :     OUString aSystemFileName;
     307        3318 :     if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
     308             :         != FileBase::E_None )
     309             :     {
     310        1047 :         aSystemFileName = rFileName;
     311             :     }
     312        3318 :     Open( aSystemFileName, nOpenMode );
     313        3318 : }
     314             : 
     315         274 : SvFileStream::SvFileStream()
     316             : {
     317         274 :     bIsOpen             = false;
     318         274 :     nLockCounter        = 0;
     319         274 :     bIsWritable         = false;
     320         274 :     pInstanceData       = new StreamData;
     321         274 :     SetBufferSize( 1024 );
     322         274 : }
     323             : 
     324        8446 : SvFileStream::~SvFileStream()
     325             : {
     326        3234 :     Close();
     327             : 
     328        3234 :     InternalStreamLock::UnlockFile( 0, 0, this );
     329             : 
     330        3234 :     if (pInstanceData)
     331        3234 :         delete pInstanceData;
     332        5212 : }
     333             : 
     334           0 : sal_uInt32 SvFileStream::GetFileHandle() const
     335             : {
     336             :     sal_IntPtr handle;
     337           0 :     if (osl_getFileOSHandle(pInstanceData->rHandle, &handle) == osl_File_E_None)
     338           0 :         return (sal_uInt32) handle;
     339             :     else
     340           0 :         return (sal_uInt32) -1;
     341             : }
     342             : 
     343           0 : sal_uInt16 SvFileStream::IsA() const
     344             : {
     345           0 :     return ID_FILESTREAM;
     346             : }
     347             : 
     348      131055 : sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
     349             : {
     350             : #ifdef DBG_UTIL
     351             :     OStringBuffer aTraceStr("SvFileStream::GetData(): ");
     352             :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     353             :     aTraceStr.append(" Bytes from ");
     354             :     aTraceStr.append(OUStringToOString(aFilename,
     355             :         osl_getThreadTextEncoding()));
     356             :     OSL_TRACE("%s", aTraceStr.getStr());
     357             : #endif
     358             : 
     359      131055 :     sal_uInt64 nRead = 0;
     360      131055 :     if ( IsOpen() )
     361             :     {
     362      131055 :         oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
     363      131055 :         if ( rc != osl_File_E_None )
     364             :         {
     365           0 :             SetError( ::GetSvError( rc ));
     366           0 :             return -1;
     367             :         }
     368             :     }
     369      131055 :     return (sal_Size)nRead;
     370             : }
     371             : 
     372       20755 : sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
     373             : {
     374             : #ifdef DBG_UTIL
     375             :     OStringBuffer aTraceStr("SvFileStream::PutData(): ");
     376             :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     377             :     aTraceStr.append(" Bytes to ");
     378             :     aTraceStr.append(OUStringToOString(aFilename,
     379             :         osl_getThreadTextEncoding()));
     380             :     OSL_TRACE("%s", aTraceStr.getStr());
     381             : #endif
     382             : 
     383       20755 :     sal_uInt64 nWrite = 0;
     384       20755 :     if ( IsOpen() )
     385             :     {
     386       20755 :         oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
     387       20755 :         if ( rc != osl_File_E_None )
     388             :         {
     389           0 :             SetError( ::GetSvError( rc ) );
     390           0 :             return -1;
     391             :         }
     392       20755 :         else if( !nWrite )
     393           0 :             SetError( SVSTREAM_DISK_FULL );
     394             :     }
     395       20755 :     return (sal_Size)nWrite;
     396             : }
     397             : 
     398      185436 : sal_Size SvFileStream::SeekPos( sal_Size nPos )
     399             : {
     400      185436 :     if ( IsOpen() )
     401             :     {
     402             :         oslFileError rc;
     403             :         sal_uInt64 nNewPos;
     404      185436 :         if ( nPos != STREAM_SEEK_TO_END )
     405      183592 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
     406             :         else
     407        1844 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
     408             : 
     409      185436 :         if ( rc != osl_File_E_None )
     410             :         {
     411           0 :             SetError( SVSTREAM_SEEK_ERROR );
     412           0 :             return 0L;
     413             :         }
     414      185436 :         rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
     415      185436 :         return (sal_Size) nNewPos;
     416             :     }
     417           0 :     SetError( SVSTREAM_GENERALERROR );
     418           0 :     return 0L;
     419             : }
     420             : 
     421         691 : void SvFileStream::FlushData()
     422             : {
     423             :     // does not exist locally
     424         691 : }
     425             : 
     426        2638 : bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
     427             : {
     428        2638 :     int nLockMode = 0;
     429             : 
     430        2638 :     if ( ! IsOpen() )
     431           0 :         return false;
     432             : 
     433        2638 :     if ( eStreamMode & STREAM_SHARE_DENYALL )
     434             :         {
     435         144 :         if (bIsWritable)
     436         144 :             nLockMode = F_WRLCK;
     437             :         else
     438           0 :             nLockMode = F_RDLCK;
     439             :         }
     440             : 
     441        2638 :     if ( eStreamMode & STREAM_SHARE_DENYREAD )
     442             :         {
     443           0 :         if (bIsWritable)
     444           0 :             nLockMode = F_WRLCK;
     445             :         else
     446             :         {
     447           0 :             SetError(SVSTREAM_LOCKING_VIOLATION);
     448           0 :             return false;
     449             :         }
     450             :         }
     451             : 
     452        2638 :     if ( eStreamMode & STREAM_SHARE_DENYWRITE )
     453             :         {
     454        1540 :         if (bIsWritable)
     455           0 :             nLockMode = F_WRLCK;
     456             :         else
     457        1540 :             nLockMode = F_RDLCK;
     458             :         }
     459             : 
     460        2638 :     if (!nLockMode)
     461        2494 :         return true;
     462             : 
     463         144 :     if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) )
     464             :     {
     465             : #if OSL_DEBUG_LEVEL > 1
     466             :         fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
     467             :                  OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr(), nByteOffset, nByteOffset+nBytes );
     468             : #endif
     469           0 :         return false;
     470             :     }
     471             : 
     472         144 :     return true;
     473             : }
     474             : 
     475        6686 : bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
     476             : {
     477        6686 :     if ( ! IsOpen() )
     478        4406 :         return false;
     479             : 
     480        2280 :     InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this );
     481             : 
     482        2280 :     return true;
     483             : }
     484             : 
     485        2638 : bool SvFileStream::LockFile()
     486             : {
     487        2638 :   return LockRange( 0UL, 0UL );
     488             : }
     489             : 
     490        6686 : bool SvFileStream::UnlockFile()
     491             : {
     492        6686 :     return UnlockRange( 0UL, 0UL );
     493             : }
     494             : 
     495        3442 : void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
     496             : {
     497             :     sal_uInt32 uFlags;
     498             :     oslFileHandle nHandleTmp;
     499             : 
     500        3442 :     Close();
     501        3442 :     errno = 0;
     502        3442 :     eStreamMode = nOpenMode;
     503        3442 :     eStreamMode &= ~STREAM_TRUNC; // don't truncat on reopen
     504             : 
     505        3442 :     aFilename = rFilename;
     506        3442 :     OString aLocalFilename(OUStringToOString(aFilename, osl_getThreadTextEncoding()));
     507             : 
     508             : #ifdef DBG_UTIL
     509             :     OStringBuffer aTraceStr("SvFileStream::Open(): ");
     510             :     aTraceStr.append(aLocalFilename);
     511             :     OSL_TRACE( "%s", aTraceStr.getStr() );
     512             : #endif
     513             : 
     514        6884 :     OUString aFileURL;
     515        6884 :     osl::DirectoryItem aItem;
     516        6884 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL );
     517             : 
     518             :     // FIXME: we really need to switch to a pure URL model ...
     519        3442 :     if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
     520           0 :         aFileURL = aFilename;
     521        6026 :     bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
     522        6026 :                         aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
     523             : 
     524             :     // SvFileStream can't open a directory
     525        3442 :     if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
     526             :     {
     527           0 :         SetError( ::GetSvError( EISDIR ) );
     528        3442 :         return;
     529             :     }
     530             : 
     531        3442 :     if ( !( nOpenMode & STREAM_WRITE ) )
     532        3056 :         uFlags = osl_File_OpenFlag_Read;
     533         386 :     else if ( !( nOpenMode & STREAM_READ ) )
     534         184 :         uFlags = osl_File_OpenFlag_Write;
     535             :     else
     536         202 :         uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
     537             : 
     538             :     // Fix (MDA, 18.01.95): Don't open with O_CREAT upon RD_ONLY
     539             :     // Important for Read-Only-Filesystems (e.g,  CDROM)
     540        3442 :     if ( (!( nOpenMode & STREAM_NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
     541         386 :         uFlags |= osl_File_OpenFlag_Create;
     542        3442 :     if ( nOpenMode & STREAM_TRUNC )
     543         232 :         uFlags |= osl_File_OpenFlag_Trunc;
     544             : 
     545        3442 :     uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
     546             : 
     547        3442 :     if ( nOpenMode & STREAM_WRITE)
     548             :     {
     549         386 :         if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
     550             :         {
     551           0 :             if ( bStatValid && aStatus.getFileType() == osl::FileStatus::Link &&
     552           0 :                  aStatus.getLinkTargetURL().getLength() > 0 )
     553             :             {
     554             :                 // delete the symbolic link, and replace it with the contents of the link
     555           0 :                 if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
     556             :                 {
     557           0 :                     File::copy( aStatus.getLinkTargetURL(), aFileURL );
     558             : #if OSL_DEBUG_LEVEL > 0
     559             :                     fprintf( stderr,
     560             :                              "Removing link and replacing with file contents (%s) -> (%s).\n",
     561             :                              OUStringToOString( aStatus.getLinkTargetURL(),
     562             :                                                      RTL_TEXTENCODING_UTF8).getStr(),
     563             :                              OUStringToOString( aFileURL,
     564             :                                                      RTL_TEXTENCODING_UTF8).getStr() );
     565             : #endif
     566             :                 }
     567             :             }
     568             :         }
     569             :     }
     570             : 
     571        3442 :     oslFileError rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     572        3442 :     if ( rc != osl_File_E_None )
     573             :     {
     574         804 :         if ( uFlags & osl_File_OpenFlag_Write )
     575             :         {
     576             :             // Change to read-only
     577           0 :             uFlags &= ~osl_File_OpenFlag_Write;
     578           0 :             rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     579             :         }
     580             :     }
     581        3442 :     if ( rc == osl_File_E_None )
     582             :     {
     583        2638 :         pInstanceData->rHandle = nHandleTmp;
     584        2638 :         bIsOpen = true;
     585        2638 :         if ( uFlags & osl_File_OpenFlag_Write )
     586         386 :             bIsWritable = true;
     587             : 
     588        2638 :         if ( !LockFile() ) // whole file
     589             :         {
     590           0 :             rc = osl_closeFile( nHandleTmp );
     591           0 :             bIsOpen = false;
     592           0 :             bIsWritable = false;
     593           0 :             pInstanceData->rHandle = 0;
     594             :         }
     595             :     }
     596             :     else
     597        4246 :         SetError( ::GetSvError( rc ) );
     598             : }
     599             : 
     600        6686 : void SvFileStream::Close()
     601             : {
     602        6686 :     UnlockFile();
     603             : 
     604        6686 :     if ( IsOpen() )
     605             :     {
     606             : #ifdef DBG_UTIL
     607             :         OStringBuffer aTraceStr("SvFileStream::Close(): ");
     608             :         aTraceStr.append(OUStringToOString(aFilename,
     609             :             osl_getThreadTextEncoding()));
     610             :         OSL_TRACE("%s", aTraceStr.getStr());
     611             : #endif
     612             : 
     613        2280 :         Flush();
     614        2280 :         osl_closeFile( pInstanceData->rHandle );
     615        2280 :         pInstanceData->rHandle = 0;
     616             :     }
     617             : 
     618        6686 :     bIsOpen     = false;
     619        6686 :     bIsWritable = false;
     620        6686 :     SvStream::ClearBuffer();
     621        6686 :     SvStream::ClearError();
     622        6686 : }
     623             : 
     624             : /// set filepointer to beginning of file
     625          67 : void SvFileStream::ResetError()
     626             : {
     627          67 :     SvStream::ClearError();
     628          67 : }
     629             : 
     630         111 : void SvFileStream::SetSize (sal_Size nSize)
     631             : {
     632         111 :     if (IsOpen())
     633             :     {
     634         111 :         oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
     635         111 :         if (rc != osl_File_E_None )
     636             :         {
     637           0 :             SetError ( ::GetSvError( rc ));
     638             :         }
     639             :     }
     640         111 : }
     641             : 
     642             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10